![](/assets/img/weixin-blog.311ae013.png)
# tsconfig.json配置说明
{
"compilerOptions": {
/* 基本选项 */
"target": "es6", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
"module": "commonjs", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
"lib": [], // 指定要包含在编译中的库文件
"allowJs": true, // 允许编译 javascript 文件
"checkJs": true, // 报告 javascript 文件中的错误
"jsx": "preserve", // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
"declaration": true, // 生成相应的 '.d.ts' 文件
"declarationDir": "./dist/types", // 生成的 '.d.ts' 文件保存文件夹
"sourceMap": true, // 生成相应的 '.map' 文件
"outFile": "./", // 将输出文件合并为一个文件
"outDir": "./dist", // 指定输出目录
"rootDir": "./", // 用来控制输出目录结构 --outDir.
"removeComments": true, // 删除编译后的所有的注释
"noEmit": true, // 不生成输出文件
"importHelpers": true, // 从 tslib 导入辅助工具函数
"isolatedModules": true, // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似).
/* 严格的类型检查选项 */
"strict": true, // 启用所有严格类型检查选项
"noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错
"strictNullChecks": true, // 启用严格的 null 检查
"noImplicitThis": true, // 当 this 表达式值为 any 类型的时候,生成一个错误
"alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict'
/* 额外的检查 */
"noUnusedLocals": true, // 有未使用的变量时,抛出错误
"noUnusedParameters": true, // 有未使用的参数时,抛出错误
"noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时,抛出错误
"noFallthroughCasesInSwitch": true, // 报告switch语句的fallthrough错误。(即,不允许switch的case语句贯穿)
/* 模块解析选项 */
"moduleResolution": "node", // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
"baseUrl": "./", // 用于解析非相对模块名称的基础目录
"paths": {}, // 模块名到基于 baseUrl 的路径映射的列表
"rootDirs": [], // 根文件夹列表,其组合内容表示项目运行时的结构内容
"typeRoots": [], // 包含类型声明的文件列表
"types": [], // 需要包含的类型声明文件名列表
"allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。
"esModuleInterop": true, // 支持合成模块的默认导入
/* Source Map Options */
"sourceRoot": "./", // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
"mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置
"inlineSourceMap": true, // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件
"inlineSources": true, // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性
/* 其他选项 */
"experimentalDecorators": true, // 启用装饰器
"emitDecoratorMetadata": true // 为装饰器提供元数据的支持
},
/* 指定编译文件或排除指定编译文件 */
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"],
"files": ["index.ts", "test.ts"],
// 从另一个配置文件里继承配置
"extends": "@tsconfig/recommended",
// 让 IDE 在保存文件的时候根据 tsconfig.json 重新生成文件
"compileOnSave": true // 支持这个特性需要Visual Studio 2015, TypeScript 1.8.4 以上并且安装 atom-typescript 插件
}
# Rollup + TypeScript
在 Rollup 打包中,我们一般只需要添加 @rollup/plugin-typescript (opens new window) 插件即可,该插件会默认读取项目根目录下的 tsconfig.json
配置文件。
Rollup 的配置就像这样:
// file: rollup.config.js
import typescript from '@rollup/plugin-typescript';
export default {
input: 'src/index.ts',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [typescript()]
};
结合其源码:
{
"peerDependencies": {
"rollup": "^2.14.0||^3.0.0",
"tslib": "*",
"typescript": ">=3.7.0"
},
}
默认使用 TSC 作为 TS 的编译器,因为 typescript 声明了是 peerDependencies
,因此会采用项目中安装的 typescript 版本,即是使用我们项目中的 TS 编译器。
# Webpack + TypeScript
在 Webpack 中的 TypeScript (opens new window) 官方文档中,指明了需要安装:typescript
和 ts-loader
两个模块。
配置 Webpack 并支持 TypeScript 的配置如下:
// file: webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
可以看出 Webpack 主要是依赖 ts-loader
实现对 TypeScript 语法的编译支持,再看看对 ts-loader
的介绍:
换句话说,ts-loader 实际调用了 TSC 来编译 TS 文件,TSC 的配置依赖于你项目中的 tsconfig.json 文件。
如果使用了 Babel,则可以使用 @babel/preset-typescript (opens new window) 来处理,但 Babel 不会做 TS 类型校验,在打包工具 Rollup 和 Webpack 中都可以引入 Babel,那么接下来看看 Babel 是如何处理 TypeScript 的吧!
# Babel + TypeScript
Babel 处理 TS 需要安装 @babel/preset-typescript 模块,然后在 babel 项目配置文件中声明:
// 配置说明:https://babeljs.io/docs/en/babel-preset-typescript
{
"presets": ["@babel/preset-typescript"]
}
但 Babel 中只会对 TS 代码转为 JS 代码(通过 parse TS 文件为 AST,并直接移除类型信息,然后打印目标代码),不会去做 TS 类型检查,所以 Babel 编译 TS 文件相较于 TSC 的速度更快!
同时,因为 Babel 会根据不同的兼容环境,按需引入 pollyfill,比 TSC 直接引入 core-js
更优雅,因此使用了 Babel 打包的体积也会更小。
TS 类型检查工作可以交给代码编辑器承担,当然同时可以新增 TS 检查的命令:
// package.json
{
"script": {
"tsCheck": "tsc --noEmit",
}
}
可以把类型检查放到特定的 npm scripts 生命周期之前,另外其实也可以将类型检查放到 git commit 阶段,用于做必要的 TS 类型检查,保证项目的正确性。
# ESbuild + TypeScript
通过 Vite 体会到了 ESbuild (opens new window) 带来的开发热更新“极速”体验,针对 TS 项目,ESbuild 和 Babel 是相同的编译策略,即仅编译,不校验类型。
ESbuild 处理 TypeScript (opens new window) 同样可以带来飞一般的感觉!
但在 ESbuild 中需要启用 tsconfig 中的 isolatedModules
功能,然后在类型引入的时候需要替换,规则参考如下:
// old
import { UserType } from './types';
// new
import type { UserType } from './types';
因为 ESbuild 是单独编译每个文件,无法判断引入的是 Type(类型) 还是 值,所以需要开发者显示地声明是“Type”。
同时还需要启用 esModuleInterop
功能,用于支持 ESM 模块合成默认导入,以兼容 CJS 和 ESM 规范。
另外 ESbuild 不支持:emitDecoratorMetadat
、const enum
类型和 *.d.ts
文件
此外,关注到兼容性处理这方面,Bable 和 ESbuild 是类似的,因此会存在兼容性问题:
对于装饰器处理不支持,因为 TS 是 JS 的超集,ESnext 的规范提案某些还不是稳定的,因此如果有这方面诉求的项目,可以借助 TSC 做预编译,例如使用 Rollup 的 typescript 插件 或 Webpack 的 ts-loader 方式。
- 本文链接: https://mrgaogang.github.io/javascript/typescript.html
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明出处!