一、babel
babel
可以将高版本的js
代码转换为低版本的js
代码,从而达到兼容旧浏览器(比如IE)的目的。一些ES6
的类和方法,比如Promise
,babe
会通过低版本js
可以运行的方法重新实现,然后在代码中使用。
- 安装babel
npm i -D @babel/core @/babel/preset-env babel-loader core-js
其中,@babel/core
是babel
的核心工具库。
@babel/preset-env
是babel
的预置环境,这个包里预置了很多环境,比如谷歌某版本、IE某版本、火狐某版本等,设置了什么版本,babel
编译的时候就相应的编译成什么样的js
。
babel-loader
是babel
在webpack
中的加载器,用来将babel
和webpack
关联起来。
core-js
是模拟js
运行环境的代码,提供了es5、es6
的polyfills
,包括promises、symbols、collections、iterators、typed arrays、ECMAScript 7+ proposals、setImmediate
等等。core-js
里面东西很多,在实际配置的时候,会按需选择一部分使用。
2.如何使用
// webpack.config.js
// 首先在rules里加上babel对ts文件的处理
{
// test指定的是规则生效的文件
test: /\.ts$/,
// 要使用的loader
use: [
// 配置babel
{
loader: 'babel-loader',
options: {
// 设置预置环境
presets: [
[
// 指定环境的插件
"@babel/preset-env",
// 配置信息
{
// 要兼容的浏览器版本
targets: {
"chrome": "58",
"ie": "11"
},
// 指定corejs的版本
"corejs": "3",
// 使用corejs的方式 usage表示按需加载
"useBuiltIns": "usage"
}
]
]
}
},
'ts-loader'
],
// 要排除的文件
exclude: /node_modules/
// 这块配置的意思是,使用ts-loader处理所有以.ts结尾的文件,但排除掉node_modules文件夹
}
我们修改了对ts
文件的处理规则,之前只用到ts-loader
,这次加上了babel-loader
,当use
属性中有多个loader
的时候,可以通过数组的方式传入,loader
如果没有特殊配置,写入名字即可,比如上面的ts-loader
。如果有更详细的配置,可以传入一个对象,比如上面的babel-loader
。
需要注意的是:
use
中配置的loader
是按照从后往前的顺序执行的,在上面配置中,首先通过ts-loader
将ts
转为js
(js
版本由tsconfig.json
指定),然后通过babel
将js
转换为可兼容的js
代码。
- 测试
// index.ts
const fn = (a:number, b:number) => a + b
fn(123, 456)
npm run build
编译后,打开bundle.js
可以看到,
const
被转成了var
,箭头函数被转成了普通函数,通过babel
,将ts
转换的es6
版本的js
转成了ie
可以兼容的es5的js代码。
在引入es6的Promise试试
// index.ts
const fn = (a:number, b:number) => a + b
fn(123, 456)
console.log(Promise)
编译后的文件大了很多,里面自己实现了promise
- bug
到这里,我们得到的bundle.js
按理说应该可以支持到IE
浏览器了,但实际却发现报错了
执行npm run start
启动项目,在IE
浏览器中打开,打开控制台,发现报错了。
定位到错误的位置看看
我们发现webpack
打包的js
,包裹在一个立即执行函数中,而这个函数里面,是一个箭头函数。IE
不支持箭头函数,所以在最开始就报错了。
这里有点疑问,我们不是用babel
把js
给转成旧版本js
了吗,上面的例子中,箭头函数也被转成普通函数了,这里为什么会有一个箭头函数呢?
实际上,这里的箭头函数,是
webpack
的代码,而babel
处理的是我们自己写的代码,所以它处理不到这块。可以看出webpack
并不喜欢IE
,默认不想支持它。所以应该怎么解决呢?
在webpack
配置的output
对象中,增加一个配置,告诉webpack
不要使用箭头函数以及const(不设置这个,在IE10浏览器中会因为const而报错)。
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
// 告诉webpack不使用箭头函数和const
environment: {
arrowFunction: false,
const: false
}
}
在启动下用IE
打开,发现没有报错了。
以上,关于babel
的配置就告一段落了。
二、postcss
- 安装
npm i -D less less-loader css-loader style-loader
less-loader
是less
的加载器。
css-loader
是用来进行css
的模块化处理的。如果在JS
中导入了css
,那么就需要使用css-loader
来识别这个模块,通过特定的语法规则进行转换内容最后导出,css-loader
会处理import / require()
以及 @import / url
引入的内容。
style-loader
是处理css
的最终引用的,它在前面的包整理好引用关系后,在编译好的html
中,通过js
创建style
标签,里面包含了css
样式。
除了安装这些,还要安装postcss,postcss之于css,就像babel之于js,它可以将css转换为更具兼容性的写法。
npm i -D postcss postcss-loader postcss-preset-env
整体捋一下这些包的使用顺序:
- 用
less
文件写样式 - 编译的时候
webpack
首先使用less-loader
加载less
文件,并将less
代码转换成css
代码 - 使用
postcss-loader
,根据配置将css
代码转成更具兼容性的css
代码 -
css-loader
处理引用关系,知道应该在什么地方引入哪些css
代码 -
style-loader
通过js
创建style
标签,根据前面的引用关系,在合适的地方加入css
代码
- 如何使用
// webpack.config.js 在module --> rules中指定less文件的加载规则
// 设置less文件的处理
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
// 引入postcss
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
browsers: 'last 2 versions'
}
]
]
}
}
},
"less-loader"
]
}
配置方法和babel类似,plugins中指定了postcss的预置环境,以及兼容性要求为支持每种浏览器的最新的两个版本。
- 测试
在src
中创建styles/index.less
文件
body {
background: red;
display: flex;
}
在index.ts
中引用这个css
import './styles/index.less'
编译后打开bundle.js
,搜索flex
可以看到display:flex;加上了前缀,说明postcss的配置生效了。
经过两节时间,webpack的配置已经告一段落,后面章节将逐步实现贪吃蛇的小游戏。