前言
preset与plugin的关系:
- preset中已经包含了一组用来转换ES@next的语法的插件,如果只使用少数新特性而非大多数新特性,可以不使用preset而只使用对应的转换插件
- babel默认只转换语法,而不转换新的API,如需使用新的API,还需要使用对应的转换插件或者polyfill
1. 使用转换插件:babel-plugin-transform-xxx
- 使用方法
- 缺啥补啥,在package.json添加所需的依赖(非dev)babel-plugin-transform-xxx
- 在.babelrc中的plugins项指定使用babel-plugin-transform-xxx插件
- 代码中不需要显式import/require,.babelrc中不需要指定useBuiltIns,webpack.config.js中不需要做额外处理,一切由babel插件完成转换
- 优点
- 作用域是模块,避免全局冲突
- 是按需引入,避免不必要引入造成及代码臃肿
- 缺点
- 每个模块内单独引用和定义polyfill函数,造成了重复定义,使代码产生冗余
- 附:转换插件列表(摘自babel官网)
- eval
- flow-comments
- flow-strip-types
- jscript
- object-assign
- object-set-prototype-of-to-assign
- proto-to-assign
- regenerator
- runtime
- strict-mode
- react-constant-elements
- react-inline-elements
- react-display-name
- react-jsx
- react-jsx-compat
- react-jsx-self
- react-jsx-source
- inline-environment-variables
- inline-consecutive-adds
- member-expression-literals
- merge-sibling-variables
- minify-booleans
- minify-constant-folding
- minify-dead-code-elimination
- minify-flip-comparisons
- minify-guarded-expressions
- minify-infinity
- minify-mangle-names
- minify-numeric-literals
- minify-replace
- minify-simplify
- minify-type-constructors
- node-env-inline
- property-literals
- regexp-constructors
- remove-console
- remove-debugger
- simplify-comparison-operators
- undefined-to-void
- async-generator-functions
- async-to-module-method
- class-constructor-call (deprecated)
- class-properties
- decorators
- do-expressions
- export-extensions
- function-bind
- object-rest-spread
- async-to-generator
- Modules
- es2015-modules-amd
- es2015-modules-commonjs
- es2015-modules-systemjs
- es2015-modules-umd
- exponentiation-operator
- check-es2015-constants
- es2015-arrow-functions
- es2015-block-scoped-functions
- es2015-block-scoping
- es2015-classes
- es2015-computed-properties
- es2015-destructuring
- es2015-duplicate-keys
- es2015-for-of
- es2015-function-name
- es2015-literals
- es2015-object-super
- es2015-parameters
- es2015-shorthand-properties
- es2015-spread
- es2015-sticky-regex
- es2015-template-literals
- es2015-typeof-symbol
- es2015-unicode-regex
- es5-property-mutators
- es3-member-expression-literals
- es3-property-literals
- ES3
- ES5
- ES2015
- ES2016
- ES2017
- Experimental
- Minification
- React
- Other
2. babel-runtime & babel-plugin-tranform-runtime
相比方法1,相当于抽离了公共模块,避免了重复引入,从一个叫core.js的库中引入所需polyfill(一个国外大神用ES3写的ES5/6/7 polyfill)
- 使用方法
- package中添加开发依赖babel-plugin-tranform-runtime以及生产依赖 babel-runtime
- .babelrc中指定插件:"plugins": ["transform-runtime"]
- 代码中可以直接使用ES2015+的特性,无需import/require额外东西,webpack也不需要做额外配置
- 优点
- 无全局污染
- 依赖统一按需引入,无重复引入,无多余引入
- 适合用来编写lib(第三方库)类型的代码
- 缺点
- 被polyfill的对象是临时构造并被import/require的,并不是真正挂载到全局
- 由于不是全局生效,对于实例化对象的方法,如[].include(x),依赖于Array.prototype.include仍无法使用
3. 全局babel-polyfill(不使用useBuiltIns)
- 使用方法
- 法3.1: (浏览器环境)单独在html的<head>标签中引入babel-polyfill.js(CDN或本地文件均可)
- 法3.2: 在webpack配置文件增加入口:如entry: ["babel-polyfill",'./src/app.js'],polyfill将会被打包进去,记得在package.json中添加生产babel-polyfill依赖
- 法3.3: 在webpack入口文件顶部使用import/require引入,如import 'babel-polyfill',同时package.json添加生产依赖babel-polyfill
- 优点
- 一次性解决所有兼容性问题,而且是全局的,浏览器的console也可以使用
- 缺点
- 一次性引入了ES@next的所有polyfill,打包后的js文件会偏大
- 对于现代的浏览器,有些不需要polyfill,造成流量浪费
- 污染了全局对象
- 不适合框架或库的开发
4. 全局babel-polyfill(使用babel-preset-env和useBuiltIns)
- 使用方法
- packge.json引入开发依赖babel-preset-env
- .babelrc中使用preset-env
- 指定useBuiltins选项为true
- 指定浏览器环境或node环境
- 在webpack入口文件中使用import/require引入polyfill,如import 'babel-polyfill'
- .babelrc示例
{ "presets": [ ["env", { "modules": false, "targets": { "browsers": ["ie >=6"] }, "useBuiltIns": false, "debug": true }] ] }
- 优点
- 不可与方法3混用,否则会引起冲突
- 全局方式要保证polyfill在所有其它脚本之前被执行(首行import或者设置为html的第一个<head>标签)
按需(按照指定的浏览器环境所需,并非按照代码所需)引入polyfill,一定程度上减少了不必要polyfill的引入
配置简单,无需对webpack\html做额外的配置\引入
注意:
5. polyfill.io
- 一个CDN方式提供的polyfill,可根据浏览器UserAgent自动返回合适的polyfill,详细内容自行google.
登录 | 立即注册