主要内容
babel 工作流
- Toolings
- Plugins
- Presets
- Polyfills
babel7 做的更新
1.babel 工作流
输入字符串 -> @babel/parser parser -> AST -> transformer[s] -> AST -> @babel/generator -> 输出字符串
AST
抽象语法树 (abstract syntax tree 或者缩写为 AST), 或者语法树 (syntax tree), 是源代码的抽象语法结构的树状表现形式, 这里特指编程语言的源代码.
和抽象语法树相对的是具体语法树 (concrete syntaxtree), 通常称作分析树 (parse tree).
一般的, 在源代码的翻译和编译过程中, 语法分析器创建出分析树. 一旦 AST 被创建出来, 在后续的处理过程中, 比如语义分析阶段, 会添加一些信息.
AST 示例 http://esprima.org/demo/parse.html
2.Toolings
@babel/parser 将源代码解析成 AST.
@babel/generator 将 AST 解码生 js 代码.
@babel/core 包括了整个 babel 工作流, 也就是说在 @babel/core 里面我们会使用到 @babel/parser,transformer[s], 以及 @babel/generator.
@babel/code-frame 用于生成错误信息并且打印出错误原因和错误行数.(其实就是个 console 工具类)
@babel/helpers 也是工具类, 提供了一些内置的函数实现, 主要用于 babel 插件的开发.
@babel/runtime 也是工具类, 但是是为了 babel 编译时提供一些基础工具库. 作用于 transformer[s] 阶段, 当然这是一个工具库, 如果要使用这个工具库, 还需要引入 @babel/plugin-transform-runtime, 它才是 transformer[s] 阶段里面的主角.
@babel/template 也是工具类, 主要用途是为 parser 提供模板引擎, 更加快速的转化成 AST
@babel/traverse 也是工具类, 主要用途是来便利 AST 树, 也就是在 @babel/generator 过程中生效.
@babel/types 也是工具类, 主要用途是在创建 AST 的过程中判断各种语法的类型.
通过了解这每一个工具的用途 我们对前面简略的工作流坐下填充.
@babel/code-frame 为全局错误捕获工具类
@babel/core
输入字符串
- @babel/parser
- @babel/template
- @babel/types
- AST
- transformer[s]
- @babel/helpers
- AST
- @babel/generator
- @babel/traverse
- 3.Plugins
每一个 Plugin 处理自己的一种 AST Type 语法. 重点讲一下 @babel/plugin-transform-runtime 用来解析 @babel/runtime 工具类内的函数 core-js
- {
- "plugins": [
- ["@babel/plugin-transform-runtime", {
- "corejs": false, // 是否启用 corejs https://babeljs.io/docs/en/babel-plugin-transform-runtime#corejs
- "helpers": true, // 各种辅助函数
- "regenerator": true, // 启用 generator 支持 async await
- "useESModules": false
- }]
- ]
- }
- Plugins List https://babeljs.io/docs/en/plugins
- 4.Presets
而 Presets 可能理解起来更为简单, 翻译过来是预设的意思, 他几乎就是一个 Plugins 数组和配置的集合.
@babel/preset-env 重点讲一下, 他是以前 es2015,es2016 和 es2017 的集合. 需要注意的是 @babel/preset-env 不支持所有在 stage-x 的 plugin. https://github.com/browserslist/browserslist browserslist 会和 caniuse 数据结合来判断当前语法是否需要转换. target 属性完全按照 browserslist 规则实现.
- {
- "presets": [
- [
- "env",
- {
- "targets": { // 目标环境
- "browsers": [ // 浏览器
- "last 2 versions",
- "ie>= 10"
- ],
- "node": "current" // node
- },
- "modules": true, // 是否转译 module syntax, 默认是 commonjs
- "debug": true, // 是否输出启用的 plugins 列表
- "spec": false, // 是否允许 more spec compliant, 但可能转译出的代码更慢 https://babeljs.io/docs/en/babel-preset-env#spec
- "loose": false, // 是否允许生成更简单 es5 的代码, 但可能不那么完全符合 ES6 语义
- "useBuiltIns": false, // 怎么运用 polyfill"usage" | "entry" | false 测试了一下 usage 的包最小
- "include": [], // 总是启用的 plugins
- "exclude": [], // 强制不启用的 plugins
- "forceAllTransforms": false, // 强制使用所有的 plugins, 用于只能支持 ES5 的 uglify 可以正确压缩代码
- "configPath": string //browserslist 的路径
- "ignoreBrowserslistConfig": boolean // 是否忽略 browserslist 的配置
- }
- ]
- ],
- }
useBuiltIns: 'usage' 实验性
- /// input
- var a = new Promise(); // a.js
- var b = new Map(); // b.js
- /// output
- // a.js
- import "core-js/modules/es6.promise";
- var a = new Promise();
- // b.js
- import "core-js/modules/es6.map";
- var b = new Map();
- useBuiltIns: 'entry'
- // input
- import "@babel/polyfill";
- // output
- import "core-js/modules/es7.string.pad-start";
- import "core-js/modules/es7.string.pad-end";
useBuiltIns: false 解释为不使用 polyfill. 其他 presets 列表
- stage-0
- stage-1
- stage-2
- stage-3
- flow
- react
- typescript
- minify // 比较鸡肋的压缩 preset 我也不知道为什么放在 presets 里面 我觉得他更应该是一个 plugin. 当然看名字也看的出来 babel-preset-minify 这么模块并没有在这次升级中被移到 @babel 的私有域下.
- 5.Polyfills
@babel/polyfill 和 runtime 的差别
runtime 提供的其实是一个工具类合集, 例如 _extend, 是为了减少编译时产生的冗余代码, 它不包括所有新的 es API 比如 Set Map Promise 等.
而 polyfill 则是用来提供上述的新的 ES API, 其中也包括了 Array.form Object.assign 等新增的原型方法.
使用方法 https://babeljs.io/docs/en/babel-polyfill#usage-in-node-browserify-webpack
6.babel7 做的更新
babel7 的 npm 包正式更名为 @babel/core,@babel/cli 等.
babel7 不在支持 Node.js 0.10, 0.12, 4 和 5 版本.
babel7 移除了 @babel/polyfill 内的 polyfills 支持, 现在 @babel/polyfill 几乎只是 core-js v2 的映射.
https://github.com/babel/babel/blob/master/packages/babel-polyfill/src/index.js
babylon 现在被重命名为 @babel/parser
去除包名上的年份.
将 react 和 flow 预设分离.
core-js( https://github.com/zloirock/core-js )
来源: http://www.jianshu.com/p/9aaa99762a52