前端工程化还包括bable
Babel主要做的就是这几点:
Polyfill 实现目标环境中缺少的特性,将环境的特性差异垫平,说白了还是做兼容。比如下面这段代码
babel的使用场景主要分为两种:命令行和构建工具。
babel为命令行提供了@babel/cli工具,支持在命令行直接执行babel命令。
安装好在项目中执行babel命令就可以进行转换了。
在构建工具中使用是我们使用babel更常用的方式。
以webpack为例,babel提供了一个loader:babel-loader,使用这个loader我们就能很轻松实现代码转换。
bable的运行方式:
Babel的运行过程分为三个阶段:解析 --- 转换 --- 生成
babel7支持多种方式来进行配置:
babel.config.json(项目范围).babelrc.json(相对文件)package.json中添加babel字段除了json文件之外,babel还支持其他格式的配置文件,比如 .js,.cjs(Commonjs)和.mjs(ESModule),它们相对于json格式更加灵活,可以在配置中进行编程处理,但是会使配置无法静态分析,失去可缓存性。
babel虽然有多种方式来写配置文件,但是配置的内容都是类似的,主要包含plugins和presets两部分,不过这里需要注意几点:
配置格式:plugins和presets配置项均为数组,如果每项不需要配置的话,直接放入数组(值为项的字符串名称);如果要配置的话,则需要把格式改成数组,该数组的第一个元素是该项的字符串名字,第二个元素是该项的配置对象。这里填写的plugins和presets,babel会自动检查是否已被安装在node_modules下面,当然,也可以使用相对路径来使用本地文件。
执行顺序:
plugins会从前到后执行,presets会从后向前执行,且plugins会比presets先执行
presets逆序执行的目的是为了保证向后兼容,我们在配置的时候按照规范的时间顺序列出即可,如['es2015', 'stage-1'],这样就会先使用stage-1,否则就会出现错误。
短名称:在配置plugin和preset名字的时候,可以省略名字中的babel-plugin-和preset-字样,仅使用插件的名字就可以了。
babel的转换完全依靠插件,babel拥有的能力完全取决于给它配置了哪些插件。
babel的插件分为两种:
语法插件:赋予babel解析特定语法的能力,可以理解一个为babel服务的翻译官,仅做翻译解析工作,工作在AST转换阶段。
转译插件:转译插件即把特定的语法转换成指定标准的语法。
比如将箭头函数 (x) => x 转换成 function (x) {return x},只需要配置箭头函数转译插件即可。
插件的使用大概分为两步:
plugins属性中,可根据插件文档做相应配置。每个插件的功能是单一的,所以一般转换需求要使用的插件数量比较多,这时候可以考虑presets
和webpack一样,bable可以使用自定义插件实现功能
在实际的开发中,我们如果用ES6来进行开发的话,那需要转换的语法是非常多的,难道要一个一个去配置吗?还要不要配陪妹子了?
这个时候,就该presets登场了。presets可以理解为一组插件的集合,就像你去德克士直接点一个全家桶,而不必一个一个给服务员说要鸡腿、鸡翅、薯条...(如果想和服务员小姐姐多待一会,也不是不可以)
配置文件:通过配置文件的targets属性指定目标环境
browserslistrc:如果是浏览器或者Electron,官方推荐使用.browserslistrc
文件来指定目标环境(可以和autoprefixer、stylelint等其他工具共享配置)。
不过如果在配置文件中设置了 targets 或 ignoreBrowserslistConfig,.browserslistrc中配置的内容将不会生效。
presets中的其他配置:
modules: 用于指定转换后的模块规范,可设置为"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false,默认为"auto"。
useBuiltIns:此选项配置如何@babel/preset-env处理polyfill,在后面介绍polyfill我们会详细介绍。
corejs:用于指定corejs的版本,仅当使用了useBuiltIns: usage或者
useBuiltIns: entry此配置才有效,使用时一定要配置正确的版本,否则会报错。
当前默认的版本是2.0,不过建议使用3.0版本,因为2.0已经不会再添加新的特性了,如果使用了一些较新的语法,将会无法转换。
@babel/preset-env
这个是我们最常用的,也是官方现在推荐的preset,它是一个智能预设,我们无需再关心特定环境下所需的转换插件(只需要指定目标环境),就可以使用最新的语法。除了能够减少使用难度,还能够使转换出来的代码体积更小。
preset-env会根据配置的目标环境中缺少的功能,选择对应的插件进行必要的转换和polyfill,而目标环境支持的特性就不会转换,而不是无脑的一把梭哈。
前面我们的配置其实是不完美的,转换出来的代码直接在浏览器运行是可能会出问题的。这是因为babel默认只转换了语法,而对于一些新的API是并没有处理的,如Generator、Set、Maps、Proxy、Promise 等全局对象及其方法都不会转码,如果我们在代码中使用到了就会报错。
此时,我们就需要做Polyfill,也就是所谓的'垫片',作用就是把浏览器的差异垫平,人话就是通过模拟为这些浏览器补全缺失的全局对象及API。
@babel/plugin-transform-runtime 是一个可重复使用Babel注入的帮助程序的插件,避免重复注入,以节省代码大小。通常还要搭配@babel/runtime一起使用。
安装
配置