最近阅读某Vue项目时发现其使用了TypeScript,我在编译时踩了很多坑。

为了更好地了解它的使用,今天尝试给一个新vue项目引入TS支持,初步探索一下使用它的好处。

什么是TypeScript?

TypeScript是JavaScript的超集,是 JavaScript 的强类型版本。然后在编译期去掉类型和特有语法,生成纯粹的 JavaScript 代码。由于最终在浏览器中运行的仍然是 JavaScript,所以 TypeScript 并不依赖于浏览器的支持,也并不会带来兼容性问题。

TypeScript 是 JavaScript 的超集,这意味着他支持所有的 JavaScript 语法。并在此之上对 JavaScript 添加了一些扩展,如 class / interface / module 等。这样会大大提升代码的可阅读性。

那为什么会出现TypeScript这门语言,主要是因为现在的JavaScript可以开发很多复杂的项目,但是JavaScript又缺乏其可靠性,在使用的时候需要我们为了代码的健壮性需要添加很多业务逻辑去判断。

TypeScript可以运行在浏览器环境、Node.js环境或者ECMAScript3或者更高的JavaScript的引擎中。

创建项目

随着vue2.5 更好的 TypeScript 集成,同时因为新开项目的契机,故准备动手尝试一下typescript + vue2

可以使用Vue-CLI创建,这里不再赘述。

安装相关依赖

安装过程中记得处理相关对等依赖报错,例如webpack版本啥的

  • 如果使用的是npm的话:

    1
    2
    3
    4
    5
    # 安装vue的官方插件
    npm i vue-class-component vue-property-decorator --save

    # ts-loader 和 typescript 必须安装,其他的相信你以后也会装上的
    npm i ts-loader typescript tslint tslint-loader tslint-config-standard --save-dev
  • 如果使用的是pnpm的话:

    1
    2
    pnpm add vue-class-component vue-property-decorator --save
    pnpm add ts-loader typescript tslint tslint-loader tslint-config-standard
  • 这些依赖的作用大致如下:

    1. vue-class-component:强化 Vue 组件,使用 TypeScript/装饰器 增强 Vue 组件。扩展vue支持typescript,将原有的vue语法通过声明的方式来支持ts。
    2. vue-property-decorator:在 vue-class-component 上增强更多的结合 Vue 特性的装饰器
    3. ts-loader:TypeScript 为 Webpack 提供了 ts-loader,其实就是为了让webpack识别 .ts .tsx文件
    4. tslinttslint-loader:我想你也会在.ts .tsx文件 约束代码格式(作用等同于eslint)
    5. tslint-config-standard:tslint 配置 standard风格的约束

配置Webpack

  • 在webpack配置中,或者和我一样是vue cli创建的项目,可以在vue.config.js中添加下面配置项,增加webpack对 .ts.tsx 文件的解析:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    configureWebpack: {
    resolve: {
    // 为了之后引入.ts的时候不写后缀
    extensions: [".ts", ".tsx", ".js", ".json"],
    alias: {
    '@': resolve('src')
    }
    },
    module: {
    // 添加webpack对.ts .tsx文件的解析
    rules: [
    {
    test: /\.ts$/,
    exclude: /node_modules/,
    enforce: 'pre',
    loader: 'tslint-loader'
    },
    {
    test: /\.tsx?$/,
    loader: 'ts-loader',
    exclude: /node_modules/,
    options: {
    appendTsSuffixTo: [/\.vue$/],
    }
    }
    ]
    }
    },

添加tsconfig.json

接下来在根路径下创建tsconfig.json文件

下方配置内容仅供参考,完整的配置请点击 tsconfig.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
// 编译选项
"compilerOptions": {
// 编译输出目标 ES 版本
"target": "es2015",
// 采用的模块系统
"module": "esnext",
// 编译过程中需要引入的库文件的列表
"lib": ["esnext", "dom"],
// 允许编译器编译JS,JSX文件
"allowJs": true,
// 允许在JS文件中报错,通常与allowJS一起使用
"checkJs": false,
// 在表达式和声明上有隐含的any类型时报错
"noImplicitAny": false,
// 将每个文件作为单独的模块
"isolatedModules": false,
// 对修饰器的实验支持
"experimentalDecorators": true,
// 允许export=导出,由import from 导入
"esModuleInterop": true,
// 不允许this有隐式的any类型
"noImplicitThis": false,
// 启动严格空值检查
"strictNullChecks": false,
// 跳过声明文件(扩展名为.d.ts的文件)的类型检查
"skipLibCheck": true,
// 模块解析策略,ts默认用node的解析策略,即相对的方式导入
"moduleResolution": "node",
// 允许在TypeScript模块中导入JSON文件
"resolveJsonModule": true,
// 在.tsx中支持JSX:React 或 Preserve
"jsx": "preserve",
// 不输出文件,即编译后不会生成任何js文件
"noEmit": true,
// 解析非相对模块名的基准目录
"baseUrl": "./",
// 指定特殊模块的路径
"paths": {
"@/*": ["./src/*"]
}
},
// 需要被编译的ts文件目录路径
"include": ["**/*.ts", "**/*.tsx"],
// TypeScript编译保存
"compileOnSave": false
}

添加xxx.d.ts

由于 TypeScript 默认并不支持 *.vue 后缀的文件,所以在 vue 项目中引入的时候需要创建一个 vue-shim.d.ts 文件,放在src文件夹目录下(与main.js同级)

1
2
3
4
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}

意思是告诉 TypeScript *.vue 后缀的文件可以交给 vue 模块来处理。如果删除,会发现import的所有vue类型的文件都会报错。

而在代码中导入 *.vue 文件的时候,需要写上 .vue 后缀。原因还是因为 TypeScript 默认只识别 *.ts 文件,不识别 *.vue 文件:import Component from 'components/component.vue'

添加tslint.json

在根路径下创建tslint.json文件

这里就很简单了,就是 引入 ts 的 standard 规范

1
2
3
4
5
6
{
"extends": "tslint-config-standard",
"globals": {
"require": true
}
}

啊啊啊自己手动配置的屁用没有疯狂报错,还是使用Vue-CLI创建项目吧,让他自动添加TypeScript支持。

参考内容: