相关概念
Babel
官网介绍:Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。这里附上Babel的官方文档。
个人理解:Babel就是一个处理js的工具,可以让
IE等低版本的浏览器,兼容更多ECMAScript的新语法、新特性。
Babel可以做以下事情:
- 语法转换,也就是兼容新语法。(比如
const转换为var、() => {}转换为function(){}) - 通过 Polyfill 方式在目标环境中添加缺失的特性,也就是兼容新特性。(通过第三方 polyfill 模块,例如 core-js,实现))
- 源码转换 (codemods)
注意:babel本身不做任何事情,所有的功能通过插件来实现。(这个跟postcss有点类似)
语法以及特性
语法的相关举例:
const,() => {},...
特性的相关举例:
Promise,...
注意:babel主要是用来做语法兼容的,对于特性的兼容,需要使用babel里面插件(@babel/polyfill)
实际应用
搭建环境
关于搭建一个webpack的环境,大家请参考我的另一篇文章webpack —— 搭建一个webpack的学习环境,下面的过程中,我就默认大家搭建完毕。本文也会只用这个模板来学习。
目录结构以及相关文件内容
├─dist/ //webpack build之后生成的目录
├─src/
├─index.js //示例代码
├─.browserslistrc //浏览器集合的默认配置文件
├─.npmrc //npm 配置文件
├─package-lock.json
├─package.json
├─webpack.config.js //webpack默认的配置文件
- 在
src/index.js文件中const foo = 'foo'; const func = () => { console.log ('func函数'); }; - 在
package.json文件,创建脚本命令"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, - 在
webpack.config.js文件中(这是一个没有配置任何loader的webpack配置文件,因为webpack天然支持处理 .js、.json文件。)const path = require ('path'); module.exports = { entry: './src/index.js', mode: 'development', output: { path: path.resolve (__dirname, './dist'), filename: 'main.js', }, module: { rules: [], }, };
执行打包命令npm run build,看一下dist目录中的main.js文件内容。从图中我们可以看到,webpack除了对js代码进行压缩,并没有进行任何的兼容处理,依旧是用的箭头函数和const这种新语法。
那我们应该通过什么方式来兼容新语法呢?
集成babel-loader兼容新语法
集成babel-loader之后,我们就可以使用最新语法,在我们设定浏览器集合之后,babel-loader会帮我们自动兼容
- 安装依赖
npm install @babel/core babel-loader @babel/preset-env -D - 修改
webpack.config.js文件,配置babel-loader,指定预设@babel/preset-env。const path = require ('path'); module.exports = { ..., module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets:[ "@babel/preset-env" ] }, }, }, ], }, }; - 修改
.browserslistrc文件,设置浏览器集合last 2 versions > 1%
执行npm run build打包命令,再来看一下main.js文件中的内容。
从下面的图片我们可以看到:const 替换为 var、() => {} 替换为 function(){},如此我们就借助babel实现了对js代码的向下兼容。
集成@babel/polyfill兼容新特性
首先说明一点,集成@babel/polyfill并不是显式的在配置中设置,而是我们通过配置
@babel/preset-env这个预设的options,让他内部去调用@babel/polyfill.
如果我们index.js文件是这样的,代码中不仅包含新语法,还包含新特性。我们改怎样兼容新特性
//src/index.js文件
const foo = 'foo';
const promises = [new Promise (), new Promise ()];
const func = () => {
console.log ('func函数');
};
什么是垫片?
我们首先要理解一个叫`垫片`的概念。我们都知道在兼容新语法的时候,直接使用babel-loader将新语法替换就行,但显然兼容新特性这样处理就行不通。我们需要引入相对应的**库文件**。这样的引入操作,就被称之为`垫片`\
举例: 就拿Promise来说,如果不引入相应的Promise库文件,像IE浏览器还是无法解析Promise。
-
安装依赖
npm install @babel/polyfill -S -
修改
webpack.config.js文件,配置@babel/preset-env的options,const path = require ('path'); module.exports = { ..., module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets:[ ["@babel/preset-env", {useBuiltIns: 'usage'}]//preset(预设)的配置方式 //- `usage`:新功能,自动检测,不需要手动写上import "@babel/polyfill", //- `entry`:需要在入口文件手动`import @babel/polyfill`,会根据代码的使用情况,导入相应的垫片 //- `false`:是布尔值,不会排除掉没有用到的特性,代码体积会变大 ] }, }, }, ], }, };
运行npm run build命令,可以看到main.js体积为198kb。
你也可以自己手动去试一下另外俩种方式,本文中不做演示。以上就是webpack,关于loader的使用以及一些示例。