babel-loader运行过程

1,138 阅读3分钟

babel-loader

babel-loader 是webpack和babel之前的桥梁,配置对应的plugins去结合babel将ES6+语法转译成ES5语法

babel工作原理

babel是一个转译器,babel转译过程,parsing、transforming、generating 以ES6转译ES5代码为例,babel转译的具体过程如下:
1、parsing,ES6代码经过babylon转译成AST语法树
2、transforming,通过plugin将转译的AST语法树在进行遍历转译
(如果这个阶段不使用任何插件,那么babel会原样输出代码。) 3、babel-generator将编译好的AST树生成ES5代码

那其实babel的工作都是依赖于plugin去处理的
vuecli搭建的项目中,会有一个babel.config.js文件,官方建议在这里配置,另外你可以运行vue ui查看更多的配置项

//babek.config.js
module.exports = {
  presets: ['@vue/app'],
  plugins: []
}
//.babelrc
{
  "presets":[
      "@babel/preset-env"
  ],
  "plugins":[
  
  ]
}

@vue/app是@vue/babel-preset-app的缩写,对应的依赖在package-lock中看到

那这里配置的@vue/babel-preset-ap其实是和@babel/preset-env作用是一样的包括很多的plugins去处理ES6+的语法如果不包含的在plugins里扩充。

注意很重要的一点就是,babel只是转译新标准引入的语法,比如ES6的箭头函数转译成ES5的函数,Class转成函数;而新标准引入的新的原生对象,部分原生对象新增的原型方法,新增的API等(如Proxy、Set等),这些babel是不会转译的。需要自己去引入polyfill来解决

例如

module.exports = {
  presets: [
    ['@vue/app', {
      polyfills: [
        'es6.promise',
        'es6.symbol'
      ]
    }]
  ]
}

babel-polyfill

那经常采用的是babel-polyfill是core-js和regenerator-runtime两者的集合,从babel7.4开始推荐引入 core-js是核心解决polyfill的集合,但有个缺点是不满足ES6的generator函数,regenerator-runtime可以解决,所以采用core-js和regenerator-runtime的结合。
需要注意的是babel-polyfill文件比较大,假设只用一部分功能的时候,配置需要按需引入

那babel-polyfill存在的问题:

1) 污染全局环境:要做到兼容只能挂在到全局上,所以要看使用场景,如果做一个独立的系统则无所谓;如果是第三方的库,这个是引入使用的时候你重新定义了比如Promise这样的东西,就会导致覆盖污染全局等问题

解决

需要应用babel-runtime:首先安装@babel/plugin-transform-runtime和@babel/runtime这两个插件,通过plugin-transform-runtime来配置就不会污染全局环境

// .babelrc babel-polyfill按需引入
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ],
  "plugins": [
    //在这里面做配置
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": 3,
        "helpers": true,
        "regenerator": true,
        "useESModules": false
      }
    ]
  ]
}

transform-runtime如何处理的

1、将代码中用到的ES6+的新对象和静态方法由core-js导出对应的对象和方法替换
2、当使用generators或async函数时,用babel-runtime/regenerator导出的函数取代(类似polyfill分成regenerator和core-js两个部分)
3、把Babel生成的辅助函数改为用babel-runtime/helpers导出的函数来替代(babel默认会在每个文件顶部放置所需要的辅助函数,如果文件多的话,这些辅助函数就在每个文件中都重复了,通过引用babel-runtime/helpers就可以统一起来,减少代码体积)

后续继续补充

参考来源

www.cnblogs.com/75115926/p/…