打算系统的整理一下,webpack
的一些知识点
,也是时候结合项目中使用的一些 案例
,做一些总结了。
webpack系列
打算从 webpack核心功能
-> 常用扩展
-> CSS 工程化
-> JS 兼容性
-> 性能优化
这几个方面开始记录。
以及结合一些案例
,方便大家阅读和实践,以备 开箱即用
。
仓库地址:PantherVkin/webpack-note (github.com)
babel的安装和使用
官网:babeljs.io/
民间中文网:www.babeljs.cn/
babel简介
前端开发面临着这样的困境,不同版本的浏览器能识别的ES标准并不相同,就导致了开发者面对不同版本的浏览器要使用不同的语言。
babel的出现,就是用于解决这样的问题,它是一个编译器,可以把不同标准书写的语言,编译为统一的、能被各种浏览器识别的语言
。
由于语言的转换工作灵活多样,babel的做法和postcss
、webpack
差不多,它本身仅提供一些分析功能,真正的转换需要依托于插件完成。
babel的安装
babel可以和构建工具联合使用,也可以独立使用。
如果要独立的使用babel,需要安装下面两个库:
@babel/core
:babel核心库,提供了编译所需的所有api@babel/cli
:提供一个命令行工具,调用核心库的api完成编译
$ npm i -D @babel/core @babel/cli
babel的使用
@babel/cli
的使用极其简单。
它提供了一个命令babel
。
# 按文件编译
$ babel 要编译的文件 -o 编辑结果文件
# 按目录编译
$ babel 要编译的整个目录 -d 编译结果放置的目录
babel的配置
可以看到,babel本身没有做任何事情,真正的编译要依托于babel插件和babel预设来完成。
babel预设和postcss预设含义一样,是多个插件的集合体,用于解决一系列常见的兼容问题。
如何告诉babel要使用哪些插件或预设呢?需要通过一个配置文件.babelrc
{
"presets": [],
"plugins": []
}
babel预设
babel有多种预设,最常见的预设是@babel/preset-env
@babel/preset-env
可以让你使用最新的JS语法,而无需针对每种语法转换设置具体的插件。
$ npm i -D @babel/preset-env
.babelrc
{
"presets": [
"@babel/preset-env"
]
}
.browserslistrc
@babel/preset-env
需要根据兼容的浏览器范围来确定如何编译,和postcss一样,可以使用文件.browserslistrc
来描述浏览器的兼容范围。
last 3 version
> 1%
not ie <= 8
自身的配置
和postcss-preset-env
一样,@babel/preset-env
自身也有一些配置。
具体的配置见:www.babeljs.cn/docs/babel-…
配置方式是:
{
"presets": [
["@babel/preset-env", {
"配置项1": "配置值",
"配置项2": "配置值",
"配置项3": "配置值"
}]
]
}
其中一个比较常见的配置项是usebuiltins
,该配置的默认值是false。
它有什么用呢?由于该预设仅转换新的语法,并不对新的API进行任何处理。
例如:
new Promise(resolve => {
resolve()
})
转换的结果为
new Promise(function (resolve) {
resolve();
});
如果遇到没有Promise构造函数的旧版本浏览器,该代码就会报错。
而配置usebuiltins
可以在编译结果中注入这些新的API,它的值默认为false
,表示不注入任何新的API,可以将其设置为usage
,表示根据API的使用情况,按需导入API
。
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}]
]
}
注意
@babel/polyfill
已过时,目前被core-js
和generator-runtime
所取代。
babel插件
除了预设可以转换代码之外,插件也可以转换代码,它们的顺序是:
-
插件在 Presets 前运行
-
插件顺序
从前往后
排列 -
Preset 顺序是颠倒的(
从后往前
)。
通常情况下,@babel/preset-env
只转换那些已经形成正式标准的语法,对于某些处于早期阶段、还没有确定的语法不做转换。
如果要转换这些语法,就要单独使用插件。
@babel/plugin-proposal-class-properties
该插件可以让你在类中书写初始化字段。
class A {
a = 1;
constructor(){
this.b = 3;
}
}
@babel/plugin-proposal-function-bind
该插件可以让你轻松的为某个方法绑定this。
function Print() {
console.log(this.loginId);
}
const obj = {
loginId: "abc"
};
obj::Print(); //相当于:Print.call(obj);
遗憾的是,目前vscode无法识别该语法,会在代码中报错,虽然并不会有什么实际性的危害,但是影响观感
@babel/plugin-proposal-optional-chaining
const obj = {
foo: {
bar: {
baz: 42,
},
},
};
const baz = obj?.foo?.bar?.baz; // 42
const safe = obj?.qux?.baz; // undefined
babel-plugin-transform-remove-console
该插件会移除源码中的控制台输出语句。
console.log("foo");
console.error("bar");
编译后
@babel/plugin-transform-runtime
用于提供一些公共的API,这些API会帮助代码转换。
在webpack中使用babel
- 安装
$ npm i -D babel-loader
webpack.config.js
module.exports = {
mode: "development",
devtool: "source-map",
module: {
rules: [
{ test: /\.js$/, use: "babel-loader" }
]
}
}
- 完整案例
webpack-note/examples/4.1-webpack中使用babel at master · PantherVkin/webpack-note (github.com)