Skip to content

Babel + TS + ESLint 构建 js 环境

开发中我们很少直接去接触babel,但是babel对于前端开发来说,目前是不可缺少的一部分。我们想要使用ES6+的语法,想要使用TypeScript,开发React项目,它们都是离不开Babel的。

Stage-x

首先我们需要了解 ES 规范,它是由 TC39 组织制定。

TC39 遵循的原则是:分阶段加入不同的语言特性,新流程涉及四个不同的 Stage

  • Stage 0:strawman(稻草人),任何尚未提交作为正式提案的讨论、想法变更或者补充都被认为是第 0 阶段的" 稻草人";
  • Stage 1:proposal(提议),提案已经被正式化,并期望解决此问题,还需要观察与其他提案的相互影响;
  • Stage 2:draft(草稿),Stage 2 的提案应提供规范初稿、草稿。此时,语言的实现者开始观察 runtime 的具体 实现是否合理;
  • Stage 3:candidate(候补),Stage 3 提案是建议的候选提案。在这个高级阶段,规范的编辑人员和评审人员必 须在最终规范上签字。Stage 3 的提案不会有太大的改变,在对外发布之前只是修正一些问题;
  • Stage 4:finished(完成),进入 Stage 4 的提案将包含在 ECMAScript 的下一个修订版中

Babel

Babel 是一个工具链,主要用于旧浏览器或者缓解中将ECMAScript 2015+代码转换为向后兼容版本的 JavaScript。它包括:语法转换、源代码转换、Polyfill实现目标缓解缺少的功能等。

例如:(箭头函数转普通函数)

js
// 使用 Babel 转译前
arr.map(item => item + 1)

// 转译后
arr.map(function (item){
  return item + 1;
})

提示:Babel 还提供了一个在线版的 REPL 页面,读者可在 babeljs.io/repl 实时体验功能效果。

需要借助 babel-loader 来实现转译功能

安装

@babel/core: babel 核心代码 必须安装

@babel/preset-env : babel 预设,

bash
npm i -D @babel/core @babel/preset-env babel-loader

使用:可以在 module.rule 中进行配置,也可以新建 .babelrc 配置文件进行配置

js
{
        test: /\.js$/,
        use: [
            {
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env'],
                },
            },
        ],
},

原理

编译器的工作流程:

  • 解析阶段(Parsing)
  • 转换阶段(Transformation)
  • 生成阶段(Code Generation)

可以查看一个开源的小型编译器 是如何实现的

具体工作流程

原生代码 -> 词法分析 -> tokens 数组 -> 语法分析(成为parsing) -> AST 抽象语法树 -> 遍历 -> 访问 -> 应用插件 -> 新的AST抽象语法树 -> 目标源代码

预设 preset

常见的预设有:

babel-preset-env

可以配置目标浏览器 browserslist ,不同浏览器的兼容是不一样的,打包出来的代码也可能是不一样的

js
options: {
    presets: [
        ['@babel/preset-env', {
            // targets: 'last 2 version',
            targets: {
                'chrome': '88'
            }
        }]
    ],
},

image-20240822114013746

image-20240822113908676

在 babel7 之前,我们能看到使用这样配置 stage 预设

js
{
    "presets": ["stage-0"]
}

在 babel7 以及之后,建议使用 preset-env 来设置

polyfill

polyfill 可以理解为补丁的意思,可以帮助我们更好的使用 JavaScript。比如我们使用了一些语法特性(例如:Promise, Generator, Symbol等以及实例方法例如 Array.prototype.includes等)但是某些浏览器压根不认识这些特性,必然会报错。就可以使用 polyfill 来打补丁。

  • babel 7.4.0 之前,可以使用 @babel/polyfill 包来进行打补丁,现在不推荐
  • babel 7.4.0 之后,可以通过 core-js 和 regenerator-runtime 来完成polyfill 的使用

image-20240822135850447

bash
npm i core-js regenerator-runtime

我们需要在 babel 的配置文件中,比如 babel.config.js 文件中进行配置,给preset-env配置一些属性

  • useBuiltIns:设置以什么样的方式来使用polyfill。
    • entry 表示会根据 browserslist 目标导入所有的polyfill,但是对应的包也会变大
    • usage 表示在使用的时候按需导入,需要排除 node_modules : exclude: /node_modules/
    • false 表示不使用 polyfill 进行适配,这个时候也就不需要使用 corejs 来指定版本了
  • corejs:设置corejs的版本,目前使用较多的是3.x的版本,比如我使用的是3.38.x的版本;
    • 另外corejs可以设置是否对提议阶段的特性进行支持;
    • 设置 proposals属性为true即可
js
presets: [
    ['@babel/preset-env', {
            targets: 'last 2 version',
            useBuiltIns: 'entry',
            corejs: 3.8
    	}]
	],
]

TypeScript

Webpack 有很多种接入 TypeScript 的方法,包括 ts-loaderawesome-ts-loaderbabel-loader。通常可使用 ts-loader 构建 TypeScript 代码

bash
npm i -D typescript ts-loader

使用命令初始化 ts 配置文件

bash
npx tsc --init

使用 ts-loader

js
{
    test: /\.ts$/,
    exclude: /node_modules/,
    use: 'ts-loader'
},

除了可以使用TypeScript Compiler来编译TypeScript之外,我们也可以使用Babel。推荐使用preset :

@babel/preset-typescript

bash
npm i -D @babel/preset-typescript
js
presets: [
    ['@babel/preset-env', {
        targets: 'last 2 version',
        useBuiltIns: 'usage',
        corejs: 3
    }],
    ['@babel/preset-typescript']
],
js
{
    test: /\.ts$/,
    exclude: /node_modules/,
    use: 'babel-loader'
}

不过,@babel/preset-typescript 只是简单完成代码转换,并未做类似 ts-loader 的类型检查工作。

我们使用Babel来完成代码的转换,使用 tsc 来进行类型的检查。

json
{
      "scripts": {
          "build": "webpack",
          "type-check": "tsc --noEmit"
      },
}

ESLint

安装

bash
npm i -D eslint

初始化配置文件

bash
npx eslint --init

image-20240822151121239

选择自己所需的配置

image-20240822151258515

如果每次校验时,都需要执行一次npm run eslint就有点麻烦了,所以我们可以使用一个VSCode的插件: ESLint。它会找出这些风格不一致的地方,并予以告警

编译时对代码进行检测可以使用 eslint-loader 或者 eslint-webpack-plugin

bash
npm i -D eslint-webpack-plugin eslint-loader

除常规 JavaScript 代码风格检查外,我们还可以使用适当的 ESLint 插件、配置集实现更丰富的检查、格式化功能

Released under the MIT License.