带有打字稿的 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有两个选项:appendTsSuffixToappendTsxSuffixTo。这两个选项接受一个正则表达式数组来匹配您要编译的文件。 (这里我们把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 了解更多详情。

祝你好运!