带有打字稿的 VueJS 单文件组件:无法找到模块 stuff.vue
VueJS Single File Component with typescript: Unable to find module stuff.vue
我有一个简单的项目结构:
/src/app2/main.ts
/src/app2/components/lib.ts
/src/app2/components/stuff.vue
使用 webpack、vue-loader 和 ts-loader。
main.ts 有:
import Vue = require('vue');
import Component from './components/lib'
new Vue({
el: '#app2'
});
当尝试使用 /src/app2/main.ts
的 1 个 webpack 条目构建它时,生成的错误是:
ERROR in C:\temp\vuetest2\proj\src\app2\components\lib.ts
(2,25): error TS2307: Cannot find module './stuff.vue'.
ERROR in ./src/app2/main.ts
Module not found: Error: Can't resolve './components/lib' in 'C:\temp\vuetest2\proj\src\app2'
@ ./src/app2/main.ts 3:12-39
如果我将入口点更改为 src/app2/components/lib.ts
,它将生成。我不知道为什么 main.ts 无法构建。
lib.ts 的内容:
import Vue = require('vue');
import Stuff = require('./stuff.vue');
let o = {
Stuff
}
let componentLibrary = {
components: o,
registerExternal: function(v:any) {
for(var k in o) {
v.component(o[k].name, o[k]);
}
},
registerInternal: function() {
for(var k in o) {
Vue.component(o[k].name, o[k]);
}
}
}
export default componentLibrary;
Stuff.vue只是一个简单的单文件vue组件
根据 : https://github.com/vuejs/vue-class-component/blob/master/example/webpack.config.js
尝试在 webpack.config.js
中添加 appendTsSuffixTo
ts-loader 选项
webpack2
{
test: /\.ts$/,
exclude: /node_modules|vue\/src/,
use: [{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
}]
},
您可以在 github 上参考 this PR。其实这不是错误,只是使用问题。
我假设您想用 <script lang="ts">
、<script lang="tsx">
、*.ts
来编写 SFC 实用程序函数 & 类 和 *.tsx
来编写纯函数组件。
ts-loader 只接受 *.ts
或 *.tsx
个文件进行编译(否则会导致找不到文件的错误)。所以ts-loader有两个选项:appendTsSuffixTo
和appendTsxSuffixTo
。这两个选项接受一个正则表达式数组来匹配您要编译的文件。 (这里我们把vue-loader处理过的*.vue文件交给ts-loader编译)
我假设您对 <script lang="ts">
SFC vue 文件使用 *.ts.vue,而对 <script lang="tsx">
SFC vue 文件使用 *.tsx.vue。 ts-loader 应该配置如下:
{
test: /\.tsx?$/,
use: [
{
loader: 'babel-loader'
},
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.ts\.vue$/],
appendTsxSuffixTo: [/\.tsx\.vue$/]
}
}
],
exclude: /node_modules/
},
这意味着,传递给 ts-loader 的普通 *.ts 和 *.tsx 文件将被转译,然后发送给 babel-loader 进行进一步编译。而其他以.ts.vue
结尾的文件将以.ts
作为后缀*.ts.vue.ts
,而以.tsx.vue
结尾的则为*.tsx.vue.tsx
。这些文件都是从 vue-loader 传递过来的。记住 ts-loader 只接受 .ts
和 .tsx
文件。
但是vue-loader不够智能,<script lang="xxx">
会触发vue-loader append xxx-loader进一步编译,<script lang="tsx">
会让vue-loader append tsx-loader,即世界上不存在。
还好我们可以配置vue-loader的options
:
const loaders = {}
loaders.tsx = ['babel-loader', 'ts-loader']
loaders.ts = loaders.tsx
{
test: /\.vue$/,
loader: 'vue-loader',
options: { loaders }
},
之后webpack配置完成。对于 tsx 支持,您应该安装一些 JSX 类型并编写相关的 .d.ts 文件
您可以在 github 上查看 this repo 了解更多详情。
祝你好运!
我有一个简单的项目结构:
/src/app2/main.ts /src/app2/components/lib.ts /src/app2/components/stuff.vue
使用 webpack、vue-loader 和 ts-loader。
main.ts 有:
import Vue = require('vue');
import Component from './components/lib'
new Vue({
el: '#app2'
});
当尝试使用 /src/app2/main.ts
的 1 个 webpack 条目构建它时,生成的错误是:
ERROR in C:\temp\vuetest2\proj\src\app2\components\lib.ts
(2,25): error TS2307: Cannot find module './stuff.vue'.
ERROR in ./src/app2/main.ts
Module not found: Error: Can't resolve './components/lib' in 'C:\temp\vuetest2\proj\src\app2'
@ ./src/app2/main.ts 3:12-39
如果我将入口点更改为 src/app2/components/lib.ts
,它将生成。我不知道为什么 main.ts 无法构建。
lib.ts 的内容:
import Vue = require('vue');
import Stuff = require('./stuff.vue');
let o = {
Stuff
}
let componentLibrary = {
components: o,
registerExternal: function(v:any) {
for(var k in o) {
v.component(o[k].name, o[k]);
}
},
registerInternal: function() {
for(var k in o) {
Vue.component(o[k].name, o[k]);
}
}
}
export default componentLibrary;
Stuff.vue只是一个简单的单文件vue组件
根据 : https://github.com/vuejs/vue-class-component/blob/master/example/webpack.config.js
尝试在 webpack.config.js
appendTsSuffixTo
ts-loader 选项
webpack2
{
test: /\.ts$/,
exclude: /node_modules|vue\/src/,
use: [{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
}]
},
您可以在 github 上参考 this PR。其实这不是错误,只是使用问题。
我假设您想用 <script lang="ts">
、<script lang="tsx">
、*.ts
来编写 SFC 实用程序函数 & 类 和 *.tsx
来编写纯函数组件。
ts-loader 只接受 *.ts
或 *.tsx
个文件进行编译(否则会导致找不到文件的错误)。所以ts-loader有两个选项:appendTsSuffixTo
和appendTsxSuffixTo
。这两个选项接受一个正则表达式数组来匹配您要编译的文件。 (这里我们把vue-loader处理过的*.vue文件交给ts-loader编译)
我假设您对 <script lang="ts">
SFC vue 文件使用 *.ts.vue,而对 <script lang="tsx">
SFC vue 文件使用 *.tsx.vue。 ts-loader 应该配置如下:
{
test: /\.tsx?$/,
use: [
{
loader: 'babel-loader'
},
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.ts\.vue$/],
appendTsxSuffixTo: [/\.tsx\.vue$/]
}
}
],
exclude: /node_modules/
},
这意味着,传递给 ts-loader 的普通 *.ts 和 *.tsx 文件将被转译,然后发送给 babel-loader 进行进一步编译。而其他以.ts.vue
结尾的文件将以.ts
作为后缀*.ts.vue.ts
,而以.tsx.vue
结尾的则为*.tsx.vue.tsx
。这些文件都是从 vue-loader 传递过来的。记住 ts-loader 只接受 .ts
和 .tsx
文件。
但是vue-loader不够智能,<script lang="xxx">
会触发vue-loader append xxx-loader进一步编译,<script lang="tsx">
会让vue-loader append tsx-loader,即世界上不存在。
还好我们可以配置vue-loader的options
:
const loaders = {}
loaders.tsx = ['babel-loader', 'ts-loader']
loaders.ts = loaders.tsx
{
test: /\.vue$/,
loader: 'vue-loader',
options: { loaders }
},
之后webpack配置完成。对于 tsx 支持,您应该安装一些 JSX 类型并编写相关的 .d.ts 文件
您可以在 github 上查看 this repo 了解更多详情。
祝你好运!