使用 TypeScript 时如何在单个文件组件中导入 Vue?
Posted
技术标签:
【中文标题】使用 TypeScript 时如何在单个文件组件中导入 Vue?【英文标题】:How to import Vue in Single File Component when using TypeScript? 【发布时间】:2020-01-18 04:25:47 【问题描述】:我有一个单文件组件,我需要导入 Vue:
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
...
@Component(...)
export class Comp extends Vue ...
我在浏览器中将 vue.js 作为模块导入:
<script type="module" src="module/vue/vue.js"></script>
但我得到了错误
Uncaught TypeError: Class extends value undefined is not a constructor or null
eval()
内部的某个位置,由 vue-cli-service --target lib
生成。我也将 SFC 作为模块加载:
<script type="module" src="module/comp/comp.js"></script>
作为一种解决方法,我尝试在 comp.js
的顶部添加导入:
import Vue from '/module/vue/vue.js'
import Component from '/module/vue-class-component/vue-class-component.js'
(function webpackUniversalModuleDefinition(root, factory)
...
但这无济于事。
如何将导入重新连接到将在 Web 服务器上使用的路径?我检查了 webpack 的选项,但只找到了 resolve
,这似乎有助于 webpack 在打包时找到东西。我需要一种“输出重写”选项。
请注意,我使用的是 ES 模块,而不是 CommonJS 或 RequireJS。
tsconfig.json
:
compilerOptions: "target": "ES2016", module: "ES2015"
更新我尝试将最终路径放入 .vue 文件并在 vue.config.js
中使用 configureWebpack.resolve.alias
以允许 Vue 编译器定位模块,但这也不起作用。
vue.config.js
:
module.exports =
runtimeCompiler: true,
configureWebpack:
externals: [
'module/vue/vue',
'module/vue-class-component/vue-class-component',
],
resolve:
alias:
'module/vue/vue': 'vue/dist/vue.esm.js',
'module/vue-class-component/vue-class-component': 'vue-class-component/dist/vue-class-component.esm.js'
,
comp.vue
:
...
import Vue from './module/vue/vue'
import Component from 'module/vue-class-component/vue-class-component'
只是给
ERROR in .../src/comp.vue
16:17 Cannot find module 'module/vue/vue'.
【问题讨论】:
可以用vue属性装饰器代替“vue-class-component”。从'vue-property-decorator'导入组件,Vue; @AmithaMahesh 谢谢。那也行不通。vue-class-component
导入不是证明问题所必需的,我只是保留它以表明 Vue 不是唯一的导入,答案也应该适用于其他事情。
找不到路径,因为外部设置不正确。它需要指向全局变量而不是路径。
我的印象(我可能是错的)是当你使用 ES2015 模块时,没有全局变量。因此出现错误。
【参考方案1】:
概述
您可以在vue.config.js
中添加configureWebpack
来修改Webpack 配置,在Webpack 中您可以使用externals
解决此问题。
处理外部
Externals 为您提供了一种导入外部库的方法。
在您的 webpack 配置中,您将添加如下所示的一行。
我们以lodash
为例,因为导入和全局变量是不同的。
// webpack.config
externals:
'lodash': '_'
_
是 webpack 可以抓取的全局变量,lodash
是它公开的导入。
此时,您可以执行以下操作。
import * as lodash from 'lodash'
处理类型检查
要使用此方法处理类型检查,您 npm install @types/...
和 TypeScript 将选择该导入的类型。
在 vue.config.js 中修改 Webpack
您可以阅读有关此here 的信息,但只需将以下内容添加到 vue.config.js 文件中。
// vue.config.js
module.exports =
configureWebpack:
externals:
'lodash': '_'
【讨论】:
如何将localhost/module/lodash/lodash.js 映射到浏览器中的导入语句? 如果你查看编译结果,你会得到这个module.exports = _;
for 'lodash',所以它期望'_'已经存在。这只是将全局变量暴露给 webpack。对于 Vue.js,就像 lodash 一样,它会创建一个全局变量 Vue
,您可以将其映射到 webpak 中。外部:'Vue'。浏览器只运行 Vue.js 并创建 Vue 全局变量,webpack 可以使用您指定的任何内容来引用它。在你的脚本中使用 type="module" 与否结果是一样的。
长话短说,这在我的测试平台上对我有用。我唯一可能做的不同的事情是我为Vue.js
<script type="module" src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
使用了CDN
啊...我正在尝试使用 ES 模块,而不是旧的 requirejs/commonjs 东西。因此,在生成的代码中,我看到 import Vue from "vue"
适用于单元测试(npm/jest 会找到这些东西),但在浏览器中却没有(= 忽略的全局符号)。当我使用 应该 在浏览器中工作的相对路径时,tsc&jest 会中断。
tsconfig.json
: compilerOptions: "target": "ES2016", module: "ES2015"
以上是关于使用 TypeScript 时如何在单个文件组件中导入 Vue?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Typescript 文件中导入 Svelte 组件?
使用Typescript和类组件装饰器时如何在Vue Router中传递props
如何使用 bit 在 javascript 项目中创建 typescript 组件?