本篇文章讲述了基于 TypeScript + Babel + Rollup 搭建 ts 开发环境的解决方案,先赘述了此方案的优劣势,后按步骤具体讲解各个插件的配置方式,以帮助你们了解 TS 项目的编译原理。javascript
如下是该文章示例代码所依赖的基础环境,若有不符,配置引导可能没法正常运行。css
你们也许在 Babel 官网中看到过一个 preset,叫 @babel/preset-typescript
,没错,Babel 不只能够编译 ES6 的语法糖、对浏览器兼容性进行 polyfill 之外,还扩展了对 TypeScript 的支持,但它与官方的 TypeScript 有一些差别,比较特殊。vue
下面,由我来给你们一一道来。java
使用 TypeScript + Babel 方案搭建的项目有什么特色?node
开发编译过程,babel 会直接去除 typescript 类型标记,输出编译结果git
经过 eslint 作语法检查和类型检查github
为了下降语法检查带来的麻烦,经过配置 prettier 来格式化代码typescript
万事开头难,先说说 Babel 编译的劣势npm
Typescript 编译器彻底没有上述的问题,那为何还要画蛇添足使用 Babel 编译 Typescript 呢?json
先苦后甜,再来讲说 Babel 的优点
灵活性
- Babel 支持根据浏览器兼容性要求按需编译,这个 TypeScript 是不支持的,且官方也声明过不在考虑范围内Polyfill
- Babel 支持根据浏览器兼容性要求按需添加 PolyfillPlugins/Presets
- Babel 支持超级多的 Plugins,并且经过预设 Presets 能够免去复杂的 Plugins 配置,这点 TypeScript 也不能知足好,赘述完了,咱们来看一下实战演练,动手作个 demo。
懒人请执行如下命令,后面的就不用动手了(先查看上面的基础环境要求,以确保你的环境能够正常运行如下命令)
git clone https://github.com/lianer/test-babel-typescript.git
在命令行直接执行这些命令,先搭一个基础的仓库脚手架
mkdir test cd test npm init mkdir src cd src # 下面多行内容一整段复制执行 cat <<EOF > index.ts const sum = function (a: number, b: number): number { return a + b; }; console.log(sum(1, 2)); EOF
目录结构以下
| src | index.ts | package.json
配置核心要求的 typescript,虽然仅仅会在 lint 的时候用到它
一、安装 typescript 依赖
yarn add -D typescript
二、添加 tsconfig 配置文件
由于是 demo 项目,没有太多要求,所以这里保持默认的配置就足够了
./node_modules/.bin/tsc --init
支持对 ts 文件的编译,产出 js 文件
一、安装相关依赖
# 安装 rollup 套件 yarn add -D rollup rollup-plugin-babel@latest @rollup/plugin-node-resolve # 安装 babel 套件 yarn add -D @babel/core @babel/preset-env @babel/preset-typescript
二、添加 .babelrc 配置文件
{ "presets": [ "@babel/preset-env", "@babel/preset-typescript" ] }
三、添加 rollup.config.js 配置文件
const path = require('path'); const babel = require('rollup-plugin-babel'); const nodeResolve = require('@rollup/plugin-node-resolve'); const pkg = require('./package.json'); const extensions = ['.js', '.ts']; const resolve = function(...args) { return path.resolve(__dirname, ...args); }; module.exports = { input: resolve('./src/index.ts'), output: { file: resolve('./', pkg.main), // 为了项目的统一性,这里读取 package.json 中的配置项 format: 'esm', }, plugins: [ nodeResolve({ extensions, modulesOnly: true, }), babel({ exclude: 'node_modules/**', extensions, }), ], };
四、配置 npm scripts
若是先前项目里尚未 package.json
文件,能够先经过 npm init
命令初始化一个
"scripts": { "build": "rollup -c" },
五、在 rollup.config.js 中,用到了 package.json - main 配置项,所以别忘了修改一下 package.json
"main": "lib/index.js"
五、测试一下
npm run build
打包成功,输出结果
> test-typescript-babel@1.0.0 build /dev/test /dev/test/src/index.ts → lib/index.js... > rollup -c created lib/index.js in 460ms
目录结构
| lib | index.js | src | index.ts | .babelrc | package.json | rollup.config.js | tsconfig.json | yarn.lock
编译出的 lib/index.js 文件内容
var sum = function sum(a, b) { return a + b; }; console.log(sum(1, 2));
认真的同窗可能注意到了,Babel 仅仅只是把 TypeScript 类型移除
了而已。
注:若是你再这一步报错了,提示 The "path" argument must be of type string. Received type undefined
,则检查 package.json - main 配置是否有误
支持代码的类型校验、语法校验,以及代码格式化
一、安装依赖
# 安装 eslint 套件 yarn add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin # 安装 prettier yarn add -D prettier # 安装 husky、lint-staged 套件 yanr add -D husky lint-staged
二、添加配置文件 .eslintrc.js
.eslintrc.js 文件描述 eslint 语法检查和 ts 类型检查的规则
const path = require('path'); module.exports = { parser: '@typescript-eslint/parser', extends: [ 'plugin:@typescript-eslint/recommended' // Uses the recommended rules from the @typescript-eslint/eslint-plugin ], parserOptions: { project: path.resolve(__dirname, './tsconfig.json'), tsconfigRootDir: __dirname, ecmaVersion: 2019, // Allows for the parsing of modern ECMAScript features sourceType: 'module', // Allows for the use of imports }, rules: { // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs // e.g. "@typescript-eslint/explicit-function-return-type": "off", } };
三、添加配置文件 .prettierrc
.prettierrc 文件描述代码格式化的规则
{ "semi": true, "trailingComma": "all", "singleQuote": true, "printWidth": 120, "tabWidth": 2 }
四、修改 package.json,配置 husky 和 lint-staged
一个很是庞大的项目,eslint 完整检查可能须要花费几分钟的时间。
而 husky + lint-staged 能够实现只对提交的文件进行检查,从而提高开发效率。
这样即便你的项目再大,也仅仅是检查本次提交的文件,只需几秒钟。
"scripts": { "lint": "eslint 'src/**/*.{js,ts}'" }, "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*./src/**/*.{js,ts,json,css,less,md}": [ "prettier --write", "yarn lint" ] }
上述配置能够实如今执行 git commit
时调用 prettier
格式化代码,并使用 eslint
作类型和语法的检查。
五、若是想要保存文件时自动格式化代码,则须要安装 vscode 插件
prettier
,并作以下配置
"editor.formatOnSave": false, // 全局默认关闭不作格式化,仅针对 js 和 ts 格式化 "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, },
进一步完善 rollup 的打包机制,支持多任务打包,打包出不一样项目所需的资源文件。
引入 rimraf, npm-run-all, rollup-plugin-uglify, lodash.merge
一、 安装依赖
yarn add -D rimraf npm-run-all rollup-plugin-uglify lodash.merge
二、修改 rollup.config.js
const path = require('path'); const babel = require('rollup-plugin-babel'); const nodeResolve = require('@rollup/plugin-node-resolve'); const uglify = require('rollup-plugin-uglify').uglify; const merge = require('lodash.merge'); const pkg = require('./package.json'); const extensions = ['.js', '.ts']; const resolve = function(...args) { return path.resolve(__dirname, ...args); }; // 打包任务的个性化配置 const jobs = { esm: { output: { format: 'esm', file: resolve(pkg.module), }, }, umd: { output: { format: 'umd', file: resolve(pkg.main), name: 'rem', }, }, min: { output: { format: 'umd', file: resolve(pkg.main.replace(/(.\w+)$/, '.min$1')), name: 'rem', }, plugins: [uglify()], }, }; // 从环境变量获取打包特征 const mergeConfig = jobs[process.env.FORMAT || 'esm']; module.exports = merge( { input: resolve('./src/index.ts'), output: {}, plugins: [ nodeResolve({ extensions, modulesOnly: true, }), babel({ exclude: 'node_modules/**', extensions, }), ], }, mergeConfig, );
三、修改 package.json - scripts
"main": "lib/index.umd.js", "module": "lib/index.esm.js", "scripts": { "lint": "eslint 'src/**/*.{js,ts}'", "dev": "rollup -w -c --environment FORMAT:esm", "build:esm": "rollup -c --environment FORMAT:esm", "build:umd": "rollup -c --environment FORMAT:umd", "build:min": "rollup -c --environment FORMAT:min", "build": "rimraf lib/* && run-p build:esm build:umd build:min" },
在这里,咱们先经过 rimraf 工具清空 lib 目录,而后再经过 npm-run-all 工具并行 3 个子编译任务
这里的 3 个子编译任务,分别是:
四、测试执行打包命令
npm run build
输出结果文件
| lib | rem.esm.js | rem.umd.js | rem.umd.min.js
统一编辑器的行为,好比空格、缩进等,并添加 git 忽略列表
一、添加 .editorconfig 配置文件,编辑器安装相应的 editorconfig 插件,使该项目统一应用相同的空格、缩进等编码风格
root = true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true
二、添加 .gitignore 配置文件,这里推荐一个 .gitignore 的生成工具 - gitignore.io
# Created by https://www.gitignore.io/api/vuejs,visualstudiocode # Edit at https://www.gitignore.io/?templates=vuejs,visualstudiocode ### VisualStudioCode ### .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json ### VisualStudioCode Patch ### # Ignore all local history of files .history ### Vuejs ### # Recommended template: Node.gitignore node_modules/ dist/ npm-debug.log yarn-error.log # End of https://www.gitignore.io/api/vuejs,visualstudiocode
至此,基于 Rollup + Babel + TypeScript + ESLint 的整套套件的搭建就完成了。
若是有不够完善的地方,欢迎在文末进行点评[点赞]。