webpack中编译ES6/7主要用到以下三个
- Babel
- Babel-presets
- Babel-plugin
Babel
Babel官网
参考:阮一峰的Babel教程
1) Babel安装
如果想安装最新可以指定@安装beta版,如果不追求最新使用第二条命令。安装完会多了以下几个文件
举粟:手动创建webpack.config.js文件,内容如下
module使用rules对js文件使用babel-loaer处理,exclude排除规范之外的node_modules,因为它是第三方引入的文件,我们不需要它走我们的loader,这样就配置好了babel-loader。
在我们配置完了babel-loader之后呢,我们这个时候还不知道babel是根据什么样的规范来打包的,这个时候就需要用到Babel-presets。
Babel-presets
Babel-presets其它就是babel规范的一个总结,比如说es2015,es2016,es2017,我们开发经常用到的是env,因为env包括2015 到 2017以及最近的发布的。还有一些自定义,如babel-preset-react跟react相关的,还有babel-preset-stage 0-3表示规范组正式发布几个阶段的所有的presets。在设置之前也需要安装presets。
1) Babel-presets 安装
如果前面babel安装的是beta版,执行第一句,否则执行第二句进行安装。
2) Babel-presets 配置
3) Babel-presets 中的参数 targets
targets其实是告诉babel,当你编译的时候,我会根据指定的targets,来选择哪些语法需要编译哪些不需要编译,targets可以指定:
-
targets.bwowsers:指定浏览器
-
targets.bwowsers:"last 2 versions",指定主浏览器最后的两个版本。
-
targets.bwowsers:">1%",表示大于全球1%浏览器都得支持。
以上数据主要来自browserlist,而browserslist的数据主要来自Can I use。
举粟:
应用:新建一个app.js,内容如下:
通过webpack命令打包后生成内容如下:
可以发现es6的写法已经被转成传统的es5了,然后我们改变一下targets,指定chrome,内容如下:
重新webpack打包后内容如下:
这时我们发现箭头函数就没有被编译过来,因为chrome支持这种语法。
Babel Polyfill, Babel Runtime Transform
我们重新给app.js 加个includes,target重新设回最早的,内容如下
重新打包后内容如下:
我们发现arr.includes(8),并没有被babel处理 ,其实低版本的浏览器里面inclues是不存在的,因为浏览器还没有实现它,这时候我们就可以借助Babel Runtime和Babel Runtime Transform来实现它,之前语法的变换,我们是用babel-presets来指定规范的版本,它只是针对于语法。而针对函数和方法我们就需要借助这两个插件,那么这两个插件有什么函数和方法呢
函数和方法
- Generator
- Set
- Map
- Array.from
- Array.prototype.inclues
以上这一系列的方法都没有被babel处理,需要用这两个插件来处理,但这两个插件会有些不同,请看:
1) Babel Polyfill
polyfill: 指的是“用于实现浏览器不支持原生功能的代码”,比如,现代浏览器应该支持fetch函数,对于不支持的浏览器,网页中引入对应fetch的polyfill后,这个polyfill就给全局的window对象上增加一个fetch函数,让这个网页中的JavaScript可以直接使用fetch函数了,就好像浏览器本来就支持fetch一样,为当前环境提供一个垫片。
全局垫片:一旦你引入它,你就可以在全局范围内,对它里面实现的api进行调用,比如说promise,array中一些新的方法,也可以理解是对全局变量时行污染。 为应用准备:其实就是一个对比,有开发应用,那其实就有开发框架,应用是你实际开发中使用的,比如说你写个人开发网站,而框架是你写一个被别人使用的代码,比如vue,如果你引用vue,在引用babel polyfill是不行的,所以这相当是为应用准备的而不是为框架准备的。那怎么使用它呢?
npm install babel-polyfill --save
复制代码
安装完后最前端引入就可以了
import "babel-polyfill"
复制代码
2) Babel Runtime Transform
-
局部垫片
-
为开发框架准备
不会污染全局,比如你在开发一个框架被别人引用的时候,里面需要用到es6新的函数和方法,那么这个时候你又不想污染全局的变量,那么这时候就可以使用些插件。那怎么安装它呢?
npm install babel-plugin-transform-runtime -save-dev
npm install babel-runtime -save
复制代码
怎么使用它呢?可以直接在根目录下新建一个.babelrc文件,在这里面去配置跟babel相关的targets,presets还有plugin。
举粟:
app.js内容如下:
重新webpack打包,生成内容如下
如果我们不用babel-polyfill, Babel Runtime Transform使用又会是怎么样呢?
3) 使用 Babel Runtime Transform
根目录手动创建.babelrc,内容如下:
修改webpack.config.js,内容如下:
重新运行webpack打包,内容如下:
跟之前区别Set方法变成了_Set,_Set是webpack Require一个模块,从中我们就可以babel-polyfill和babel-runtime的区别。
4) 实际开发中
实际开发中我们只要配置.babelrc中的presets就可以了,而不使用runtime,如果是开发饿了么element这个UI组件库的时候,里面用到一些es6的新方法,就可以使用runtime,因为我们要开发框架给第三方的时候,不希望它去污染全局的变量。
如果要使用ES6中的语法,直接在app.js引用“babel-polyfill”
愿你成为终身学习者