前端最常用的打包工具webpack(三)-兼容性处理
这是重新学习webpack的第三篇文章,之前我也写过一篇关于webpack的文章。问题是过去快半年了,我已经将webpack忘得差不多,回头一看那篇文章完全是一头雾水,也没有办法,那个时候我才刚刚开始写前端方面的博客,对于知识梳理、文字表达都有一些欠缺,啪啪啪一下扔出来几千字,全是重点,没有任何过渡性的语言,看个一会就没什么兴趣。
综上所述,本次决定给webpack写一个比较详细的系列文章,目的是如果我半年后又忘记了webpack的具体内容,再来翻阅文章,不会像这次一样一头雾水。
前景提要
在之前的那篇文章中,我学到了如何将css、js、scss、html通过webpack进行打包,而本篇文章,就着重讲解如何处理js、css的兼容性,以及如何将项目运行在webpack内置的服务器上。
1. 兼容性
1.1 css兼容性
css因为每个浏览器实现的方式不同,而且不同的浏览器还有各自的私有属性:
常用的前缀有:
- -moz代表firefox浏览器私有属性。
- -ms代表IE浏览器私有属性。
- -webkit代表chrome、safari私有属性。
- -o代表opera私有属性。
例如transform:rotate(-3deg)
这个css属性,兼容性写法就应该是:
-webkit-transform:rotate(-3deg); /* 为Chrome/Safari */
-moz-transform:rotate(-3deg); /* 为Firefox */
-ms-transform:rotate(-3deg); /* 为IE */
-o-transform:rotate(-3deg); /* 为Opera */
transform:rotate(-3deg);
试想一下,如果每一条CSS3的语句都要写成这样,那几乎不用玩了,不光你要一条条的查找该CSS属性是否存在兼容性问题,你还必须写上这些私有属性语句。
虽然现在有些网页能够帮助你将CSS语句进行转换,但是一个页面中可能有非常多的.css
文件,你要一个一个的去转换肯定是不现实的。
这个时候webpack通过插件,可以自动帮你添加这些兼容性语句,你只需要专心写css相关的样式就可以了。
1.2 js兼容性
因为有些浏览器比如IE浏览器不识别ES5之后的语法,而ES6里面有太多的便利的写法,不仅引入了箭头函数解决了历史遗留的this指针问题,还引入了class、promise这些十分方便的新特性,你总不可能不用ES6的语法再回去写ES5的语法吧?
而webpack有插件可以直接将ES6后的语法转换为ES5的语法,你只需要进行配置一下,你就可以放心的书写ES6的语法,而不用担心兼容性问题,所有的兼容性问题插件会帮助你解决。
相信看到这里,你一定对本篇文章所要讲述的内容有一定的了解,那么我们就开始吧!
2. CSS
2.1 提取CSS到单独文件
之前我们一直将CSS放在.js
中,但是这样无疑会增大.js
文件的体积,而且有些浏览器对js文件的解析速度还没有css文件的解析速度快,所以我们需要把样式文件单独提取出来。
需要的插件mini-css-extract-plugin。
npm install mini-css-extract-plugin --save-dev
配置也很简单:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 在css loader中用MiniCssExtractPlugin.loader替代style-loader
{
// 用正则表达式匹配文件类型,下面就是匹配以.css结尾的文件,并且将它们使用下面的loader解析。
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
// 将css文件编程CommonJs模块加载到js中,里面内容是样式字符串
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
// 浏览器兼容性处理
plugins: ["postcss-preset-env"],
},
},
},
],
},
// 在plugins中引入插件
new MiniCssExtractPlugin(),
这样我们打包项目中的样式文件就会单独的放在一个.css
文件中。当然我们也可以通过配置插件的filename
属性命名打包后的.css
文件。
new MiniCssExtractPlugin({
// 对输出的样式文件重命名
filename: "css/style.css",
}),
2.2 兼容性处理
这里需要使用到PostCSS。
PostCSS是一个用来处理项目中CSS文件的工具,它具有非常多的功能,同时拥有大量插件,可以实现处理CSS兼容性问题,处理CSS重复代码问题等等一系列的问题。
因为我对PostCSS也没有深入研究,所以这里只是讲解一下它如何处理CSS各个厂商的私有属性。
首先我们需要引入两个包:
npm install postcss-loader postcss-preset-env --save-dev
在package.json
文件中添加下面的代码,当然也可以单独提取出来做一个文件,文件名要命名为:.browserslistrc
。
下面代表适配浏览器的版本,关于更多配置可以到browserslist。进行查看,而我这里直接拿了vue项目默认的兼容性配置。
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
然后修改webpack.config.js中的配置。
// 在loader中配置
{
// 用正则表达式匹配文件类型,下面就是匹配以.css结尾的文件,并且将它们使用下面的loader解析。
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
// 将css文件编程CommonJs模块加载到js中,里面内容是样式字符串
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
// 浏览器兼容性处理
plugins: ["postcss-preset-env"],
},
},
},
],
},
到这里再通过webpack打包:
打包前:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
display: flex;
backface-visibility: hidden;
}
打包后:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
display: flex;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
可以看到PostCSS自动为我们做了兼容性处理。
2.3 压缩CSS
可以看到我们上面的CSS虽然经过了打包,但是没有进行压缩,所谓的压缩就是去掉代码的格式,让代码紧挨在一起,从而减小代码的体积。
npm install css-minimizer-webpack-plugin --save-dev
使用也非常简单:
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
// 引入插件
new CssMinimizerPlugin(),
重新进行打包,会发现css文件已经被压缩:
*{padding:0;margin:0;box-sizing:border-box;display:flex;-webkit-backface-visibility:hidden;backface-visibility:hidden}
3. js
3.1 Eslint
代码风格检测,因为JavaScript语言为脚本语言,所以写法非常的自由,在团队协作开发时,可能你用的是双引号,我用的是单引号,你句尾加;
号,而我句尾不加。
这些场景非常常见,有时候会因为代码样式问题造成合代码时产生大量冲突,Eslint的出现就是为了解决团队代码风格不一致的问题,它可以通过配置文件让你强制使用双引号或者单引号、句尾加;
或不加;
。让一个项目的代码运用一种风格进行编写。
同时Eslint还会检测出部分代码中可能暗藏BUG的语句。
引入Eslint的目的是为了统一代码风格,提高团队效率,而且现在在vscode上面也有Eslint插件(WebStorm上自带Eslint插件)可以在保存的时候根据规则进行自动修复。而我其实对于Eslint是非常喜爱的。
引入:
npm install eslint-webpack-plugin eslint --save-dev
配置:
const ESLintPlugin = require("eslint-webpack-plugin");
new ESLintPlugin({
// 自动修复代码
fix: true,
}),
这里配置就完成了,你可以直接在项目中输入命令:
eslint --init
生成配置文件,它可以选择3个大公司的Eslint规则,分别是:
- Airbnb: https://github.com/airbnb/javascript
- Standard: https://github.com/standard/standard
- Google: https://github.com/google/eslint-config-google
在过去Airbnb用的是非常多的,但是我其实更喜欢使用prettier,因为prettier更接近我平时写代码的风格,而且最近使用prettier的越来越多。
prettier使用
下载:
npm install eslint-config-prettier eslint-plugin-prettier prettier --save -dev
在项目根目录中创建.eslintrc.js
文件,写入下面的代码。
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: ["prettier", "plugin:prettier/recommended"],
parserOptions: {
ecmaVersion: 12,
sourceType: "module",
},
rules: {},
};
3.2 兼容性处理
正如上面所说,有些浏览器不认识ES6的语法,所以我们需要对这些代码做一些兼容性处理。
如果我们有下面的js代码:
import "./src/style.css";
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve(2);
});
});
promise.then((req) => {
console.log(req);
});
可以看到我们这里不光用了ES6的const
还用了Promise
,最终的打包结果是:
!function(){"use strict";new Promise((e=>{setTimeout((()=>{e(2)}))})).then((e=>{console.log(e)}))}();
而Promise
没有经过兼容性处理,这个时候我们就需要引入下面的包:
npm install -D babel-loader @babel/core @babel/preset-env core-js
配置:
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
// 预设:指示babel做怎么样的兼容性处理。
presets: [
[
"@babel/preset-env",
{
corejs: {
version: 3,
},
// 按需加载
useBuiltIns: "usage",
// 需要适配的最低版本
targets: {
chrome: "60",
firefox: "60",
ie: "9",
safari: "10",
edge: "17",
},
},
],
],
},
},
],
},
再进行一次打包,看一下最后我们打包的js文件,发现多了很多代码,这是因为将Promise
转化成了ES5的形式进行实现。
4. devSever
在之前的项目中,我们的目录结构最重要的两个文件夹:
- build:打包后项目的代码。
- src:项目的源代码。
我们最好将项目的源代码放在src
中进行统一管理,但是我们运行的项目是build
目录中最终打包后的项目,如果我们源代码发生了改变,我们就必须要手动执行一次打包命令进行重新打包,不然build
目录下依然是上次打包后的结果。
为了实现项目热更新,我们需要用到webpack-dev-server。
它实现了项目的热更新,需要注意的是,它的操作是在内存中进行完成,并不会输出打包文件,首先进行下载:
npm install webpack-dev-server --save-dev
在webpack.config.js
中增加配置:
devServer: {
// 项目构建后的路径
contentBase: resolve(__dirname, "build"),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open: true,
},
- contentBase:项目构建后的路径。
- compress:gzip压缩。
- port:端口号。
- open:打开浏览器,默认为false。
配置完毕后输后在终端中输入:
webpack serve
等待一会,发现会打开一个新窗口。
新窗口中就可以看到之前的项目。
这个时候只要代码进行了改动,devSever就会自动帮我们再进行打包、刷新浏览器等操作。
5. 最后
到这里为止,webpack的基础内容几乎已经全部学习完毕,经过本次的学习,我学到了如何处理CSS和JS的兼容性问题,同时我也学到了如何通过webpack打开一个服务器。
但是webpack的学习之旅还没有结束,我们只是会了基础的webpack配置,还有关于项目优化的配置我们还没有进行学习,比如如何优化打包速度,如何加快项目启动速度,如何加快热更新速度,这些都影响着我们实际开发中的效率。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!