tips: 本文及后续 webpack 相关文章如未特殊声明,都是在基于 5.x 版本进行文章编写
webpack 是什么?
本质上,webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。
现在开源社区中,与 webpack 功能相似的有 rollup、vite 等,在这我做一下简单的介绍
Rollup
是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序Rollup
偏向应用于 js 库,例如做 ES 转换,模块解析等,webpack 则更偏向于前端工程、UI 库等,如果应用场景中不止包含 js 代码,还涉及 html、css,涉及复杂的代码拆分合并的话,webpack 会更加出众Vite
—— 一种新的、更快地 web 开发工具(opinionated),Vite 的主要特点是依赖浏览器原生的 ES module 来开发,省略了打包这一过程,采用 rollup for producton.
webpack 的核心概念
- entry:入口
- output:出口
- loader:模块转换器,loader 可以使你在 import 或 “load(加载)” 模块时预处理文件
- plugins:插件,插件目的在于解决 loader 无法实现的其他事
Begin
1 |
|
配置 webpack 首先需要安装 webpack、webpack-cli
由于前端技术迭代迅速,并且不同版本包之间的配置存在差异,版本号标注如下
1 |
|
1 |
|
从 v4.0.0 开始,webpack 可以不用再引入一个配置文件来打包项目,然而,它仍然有着 高度可配置性,可以很好满足你的需求。
我们接下来采用自定义配置的方式,去探索一下 webpack 的魅力
首先,项目根目录下新建 src/index.js
文件作为我们接下来配置的入口文件,同样根目录下新建 webpack.config.js
文件来进行我们的 webpack 配置
让我们随便写点什么~
1 |
|
1 |
|
使用 npx webpack
进行构建,根目录下成功生成/dist/bundle.6f3551.js
文件,但是留意到有警告信息:
提示我们没有设置 mode,默认将采用production
模式,为了方便调试,我们将 mode 设置为development
模式,重新使用npx webpack --mode=development
构建,警告清除
为了方便启动,在package.json
中添加脚本,每次重新构建运行npm run build
即可
1 |
|
打开 dist 目录下构建好的文件
1 |
|
JS 向下兼容
由于 js 代码最终运行在用户的浏览器上,少数低版本浏览器例如 ie 对 js 的的新语法存在兼容性问题,这时候我们就需要将这一部分不兼容的语法转义成浏览器能解析的低版本语法
1 |
|
1 |
|
添加上 babel-loader 之后,还需要对 babel 进行配置,根目录下新建.babelrc 文件
1 |
|
再次运行npm run build
构建
1 |
|
可以看到声明变量从const
已经转义成var
捣鼓了这么久,可能有些小伙伴就该问了:怎么还不能在浏览器上查看页面呢?那么我们接着往下走
首先安装依赖包
1 |
|
项目根目录新建public
文件夹,在该目录下新建 index.html 文件,文件内容为标准 html5 模板即可
webpack.config.js
添加如下配置
1 |
|
再次运行npm run build
构建,可以看到 dist 目录下多了依照public/index.html
生成的index.html
文件,并且自动引入了构建的 js 文件,这时候我们已经可以通过live server
将我们的代码运行在浏览器上了,但是每次修改后都要重新构建才能预览变更显然是不合理的,我们需要的是在浏览器中能实时展示效果
实时预览
遇事不决,先装依赖
1 |
|
在package.json
添加脚本
1 |
|
运行启动脚本 npm run dev
,可以在终端看到程序已经运行到http://localhost:3000/
,打开浏览器访问该连接即可预览我们程序
修改一下我们的代码,例如在 src/index.js
中添加console.log('Hello World')
保存后回到浏览器打开控制台,可以发现已经成功打印,我们还可以在 webpack.config.js
中进行自定义的 webpack-dev-server
相关配置,更多配置 webpack-dev-server
1 |
|
重新npm run dev
程序启动在http://localhost:9000/
,抱着严谨的态度复制该链接在 IE 浏览器访问,打开控制台,好家伙居然报错了,我们开始不是通过babel
把高版本 js 向下兼容了吗,根据报错信息以及dist
文件夹下打包的代码定位到原因:babel
的确帮我们进行了转义,但是 webpack 5 在构建的时候默认是箭头函数来包裹代码,而箭头函数在低版本浏览器中是不兼容的
1 |
|
修改配置文件后,需要重新启动程序npm run dev
,ie 浏览器下刷新报错清除,正常打印,运行npm run build
发现dist
目录下构建的 js 代码中箭头函数被替换成普通函数
devtool
我们将src/index.js
中console.log('Hello World')
这一行前回车多添加几个空行,打开浏览器控制台查看
如图告诉我这一行打印来自与 bundle.xxx 文件第二行,而实际情况是我的这行代码写在src/index.js
的第五行,这样就很影响我们开发过程中定位问题,devtool
可以帮助我们映射源码位置,帮助我们 debugger
1 |
|
修改配置文件,重启程序npm run dev
,正确映射源码地址
*devtool
的不同设置会直接影响到构建速度,以及打包后文件的大小,因此要根据实际情况配置,具体参考devtool
style
新建src/index.less
文件,并且在src/index.js
中引入
1 |
|
终端报错,提示我们需要loader
来处理.less
类型的文件。对于css
、less
、sass
等样式文件 webpack 并不能直接处理,需要借助相应的 loader,接下来以less
为例,来使得 webpack 可以处理样式文件,首先先安装依赖
1 |
|
修改webpack.config.js
配置文件
1 |
|
npm run dev
重启程序,报错清楚,浏览器能正确显示设置的背景色
图片以及字体文件处理
修改src/index.less
1 |
|
当我们设置背景为一张本地图片时,发现终端报类似上面处理less
文件的错误,也就是说我们需要配置对应loader
来处理
1 |
|
1 |
|
打包前清空 dist 目录
由于每次打包都会生成dist
文件夹,文件名上又存在 hash 的原因,所以每次打包,之前的dist
目录下的文件就会成为没有意义的垃圾文件,我们可以打包前手动清除它,当然我们可以使用webpack
的插件来帮我们偷懒
1 |
|
1 |
|
可以配置cleanOnceBeforeBuildPatterns
,来排除那些不想清除的文件
1 |
|
静态资源拷贝
有时候我们有一些本地资源不希望经过 webpack 打包处理,比如一些外部 sdk,接下来我们来模拟一下,在public
目录下新建js/cdn.js
文件,然后在public/index.html
中将其引入
1 |
|
1 |
|
打开浏览器控制台,发现我们引入的cdn.js
报 404 了,因为我们并没有在入口文件src/index.js
中引入cdn.js
,所以 webpack 并没有将其打包,我们可以通过插件来帮我们自动拷贝文件来解决这个问题
1 |
|
修改配置文件
1 |
|
npm run dev
重启程序,发现浏览器控制台 404 错误清除,正确打印cdn init
配置到这一步,webpack 的基础配置就差不多完成了,不过 webpack 的强大远不止此,可以根据实际的需求完善&优化 webpack 的配置~