babel默认是只会去转义js语法的,不会去转换新的API,比如babel是不会去编译Promise、Generator、Symbol这种全局API对象,

@babel/core

@babel/core 这个包里主要都是一些去对代码进行转换的核心方法,需要配合babel.config.js配置文件使用

@babel/cli

babel的命令行工具

@babel/plugin

babel是基于插件化的
配置

  1. /* babel.config.js */
  2. module.exports = {
  3. presets: [
  4. ],
  5. plugins: [
  6. "@babel/plugin-transform-arrow-functions"
  7. ]
  8. }

编译结果

  1. /* study.js */
  2. const study = () => {}
  3. /* study-compiled.js */
  4. const study = function () {};

这种一个个配置插件的方法非常不方便,所以babel提供了@babel/preset-env

babel/preset-env

presets是预设的意思,可以预先设定好一些东西,不用去一个个引入插件

  1. /* babel.config.js */
  2. module.exports = {
  3. presets: [
  4. "@babel/preset-env"
  5. ],
  6. plugins: [
  7. ]
  8. }

Browserslist集成

babel提供一个targets配置项指定运行环境,可以配置对应目标浏览器环境,那么babel就会编译出对应目标浏览器环境可以运行的代码

  1. /* babel.config.js */
  2. module.exports = {
  3. presets: [
  4. [
  5. "@babel/preset-env", {
  6. 'targets': {
  7. 'browsers': ['ie >= 8', 'iOS 7'] // 支持ie8,直接使用iOS浏览器版本7
  8. }
  9. }
  10. ]
  11. ],
  12. }

@babel/polyfill

是由core-js2regenerator-runtime组成的一个集成包,可以编译高级API

  1. "modules": false // 不使用commonjs
  2. "useBuiltIns": // 按需引入polyfill

useBuiltIns

选项:”usage”| “entry”| false,默认为false。
entry:是在入口处将根据我们配置的浏览器兼容,将目标浏览器环境所有不支持的API都引入。
usage:当配置成usage的时候,babel会扫描你的每个文件,然后检查你都用到了哪些新的API,跟进我们配置的浏览器兼容,只引入相应API的polyfill

  1. /* babel.config.js */
  2. module.exports = {
  3. presets: [
  4. [
  5. "@babel/preset-env", {
  6. "modules": false,
  7. "useBuiltIns": "entry",
  8. "corejs": "3",
  9. 'targets': {
  10. 'browsers': ['not ie >= 8', 'iOS 7'] // 支持ie8,直接使用iOS浏览器版本7
  11. }
  12. }
  13. ]
  14. ],
  15. plugins: [
  16. ]
  17. }

@babel/runtime

有的时候一些语法的转换会比较复杂,babel会引入一些helper函数,比如说对es6的class进行转换:

  1. /* study.js */
  2. class Test {}
  3. /* study-compiled.js */
  4. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5. var Test = function Test() {
  6. _classCallCheck(this, Test);
  7. };

如果编译后存在大量的helper函数,将会使得输出文件变的庞大,@babel/plugin-transform-runtime可以把这些helper函数都抽离到一个公共的包里,用到的地方只需要引入对应的函数,来解决这一问题

  1. /* babel.config.js */
  2. module.exports = {
  3. presets: [
  4. [
  5. "@babel/preset-env", {
  6. "modules": false,
  7. "useBuiltIns": "entry",
  8. "corejs": "3",
  9. 'targets': {
  10. 'browsers': ['not ie >= 8', 'iOS 7'] // 支持ie8,直接使用iOS浏览器版本7
  11. }
  12. }
  13. ]
  14. ],
  15. plugins: [
  16. "@babel/plugin-transform-runtime"
  17. ]
  18. }

corejs 清除 polyfill副作用

例如:为了编译Promise提供的polyfill会污染全局变量
@babel/plugin-transform-runtime插件提供了一个配置项corejs,他可以给这些polyfill提供一个沙箱环境,这样就不会污染到全局变量

  1. /* babel.config.js */
  2. module.exports = {
  3. presets: [
  4. [
  5. "@babel/preset-env",
  6. {
  7. "modules": false,
  8. "useBuiltIns": "usage",
  9. "corejs": "3",
  10. 'targets': {
  11. 'browsers': ["ie >= 8", "iOS 7"] // 支持ie8,直接使用iOS浏览器版本7
  12. }
  13. }
  14. ]
  15. ],
  16. plugins: [
  17. [
  18. "@babel/plugin-transform-runtime",
  19. {
  20. "corejs": 2, // 3
  21. }
  22. ]
  23. ]
  24. }

@babel/plugin-syntax-dynamic-import

有时候项目中懒加载使用import()语法不被识别,这种情况下的 import 属于异步引用组件,需要特殊的babel-loader处理
我所在的公司由于项目较老,所用的就是这个方法来解析识别import()动态导入语法—-并非转换,而是解析识别