增加typescript,ts-loader,@babel/plugin-proposal-class-properties,@babel/plugin-proposal-decorators
npm i -D ts-loader typescript @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators
@babel/plugin-proposal-class-properties 是为了支持在class中用类属性的写法:
@babel/plugin-proposal-decorators是为了支持在class中用装饰器语法:
并在babel.config.js中增加配置:
对tsconfig.json做修改:
其中需要关注的是
"module": "es2020"因为我使用了动态import,如果module是"es6"或者更低则不识别动态import。"experimentalDecorators": true支持装饰器语法。"emitDecoratorMetadata": true配合reflect-metadata包。
在vue.config.js中增加ts-loader配置。起初我在chainWebpack中配置:
但是编译时报错不识别装饰器符号'@',
在排查了vue-loader、vue-template-compiler,@babel/plugin-proposal-decorators,@babel/plugin-proposal-class-properties,ts-loader配置之后,把ts-loader的配置放到configureWebpack中后,这个报错消失了:
在这过程中了解到vue-loader从15版本开始借助vue-template-compiler把SFC文件的各个语法块解析成descriptor,
然后selectBlock方法中使用webpack中配置的module的loader去编译各个语法块:
因此上面报错不识别'@'符号,而且提示需要另外的loader去处理vue-loader的结果,应该就是ts-loader没配置好。
文件后缀类型中增加ts
增加vue-class-component,vue-property-decorator
npm i vue-class-component vue-property-decorator reflect-metadata
然后就是把.js文件改成.ts,.vue中的<script>变成<script lang="ts">,vue-class-component + vue-property-decorator的配置方式参看各自文档即可。
为了不让在引用.vue文件时报错
创建一个.d.ts文件对.vue后缀的文件做一个类型声明,并在tsconfig.json的include中加上该文件
我增加的vue-shim.d.ts文件如下:
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
declare module 'vue/types/vue' {
export interface Vue {
/**
*
自定义的比如 Vue.prototype.$api = myApi 这样的全局属性,要在vue组件内用 this.$api 时类型
检验不报错,就需要在这里加声明,比如:
$api: any
*/
}
}
改用@typescript-eslint/parser
npm i @typescript-eslint/eslint-plugin @typescript-eslint/parser
增加.eslintrc.js文件:详细配置参考@typescript-eslint/parser文档
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
],
env: {
browser: true
},
extends: [
"plugin:vue/essential",
"eslint:recommended",
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
"parserOptions": {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
extraFileExtensions: ['.vue'],
},
"rules": {
"vue/no-unused-components": "warn"
}
};