为了支持业务中少许的es6+的高级特性,最近在研究了一下babel的垫片,现将此整理为文字,以下。node
一、先来理解下 babel 究竟是作什么的?react
简单来说, babel解决 语法层面的问题。用于将ES6+的高级语法转为ES5。
二、babel polyfill 又是作什么的?webpack
若是要解决 API层面的问题,须要使用垫片。好比常见的有babel-polyfill
、babel-runtime
和babel-plugin-transform-runtime
。
理清了他们之间的关系,那么再正式来说讲有关polyfill
的二三事。git
babel polyfill 有三种es6
* babel-polyfill * babel-runtime * babel-plugin-transform-runtime
babel-polyfill
经过向全局对象和内置对象的prototype上添加方法来实现的。因此这会形成全局空间污染。github
babel-polyfill
使用的两种方式一、webpack.config.js 中:
配置webpack.config.js
里的entry
设置为entry: ['babel-polyfill',path.join(__dirname, 'index.js')]
web
二、业务 js 中:
在webpack.config.js
配置的主入口index.js
文件的最顶层键入promise
import 'babel-polyfill'
二者打印出来的大小都是同样的,打包后大小是280KB,若是没有使用babel-polyfill
,大小是3.43kb。两则相差大概81.6倍。缘由是webpack
把babel-polyfill
总体所有都打包进去了。而babel-polyfill
确定也实现了全部ES6新API
的垫片,文件必定不会小。浏览器
那么有没有一种办法,根据实际代码中用到的ES6
新增API ,来使用对应的垫片,而不是所有加载进去呢?
是的,有的。那就是 babel-runtime
& babel-plugin-transform-runtime
,他们能够实现按需加载。babel
简单说 babel-runtime 更像是一种按需加载的实现,好比你哪里须要使用 Promise,只要在这个文件头部
import Promise from 'babel-runtime/core-js/promise'
就好了。
不过若是你许多文件都要使用 Promise,难道每一个文件都要 import
一下吗?固然不是,Babel 官方已考虑这种状况,只须要使用 babel-plugin-transform-runtime
就能够解决手动 import
的苦恼了。
babel-plugin-transform-runtime
装了就不须要装 babel-runtime
了,由于前者依赖后者。
总的来讲,babel-plugin-transform-runtime
就是能够在咱们使用新 API 时 自动 import babel-runtime 里面的 polyfill,具体插件作了如下三件事情:
babel-plugin-transform-runtime
优势:
在 .babelrc 中配置:
plugins:\["tranform-runtime"\]
打包后大小为 17.4kb,比以前的280kb要小不少。
若是不想本身设置一堆插件的话,官方有env
,react
,flow
三个 Presets。即预安装了 plugins 的配置。
presets 属性告诉 Babel 要转换的源码使用了哪些新的语法特性, presets 是一组 Plugins 的集合。如:
babel-preset-es2015: 能够将es6的代码编译成es5
babel-preset-es2016: 能够将es7的代码编译为es6
babel-preset-es2017: 能够将es8的代码编译为es7
babel-preset-latest: 支持现有全部ECMAScript版本的新特性
当咱们须要转换es6语法时,能够在 .babelrc 的 plugins 中按需引入一下插件,好比:check-es2015-constants
、es2015-arrow-functions
、es2015-block-scoped-functions
等等几十个不一样做用的 plugin。.babelrc
中配置项多是以下方式:
{ "plugins": \[ "check-es2015-constants", "es2015-arrow-functions", "es2015-block-scoped-functions", // ... \] }
但 Babel 团队为了方便,将同属 ES2015 的几十个 Transform Plugins 集合到 babel-preset-es2015
一个 Preset 中,这样咱们只须要在 .babelrc
的 presets 加入 ES2015 一个配置就能够完成所有 ES2015 语法的支持了。.babelrc
中配置以下:
{ "presets": \[ "es2015" \] }
这个比较好理解,就是为了支持 TC39 对于草案阶段的 ES 最新特性而开发的 presets。
官方和民间提供了不少的转换插件,用于指定对某一项 ES 高级特性进行转换。
官方见:https://babeljs.io/docs/en/pl...
这种插件可让Babel
来解析特殊类型的语法。
{ "parserOpts": { "plugins": \["jsx", "flow"\] } }
见文档:https://github.com/jamiebuild...
开发采用了 AST 抽象语法树,相似于 Eslint 插件开发。
export default function () { return { visitor: { Identifier(path) { const name = path.node.name; // reverse the name: JavaScript -> tpircSavaJ path.node.name = name.split("").reverse().join(""); } } }; }
babel 用途是语法转换,因此webpack 中须要用到 babel-loader
。而 babel-core
是 Babel 编译器的核心,所以也就意味着若是咱们须要使用 babel-loader
进行 es6 转码的话,咱们首先须要安装 babel-core
。
使用场景建议:
以上,若有写的不正确或者有疑问的地方请留言。未完待续,本文会持续更新babel相关知识。