一、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
浏览器中打开,打开控制台,发现报错了。
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的配置已经告一段落,后面章节将逐步实现贪吃蛇的小游戏。