1. 安装
yarn add -D typescript ts-loader vue-class-component vue-property-decorator
2. 修改 vue.config.js
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = {
// ...
chainWebpack: config => {
// ...
// add ts-loader
config.module
.rule('ts')
.test(/\.tsx?$/)
.exclude
.add(resolve('node_modules'))
.end()
.use('cache-loader')
.loader('cache-loader')
.options({
cacheDirectory: resolve('node_modules/.cache/ts-loader')
})
.end()
.use('babel-loader')
.loader('babel-loader')
.end()
.use('ts-loader')
.loader('ts-loader')
.options({
transpileOnly: false, // 关闭类型检查,即只进行转译(类型检查交给webpack插件(fork-ts-checker-webpack-plugin)在另一个进程中进行,这就是所谓的多进程方案,如果设置transpileOnly为false, 则编译和类型检查全部由ts-loader来做, 这就是单进程方案.显然多进程方案速度更快)
appendTsSuffixTo: ['\\.vue$'],
happyPackMode: false
})
.end()
}
}
3. 新增 3 个文件
-
tsconfig.json// 使用官方的,其他配置可以自定义 { "compilerOptions": { // 与 Vue 的浏览器支持保持一致 "target": "es5", // 这可以对 `this` 上的数据 property 进行更严格的推断 "strict": true, // 如果使用 webpack 2+ 或 rollup,可以利用 tree-shake: "module": "es2015", "moduleResolution": "node" } }丰富配置的版本:
{ "externalTranspiler": { "name": "babel", "options": {} }, "buildOnSave": false, "compileOnSave": false, "indentSize": 2, "tabSize": 2, "compilerOptions": { "suppressOutputPathCheck": true, "baseUrl": ".", "noEmit": false, "declaration": false, "moduleResolution": "node", "module": "commonjs", "target": "es6", "allowNonTsExtensions": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "jsx": "react", "removeComments": false, "noLib": false, "preserveConstEnums": false, "suppressImplicitAnyIndexErrors": true }, "filesGlob": [ "app/**/*.ts" ], "files": [ "app/routing.ts" ], "atom": { "rewriteTsconfig": false } } -
shims-vue.d.tsAmbient Declarations(通称:外部模块定义) ,主要为项目内所有的 vue 文件做模块声明,毕竟 ts 默认只识别 .d.ts、.ts、.tsx 后缀的文件;(即使补充了 Vue 得模块声明,IDE 还是没法识别 .vue 结尾的文件,这就是为什么引入 vue 文件时必须添加后缀的原因,不添加编译也不会报错)
declare module '*.vue' { import Vue from 'vue'; export default Vue; } -
shims-tsx.d.ts后者为 JSX 语法的全局命名空间,这是因为基于值的元素会简单的在它所在的作用域里按标识符查找(此处使用的是**无状态函数组件 (SFC)**的方法来定义),当在 tsconfig 内开启了 jsx 语法支持后,其会自动识别对应的 .tsx 结尾的文件,可参考官网 jsx。
import Vue, { VNode } from 'vue'; declare global { namespace JSX { // tslint:disable no-empty-interface interface Element extends VNode { } // tslint:disable no-empty-interface interface ElementClass extends Vue { } interface IntrinsicElements { [elem: string]: any } } }
4. 额外
一些必要的工具库,可以考虑加入,如 eslint :
module.exports = {
// ...
chainWebpack: config => {
// ...
// eslint 自动修复 (修改已经存在的loader)
config.module
.rule('eslint')
.test(/\.(vue|(j|t)sx?)$/)
.pre() // eslint是pre处理的
.use('eslint-loader')
.loader('eslint-loader')
.tap(options => { // 修改已经存在loader的配置
options.fix = true
return options
})
.end()
}
}