关于bable的一些知识点整理babel-polyfill 的作用 和 runtime babel-cli babel-corebabel-preset-env babel-preset-preset-stage-2babel-loaderbabel使用方法:使用单体文件使用命令行构建工具的插件运行方式和插件babel总共分为3个阶段: 解析,转换和生成babel本身不具有任何转换功能, 如果没有plugin,那么经过babel的代码和输入的是相同的。babel插件分为两种语法插件:在解析的过程中,能使babel能够解析更多的语法转译插件: 在转换的过程中将代码输出。比如将箭头函数转译成正常的函数用了转译插件后,就不需要用语法插件了,因为同一语法可能同时存在语法插件和转译插件。常用的一些插件问题presetpreset是一套规范, 里面包含了几十个转译插件。这是一组插件的集合preset可以分为下面几种:按官方内容: env, react, flow, minifystage-x, 包含当年最新规范的草案,每年更新每个stage是不一样的,可以分为以下几点Stage 0 - 稻草人: 只是一个想法,经过 TC39 成员提出即可。Stage 1 - 提案: 初步尝试。Stage 2 - 初稿: 完成初步规范。Stage 3 - 候选: 完成规范和浏览器初步实现。Stage 4 - 完成: 将被添加到下一年度发布。低一级的stage会包含所有高级stage的内容,stage-1包含stage-2,stage-3的所有内容。stage-4 在下一年更新会直接放到env中,所以没有单独的stage-4可供使用。 env是一个每年更新的preset.执行顺序plugin会运行在Preset之前plugin从前到后顺序执行preset的顺序是从后向前插件和 preset 只要列出字符串格式的名字即可。但如果某个 preset 或者插件需要一些配置项(或者说参数),就需要把自己先变成数组。第一个元素依然是字符串,表示自己的名字;第二个元素是一个对象,即配置对象。“presets”: [ // 带了配置项,自己变成数组 [ // 第一个元素依然是名字 “env”, // 第二个元素是对象,列出配置项 { “module”: false } ], // 不带配置项,直接列出名字 “stage-2”]babel-clicli是命令工具,安装了之后,就能够在命令行中使用babel命令来编译文件所以babel-cli 安装为 devDependencies### babel-nodebabel-node是babel-cli的一部分,不需要独立安装他使得能够在node环境中,直接运行es2015的代码,不需要额外进行转码。babel-node = babel-polyfill + babel-register### babel-registerbabel-register 改写require命令, 为它加上一个钩子。每当使用require加载.js、.jsx、.es 和 .es6 后缀名的文件, 就会先用babel进行转码。使用时,必须先加载require(‘babel-register’)。但是babel-register只会对加载的文件转码,对当前文件是不会骑左右的。而且他属于实时转码,只适用于开发环境使用。### babel-polyfillbabel只转换js语法,不转换API,如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign)都不会转码。但是可以用babel-polyfill进行转码。使用时,在所有代码运行之前增加 require(‘babel-polyfill’)。或者更常规的操作是在 webpack.config.js 中将 babel-polyfill 作为第一个 entry。因此必须把 babel-polyfill 作为 dependencies 而不是 devDependencies但是他的缺点是:使用babel-polyfill 会导致打出来的包非常大。babel-polyfill 是一个整体,把所有的方法都加到原型链上。如果我们只使用了Array.from,但是他会把Object.defineProperty也给加上。babel-polyfill会污染全局变量,给很多类的原型链上都作了修改。所以在实际过程中,通常倾向于用babel-plugin-transform-runtime但是如果代码中有高版本的js中类型的实例方法([1,2,3].includes(1)),就只能用polyfill了。这个相当于是垫片。babel-runtime 和 babel-plugin-transform-runtimebable 会转译js语法,举个async/await例子// babel 添加一个方法,把 async 转化为 generatorfunction _asyncToGenerator(fn) { return function () {….}} // 很长很长一段// 具体使用处var _ref = _asyncToGenerator(function* (arg1, arg2) { yield (0, something)(arg1, arg2);});这里_asyncToGenerator在当前文件被定义的,然后被使用了。如果每个文件都有用async/await方法,那么每个文件都会有_asyncToGenerator 这段,会导致重复和浪费。用了babel-plugin-transform-runtime之后,转换的代码就变成// 从直接定义改为引用,这样就不会重复定义了。var _asyncToGenerator2 = require(‘babel-runtime/helpers/asyncToGenerator’);var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);// 具体使用处是一样的var _ref = _asyncToGenerator3(function* (arg1, arg2) { yield (0, something)(arg1, arg2);});这里就相当于引用了一个模块代码,就不存在重复的问题了。所以这就是用babel-plugin-transform-runtime的好处,而babel-runtime就是为这些方法提供了集合。所以在使用babel-plugin-transform-runtime的时候,需要babel-runtime做依赖。babel-runtimebabel-runtime 内部集成了core-js: 转换一些内置类(Promise, Symbol)和静态方法(Array.from等)。绝大部分的引用都是这里做的,自动引入。regenerator: 是作为core-js的拾遗补漏,主要是generator/yield和async/await两组做支持。当代码中有generators/async时会自动引入。helpersbabel-plugin-transform-runtime 不支持 实例方法 (例如 [1,2,3].includes(1))babel-loader主要使用在构建工具中。babel-loader和babel-cli一样,会读取.babelrc或者package.json中的babel段作为自己的配置,但是babel-loader必须要和webpack做交互。名称作用备注babel-cli允许命令行使用 babel 命令转译文件 babel-node允许命令行使用 babel-node 直接转译+执行 node 文件随 babel-cli 一同安装.babel-node = babel-polyfill + babel-registerbabel-register改写 require 命令,为其加载的文件进行转码,不对当前文件转码只适用于开发环境babel-polyfill为所有 API 增加兼容方法需要在所有代码之前 require,且体积比较大babel-plugin-transform-runtime & babel-runtime把帮助类方法从每次使用前定义改为统一 require,精简代码babel-runtime 需要安装为依赖,而不是开发依赖babel-loader使用 webpack 时作为一个 loader 在代码混淆之前进行代码转换 一口(很长的)气了解 babel