为什么 typescript(或者是 webpack)找不到我的 vue 视图?

cac*_*vis 5 typescript webpack vue.js

npx webpack

TS2307: Cannot find module './App.vue' or its corresponding type declarations.
Run Code Online (Sandbox Code Playgroud)

我正在使用 webpack、vue 和 typescript。

我有基本的 webpack 配置。它有一个打字稿文件作为入口点。输出是文件夹构建。我正在使用 typescript 加载器和 vue 加载器。

构建工作正常,直到我从 javascript 更改为 typescript(即,如果我将 app.ts 重命名为 app.js 并从 webpack 中删除 typescript 加载器,一切正常)。

对于 vue,我添加了 tsconfig.json 文件。这有助于减少错误。但我仍然收到上面显示的这个错误。

(我试图从第一原理学习 webpack-vue-typescript 。所以我不想使用 vue cli 或 vue ui 。尽管我确实使用 vue cli 生成了 vue typescript 骨架项目。我将我的代码与 vue cli 代码进行了比较.我找不到任何差异。)

这是完整的错误消息(带有警告)

npx webpack
[webpack-cli] Compilation finished
assets by status 64.1 KiB [cached] 1 asset
orphan modules 227 KiB [orphan] 7 modules
runtime modules 495 bytes 2 modules
./src/app.ts + 7 modules 227 KiB [built] [code generated]

WARNING in ./src/App.vue?vue&type=script&lang=ts& 1:166-169
export 'default' (imported as 'mod') was not found in '-!../node_modules/ts-loader/index.js!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=script&lang=ts&' (possible exports: )
 @ ./src/App.vue 2:0-55 3:0-50 3:0-50 9:2-8
 @ ./src/app.ts 2:0-28 4:36-39

ERROR in \src\app.ts
[tsl] ERROR in D:\code\vue\fs\src\app.ts(2,17)
      TS2307: Cannot find module './App.vue' or its corresponding type declarations.

webpack 5.4.0 compiled with 1 error and 1 warning in 3364 ms
Run Code Online (Sandbox Code Playgroud)

文件夹结构

+-- package.json
+-- webpack.config.js
+-- tsconfig.json
+-- src
    +-- app.ts
    +-- App.vue
    +-- index.html
Run Code Online (Sandbox Code Playgroud)

这是入口点app.ts

import Vue from 'vue'
import App from './App.vue'

new Vue({
    render: h => h(App)
}).$mount('#app')
Run Code Online (Sandbox Code Playgroud)

应用程序.vue

<template>
  <div>hello from vue</div>
</template>
Run Code Online (Sandbox Code Playgroud)

Webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const path = require('path');

module.exports = {
    entry: './src/app.ts',
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name].js'
    },
    plugins: [
        new HtmlWebpackPlugin({ template: './src/index.html' }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin()
    ],
    devServer: {
        inline: true
    },
    module: {
        rules: [{
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: /\.vue$/,
                use: 'vue-loader'
            }
        ]
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js']
    }
};
Run Code Online (Sandbox Code Playgroud)

包.json

{
    "name": "vue_ts",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "start": "webpack serve",
        "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "clean-webpack-plugin": "^3.0.0",
        "html-webpack-plugin": "^4.5.0",
        "ts-loader": "^8.0.11",
        "typescript": "^4.0.5",
        "vue-class-component": "^7.2.6",
        "vue-loader": "^15.9.5",
        "vue-property-decorator": "^9.0.2",
        "vue-template-compiler": "^2.6.12",
        "webpack": "^5.4.0",
        "webpack-cli": "^4.2.0",
        "webpack-dev-server": "^3.11.0"
    },
    "dependencies": {
        "vue": "^2.6.12"
    }
}
Run Code Online (Sandbox Code Playgroud)

tsconfig.json

{
    "compilerOptions": {
        // this aligns with Vue's browser support
        "target": "es5",
        // this enables stricter inference for data properties on `this`
        "strict": true,
        // if using webpack 2+ or rollup, to leverage tree shaking:
        "module": "es2015",
        "moduleResolution": "node"
    },
    "include": [
        "src/**/*.ts",
        "src/**/*.tsx",
        "src/**/*.vue",
        "tests/**/*.ts",
        "tests/**/*.tsx"
    ],
    "exclude": [
        "node_modules"
    ]
}
Run Code Online (Sandbox Code Playgroud)

索引.html

<html>
<head></head>
<body>
    <div id="app"></div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

版本

  • npm 6.14.8
  • 节点 14.15.0
  • TSC 4.0.5
  • 其他版本请上面的package.json

小智 9

我按照这两个链接解决了问题

  1. https://johnpapa.net/vue-typescript/
  2. https://github.com/microsoft/typescript-vue-starter#install-our-dependencies

src在我添加这个文件的文件夹下vue-shims.d.ts

declare module "*.vue" {
    import Vue from "vue";
    export default Vue;
}
Run Code Online (Sandbox Code Playgroud)

从上面的2个链接

单文件组件...我们需要做的另一件事是告诉 TypeScript .vue 文件在导入时会是什么样子。我们将使用 vue-shims.d.ts 文件来完成此操作。

我们不需要将此文件导入到任何地方。它会被 TypeScript 自动包含,并告诉它任何以 .vue 结尾的导入内容都与 Vue 构造函数本身具有相同的形状。

然后 webpack 中的 typescript 模块加载器需要稍微改变一下

 module: {
    rules: [{
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
            //Then there are settings for a ts-loader, which helps load the TypeScript with Vue.
            //We also specified the appendTsSuffixTo: [/\.vue$/], option to ts-loader in our webpack.config.js file, 
            //which allows TypeScript to process the code extracted from a single file component.
            //https://github.com/TypeStrong/ts-loader#appendtssuffixto
            appendTsSuffixTo: [/\.vue$/],
        },
Run Code Online (Sandbox Code Playgroud)