Почему typescript (или это webpack) не находит мой вид vue?

#typescript #vue.js #webpack

#typescript #vue.js #webpack

Вопрос:

npx webpack

 TS2307: Cannot find module './App.vue' or its corresponding type declarations.
  

Я использую webpack, vue и typescript.

У меня базовая конфигурация webpack. В качестве точки входа используется файл typescript. Вывод — это сборка папки. Я использую загрузчик typescript и загрузчик vue.

Сборка работает нормально, пока я не перейду с javascript на typescript (т. Е. Если я переименовал app.ts в app.js и удалите загрузчик typescript из webpack, все работает).

Для vue я добавил файл tsconfig.json. Это помогло уменьшить количество ошибок. Но я все еще получаю эту ошибку, показанную выше.

(Я пытаюсь изучить webpack-vue-typescript из первых принципов. Поэтому я не хочу использовать vue cli или vue ui. Хотя я сгенерировал проект скелета vue typescript с помощью vue cli. Я сравнил свой код с кодом командной строки vue. Я не могу найти никаких различий.)

Вот полное сообщение об ошибке (с предупреждением)

 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?vueamp;type=scriptamp;lang=tsamp; 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?vueamp;type=scriptamp;lang=tsamp;' (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 srcapp.ts
[tsl] ERROR in D:codevuefssrcapp.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
  

Структура папок

  -- package.json
 -- webpack.config.js
 -- tsconfig.json
 -- src
     -- app.ts
     -- App.vue
     -- index.html
  

Это точка входа app.ts

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

new Vue({
    render: h => h(App)
}).$mount('#app')
  

App.vue

 <template>
  <div>hello from vue</div>
</template>
  

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']
    }
};
  

package.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"
    }
}
  

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"
    ]
}
  

index.html

 <html>
<head></head>
<body>
    <div id="app"></div>
</body>
</html>
  

Версии

  • npm 6.14.8
  • узел 14.15.0
  • tsc 4.0.5
  • другая версия, пожалуйста, package.json выше

Ответ №1:

Я решил проблему, следуя этим 2 ссылкам

  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;
}
  

Из 2 ссылок выше

Компоненты одного файла… Еще одна вещь, которую нам нужно будет сделать, это сообщить TypeScript, как будут выглядеть файлы .vue при импорте. Мы сделаем это с помощью файла vue-shims.d.ts.

Нам не нужно никуда импортировать этот файл. Он автоматически включается TypeScript и сообщает ему, что все импортированное, заканчивающееся на .vue, имеет ту же форму, что и сам конструктор Vue.

И затем загрузчик модуля typescript в webpack нуждался в небольшом изменении

  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$/],
        },