带有打字稿的VueJS单文件组件:找不到模块stuff.vue

Posted

技术标签:

【中文标题】带有打字稿的VueJS单文件组件:找不到模块stuff.vue【英文标题】:VueJS Single File Component with typescript: Unable to find module stuff.vue 【发布时间】:2017-07-15 20:34:15 【问题描述】:

我有一个简单的项目结构:

/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 组件。

【问题讨论】:

尝试修改你的main.ts,像这样new Vue( el: '#app2', render: (h) => h(Component) );我猜Component是主要组件 它不会在 webpack 中编译。据我所知,您的建议不会对编译产生影响。 你有没有想过这个问题? 我做到了,我会看看我是否可以稍后发布我的答案或确认下面的答案.. 只是没有太多时间。 【参考方案1】:

根据: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$/]
            
        ]
,

【讨论】:

我已经有了这个,但是仍然无法从 index.ts 中找到我的 .vue 模块。不过可以从其他 .vue 文件中找到它们!【参考方案2】:

您可以参考 github 上的this PR。其实这不是bug,只是使用问题。

我假设您想用<script lang="ts"><script lang="tsx">*.ts 编写 SFC,用于 utils 函数和类,*.tsx 用于功能纯组件。

ts-loader 只接受 *.ts*.tsx 文件进行编译(否则会导致找不到文件的错误)。所以 ts-loader 有两个选择:appendTsSuffixToappendTsxSuffixTo。这两个选项接受一个正则表达式数组来匹配您要编译的文件。 (这里我们把已经被 vue-loader 处理过的 *.vue 文件交给 ts-loader 编译)。

我假设您将 *.ts.vue 用于<script lang="ts"> SFC vue 文件,而 *.tsx.vue 用于<script lang="tsx"> SFC 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 附加 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了解更多详情。

祝你好运!

【讨论】:

我在那个 repo 中没有看到 vue-loader 选项,它放在哪里?

以上是关于带有打字稿的VueJS单文件组件:找不到模块stuff.vue的主要内容,如果未能解决你的问题,请参考以下文章

如何将图像导入打字稿?他说“找不到模块”

使用带有打字稿的 eslint - 无法解析模块的路径

如何使用带有打字稿的“调试”模块

带有打字稿的vue3组件子属性

如何在带有打字稿的 vue.js 中使用 javascript 组件?

带有打字稿的角度材料设计