前言
首先抛出结论,webpack是一个非常简单的工具,毫无难度可言。webpack阻碍很多人的根本原因是大家对一些概念的不熟悉、对webpack丰富的loader和plugin望而怯步。当你把概念弄清楚后,你自然而然的就知道自己需要什么loader和plugin了。
看完后你一定会说:“就这?webpack就这?”。
个人建议:例如create-react-app就是一个很好的脚手架,你可以写不出这样的脚手架,但你一定要能看懂,在你有需要的时候有能力去修改源码。webpack掌握到这个程度很多时候就完全够用了。在最后我还会补充如何自己写一个loader和plugin(不过我相信不用到最后,认真阅读的你就已经知道要如何编写了)
准备环境、版本
node: ^12.16.1
webpack: ^4.44.2
webpack-cli: ^3.3.12
webpack5升级了一些新特性,所以我们这篇文章以目前常用的webpack4来讲解。不过完全不用担心都出5了怎么还学4的问题,道理都是相通的,4都会了,5它不就是多点新特性了吗
你必须知道的知识
1、webpack概念
webpack是一个现代JavaScript应用程序的静态模块打包器。如果你接触js够早的话,你一定知道最初的工程可没有这样的打包工具,一个文件就相当于一个模块,最终这些文件需要按照一定的顺序使用script标签引入html(因为如果顺序不对就会导致依赖变量丢失等错误问题)。
但是这个写项目不仅麻烦而且不优雅,随着node.js的出现和发展,才出现了这类基于node.js运行的打包工具(gulp、grunt,以及现在最流行的webpack),因为node.js拥有可对文件操作的能力。所以webpack本质就是为我们打包js的引用,而我们常听到各种loader、各种plugin、热更新、热模块替换等等都是webpack的一个升华,使得webpack能为我们提供更多的帮助。
- loader:webpack本身只能打包js和json格式的文件,但实际项目中我们还有css、scss、png、ts等其他文件,这时我们就需要使用loader来让它正确打包。
总结: loader是处理编译js和json以外的文件时用的
常见的loader:
style-loader
css-loader
sass-loader
ts-loader
file-loader
babel-loader
postcss-loader
...
- plugin:plugin可以在webpack运行到某个阶段时候,帮你做一些事情,类似react/vue中的生命周期。具体的某个插件(plugin)就是在webpack构建过程中的特定时机注入扩展逻辑来改变构建结果,作用于整个构建过程。
弄明白这些东西
-
postcss:postcss是一个用 JavaScript 工具和插件转换 CSS 代码的工具。你可以把他理解成babel,他本身作用不大,我们很多具体需求的实现都需要他的插件来完成,他本身更像一个平台。
例如,项目中我们需要webpack自动的帮我们为css样式加上兼容性前缀,实际帮我们加上前缀的插件是autoprefixer,但他能为我们加前缀的前提又是我们有postcss。千万不要把postcss误解postcss成scss、less替代品. -
babel:babel 是一个 JavaScript 编译器,他可以让我们不再考虑兼容性,尽情的使用下一代的 JavaScript 语法编程。但是要实现具体的语法转换,我们还是要使用他的插件才能实现。
在babel7后为我们提供了预设[5],可以让我们不再自己麻烦的对插件进行组合,想在什么环境运行就写什么预设即可(相当于每个预设选项中都帮你组合好了这个环境中需要用到的插件) -
es6+语法:babel默认会转换语法,例如:let、const、() => {}、class
-
es6+特性:babel不会转换特性(API),特性需要js代码垫片来兼容低版本的浏览器。例如:Iterator、Generator、Set、Map、Proxy、Reflect、Symbol、Promise
-
@babel/core:@babel/core是babel的核心库,所有的核心api都在这个库里,这些api可供babel-loader调用
-
@babel/preset-env:这是一个预设的插件集合,包含了一组相关的插件,Bable中是通过各种插件来指导如何进行代码转换。该插件包含所有es6转化为es5的翻译规则
-
@babel/polyfill:@babel/preset-env只是提供了语法转换的规则,但是它并不能弥补浏览器缺失的一些新的功能,如一些内置的方法和对象,如Promise,Array.from等,此时就需要polyfill来做js的垫片,弥补低版本浏览器缺失的这些新功能。注意:Babel 7.4.0该包将被废弃
-
core-js:它是JavaScript标准库的polyfill,而且它可以实现按需加载。使用@babel/preset-env的时候可以配置core-js的版本和core-js的引入方式。注意:@babel/polyfill依赖core-js
-
regenerator-runtime:提供generator函数的转码
补充知识点(重要)
- browserslist:browserslist实际上就是声明了一段浏览器的合集,我们的工具可以根据这个合集描述,针对性的输出兼容性代码,browserslist应用于babel、postcss等工具当中。
- browserslist可以在package.json文件配置,也可以单出写一个.browserslistrc文件进行配置
- 工具会自动查找.browserslistrc中的配置,如果没有发现.browserslistrc文件,则会去package.json中查找
// 在.browserslistrc中的写法
> 1%
last 2 versions
// 还可以配置不同环境下的规则(在.browserslistrc中)
[production]
> 1%
ie 10
[development]
last 1 chrome version
last 1 firefox version
// 在package.json中的写法
{
"browserslist": ["> 1%", "last 2 versions"]
}
// 还可以配置不同环境下的规则(在package.json中)
// production和development取决你webpack中mode字段的配置
{
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
“> 1%”表示兼容市面上使用量大于百分之一的浏览,“last 1 chrome version”表示兼容到谷歌的上一个版本,具体的可以使用命令npx browserslist "> 1%"的方式查看都包含了哪些浏览器
执行 npx browserslist "> 1%"
chrome 100
chrome 99
edge 100
firefox 99
ios_saf 15.4
ios_saf 15.2-15.3
ios_saf 14.5-14.8
op_mini all
safari 15.4
samsung 16.0
- chunk:它不是库也不是插件,它就是一个名词,顾名思义就是代码块。为什么要单独把他拎出来说呢,因为你明白它以后你自然就能理解webpack中配置一些参数的意思了
- chunks:一个chunks至少包含一个chunk,chunks是多个chunk的合集
上面代码来说,a.js就是chunk,而index.js就是chunks
在webpack构建中入口是chunks,出口是chunk(知道这个概念就行)
网友评论