前端基础能力 - Babel编译及代码规范 - 图1

前言

大家一起学习探讨 三大开发环境利器 ESLint, EditorConfig 和 Babel, 前两者属于代码规范,最后一个属于JavaScript的编译器。

浅谈 Babel 的 AST 编译过程,以及Babel 的 Plugin 和 Preset 的区别。

如何搭建项目开发静态代码检查规范,大厂的开箱即用的 EditorConfig 配置规则。

把三个知识点放在一起更好配合下文的React项目开发环境搭建实践。

Babel + React 开发环境

源码地址:https://github.com/dkypooh/front-end-develop-demo/tree/master/base/babel7-react

理解 Eslint 和 EditorConfig

ESLint 是一种可组装的 JavaScript 和 JSX 检查工具。 完全可配置,可以自定义每一个规则。

EditorConfig 是一个跨编辑器的项目统一编码样式管理规范,由文件定义格式和文本编辑插件格式。

理解 Babel

Babel 是一个代码编译器,输入代码编译输出代码 (source code => output code)。

开箱即用的 EditorConfig 配置规则

  1. # 所有文件匹配
  2. [*]
  3. indent_style = space # 缩进样式
  4. end_of_line = lf # 结束换行,cr回车
  5. indent_size = 2 # 缩进2个空格
  6. charset = utf-8 # 文件utf-8编码
  7. trim_trailing_whitespace = true # 去掉末尾空格
  8. insert_final_newline = true # 在最后插入一个新行
  9. # md文件匹配
  10. [*.md]
  11. trim_trailing_whitespace = false # 取消去掉末尾空格

在 VSCode 编辑器下要首先要下载 EditorConfig 插件,然后配置代码样式规划:

前端基础能力 - Babel编译及代码规范 - 图2

Babel编译原理

AST语法解析实例

通过 AST 树形描述了表达式的语法结构。例如变量声明 (VariableDeclaration),字符穿字面量 (StringLiteral) 及值 (value)等等。
前端基础能力 - Babel编译及代码规范 - 图3

如下是 AST 编译器地址:AST链接地址

Babel编译过程

前端基础能力 - Babel编译及代码规范 - 图4
abel 的三个主要处理步骤分别是: 解析(parse)转换(transform)生成(generate)。原理不是本章重点,具体可以查看参考文档[Babel插件指南]。

  • 解析: 解析步骤接收代码并输出 AST。 这个步骤分为两个阶段:词法分析(Lexical Analysis语法分析(Syntactic Analysis)
    • 词法解析: 词法分析阶段把字符串形式的代码转换为令牌(tokens) 流。
    • 语法解析: 语法分析阶段会把一个令牌流转换成 AST语法书的形式。
  • 转换: 转换步骤接收 AST 并对其进行遍历,在此过程中对节点进行添加、更新及移除等操作。
  • 生成: 代码生成步骤把最终(经过一系列转换之后)的 AST转换成字符串形式的代码,同时创建源码映射(source maps)。
    • 代码生成其实很简单:深度优先遍历整个 AST,然后构建可以表示转换后代码的字符串。

Babel基础配置

Babel 是一个工具链,主要用于在旧的浏览器或环境中将 ECMAScript 2015+ 代码转换为向后兼容版本的 JavaScript 代码。

babel-cli 命令行转换工具

  1. # 工具安装
  2. $ npm i babel-cli -g
  3. # 转码结果输出到标准输出
  4. $ babel example.js
  5. # 转码结果写入一个文件
  6. # --out-file 或 -o 参数指定输出文件
  7. $ babel example.js --out-file compiled.js
  8. # 或者
  9. $ babel example.js -o compiled.js
  10. # 整个目录转码
  11. # --out-dir 或 -d 参数指定输出目录
  12. $ babel src --out-dir lib
  13. # 或者
  14. $ babel src -d lib
  15. # -s 参数生成source map文件
  16. $ babel src -d lib -s

.babelrc 配置文件

在特定环境的时候,您可以用 env 选项来设置特定的配置, 如下在生产环境中指定插件:

  1. {
  2. "env": {
  3. "production": {
  4. "plugins": ["transform-react-constant-elements"]
  5. }
  6. }
  7. }

env 选项的值将从 process.env.BABEL_ENV 获取,如果没有的话,则获取 process.env.NODE_ENV 的值,它也无法获取时会设置为 development

您可以通过下面的方法设置环境变量, 也可以使用跨平台命令 cross-env

  1. # 指定Babel环境
  2. $ BABEL_ENV=production <commond>
  3. # 跨平台使用
  4. $ cross BABEL_ENV=production <commond>

查找规则

Babel 会在正在被转录的文件的当前目录中查找一个 .babelrc 文件。 如果不存在,它会遍历目录树,直到找到一个 .babelrc 文件,或一个 package.json 文件中有 “babel”: {}。

.babelrc 的几种配置方式

通过 package.json 使用Babel

  1. {
  2. "name": "my-package",
  3. "version": "1.0.0",
  4. "babel": {
  5. // my babel config here
  6. }
  7. }

通过 .babelrc 使用 Babel

  1. {
  2. plugins: [],
  3. presets: []
  4. }

React 开发环境配置实例

如下是配置 React 开发环境的事例,需要用到 es2015, react, stage-1三个 Preset 预设装置。

  1. # ES2015转码规则
  2. $ npm install --save-dev babel-preset-es2015
  3. # react转码规则
  4. $ npm install --save-dev babel-preset-react
  5. # ES7不同阶段语法提案的转码规则(共有4个阶段),选装一个
  6. $ npm install --save-dev babel-preset-stage-0
  1. {
  2. "presets": [
  3. "es2015",
  4. "react",
  5. "stage-1"
  6. ]
  7. }

Plugin 和 Preset 区别

Preset 是由一系列的 Plugins 组成的。可以组合完成 Plugins 的事情。例如 babel-preset-react 由如下 Plugins 组成:

  1. preset-flow
  2. syntax-jsx
  3. transform-react-jsx
  4. transform-react-display-name

ESLint 配置

为了在 Node.js 上运行 ESLint,你必须先安装 npm,之后全局安装 eslint

  1. npm i eslint -g // 全局安装eslint

初始化eslint文件前需要有 package.json 文件,生成 package.json,之后再生成 .eslint.js 文件

  1. npm init // 生成package.json
  2. eslint --init // 生成.eslint.js

Eslint fix 可以根据 eslint 检查配置 自动修复编码问题。 参考ESLint修复选项

  1. ## 语法
  2. eslint [options] file.js [file.js] [dir]
  3. ## 实例, 按照eslint配置,检查根目录和src目录,同时修复
  4. eslint --config .eslintrc.js ./src/* --fix

ESLint Rules 配置

ESLint Rules 配置是ESLint的核心概念,规定了多人协作开发过程的代码规范。如下讲解下 ESLint Rules 配置语法。
前端基础能力 - Babel编译及代码规范 - 图5

Rules 属性可以做下面的任何事情以扩展(或覆盖)规则:

  1. # 改变继承的规则级别而不改变它的选项:
  2. 基础配置:"eqeqeq": ["error", "allow-null"]
  3. 派生的配置:"eqeqeq": "warn"
  4. 最后生成的配置:"eqeqeq": ["warn", "allow-null"]
  5. # 覆盖基础配置中的规则的选项
  6. 基础配置:"quotes": ["error", "single", "avoid-escape"]
  7. 派生的配置:"quotes": ["error", "single"]
  8. 最后生成的配置:"quotes": ["error", "single"]

ESLint常用插件

如下列举项目开发中一些常用插件和 ESLint 规范。

  • eslint-plugin-react: React语法规则插件
  • eslint-config-airbnb: airbnb ESLint开发规范
  • eslint-config-standard: JavaScript ESLint开发规范

搭建React项目开发环境

本小节通过搭建React项目开发环境,实践讲解如何配置 ESLint 和 editorconfig 。 同时 Babel 插件如何使用。

配置参考项目地址: React项目仓库地址

初始化开发环境

  1. npm init // 生成package.json
  2. eslint --init // 生成.eslint.js

初始化项目目录

editorconfigbabel可以参考上文配置。

前端基础能力 - Babel编译及代码规范 - 图6

Package依赖 主要有三大方面:Babel依赖,ESLint依赖 和 Webpack配置

编写React组件

前端基础能力 - Babel编译及代码规范 - 图7

NPM Script命令行

  1. $ npm run start // 启动服务
  2. $ npm run build // 构建代码
  3. $ npm run size // 代码大小分析
  4. $ npm run lint // ESLint检查

输出页面

前端基础能力 - Babel编译及代码规范 - 图8

Babel6 迁移 Babel7

为了更好的适应未来的变化,越来越多老的项目需要迁移到 Babel7上面,作者总结了如下迁移方案,Babel渐进性更新弃用了一些原来的插件。有如下重要迁移的改变:

  • 弃用 Stage Preset: Babel正在删除 Stage presets,以支持明确的提案使用。默认使用Stage-0支持更多的特性。
  • 弃用年份 Preset: 例如babel-preset-es2015等, 使用@babel/preset-env来代替
  • 删除 @babel/polyfill 中的 polyfill 提案: polyfill插件会产生一些副作用,使用@babel/runtime代替,优化代码

具体可以参考 React-Babel7迁移项目

结语

通过本章的阅读,我们可以了解到 Babel 编译的三个核心步骤(inputCode => outputCode), 同时通过React项目实践 Babel, ESlint, Editorconfig 三大能力。

最后把此项目从 Babel6 迁移到 Babel7,增加新的特性,适应未来的变化。

下一章将要学习 Webpack 环境开发搭建以及常用的Webpack优化技巧,需要了解下 Webpack 的基本知识和原理。

请预先预习 Webapck 官方文档

思考题

Q:通过 AST Explorer https://astexplorer.net/# 观察下抽象语法书的结构?

参考文档