前言
无论哪个行业,当一件工作的流程越来越复杂时,我们往往会将它分割成多个可管理的小过程来实现,然后用自动构建工具来组合它们;像是汽车制造,起草法律文案,还有建一个现代网站;
随着web应用功能性逐渐加强,网站已经不仅仅是信息展示的工具。现代网站的构建越来越复杂,各种前端框架、依赖及相应的配置文件混杂在根目录下,使得维护难度和成本大大提高;而webpack就是为了解决这类情况的诞生打包工具;
Webpack简介
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(static module bundler)。在 webpack 处理应用程序时,它会在内部创建一个依赖图(dependency graph),用于映射到项目需要的每个模块,然后将所有这些依赖生成到一个或多个bundle。
核心哲学
万物皆模块
:就像普通的JavaScript模块一样,其他css、html文件,静态资源jpg、png等都会被webpack用相应的loader转移后成为模块(除此之外,也存在功能性的loader,如将ES6语法转换为ES5语法的babel-loader
),从而实现项目分解与模块复用;只在需要时加载需要的东西
:一般的模块管理工具会将所有模块集中并生成一个超大的”bundle.js”文件,在实际应用中,这个文件会有10~15M,直接加载的话有丶恐怖;所以webpack有好几种方法来把你的代码分割成多个”bundle”文件,并在app运行时异步加载需要的部分;核心概念
- 入口
entry
:入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始,webpack 会找出有哪些模块和 library 是入口起点(直接和间接)依赖的; - 输出
output
:output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,主输出文件默认为 ./dist/main.js,其他生成文件的默认输出目录是 ./dist。 - 转化器
loader
:作为开箱即用的自带特性,webpack 自身只支持 JavaScript。而 loader 能够让 webpack 处理那些非 JavaScript 文件,并且先将它们转换为有效 模块,然后添加到依赖图中,这样就可以提供给应用程序使用。 - 插件
plugins
:loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务,插件的范围包括:打包优化、资源管理和注入环境变量。
loader
- loader可以是同步的,也可以是异步的。
- loader运行在
Node.js
中
modules.rules
可以为一个文件类型指定多个loader,形成loader链,loader链会按照相反的顺序执行,第一个loader将转换后的资源结果返回给下一个loader,最后一个loader将返回webpack期望的JavaScript:1
2
3
4
5
6
7
8
9
10
11
12// webpack.config.js
module.export = {
rules: [
{
test: '\.css$',
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader', options: { modules: true } }
]
}
]
};
模块热替换[Hot Module Replacement]
HMR功能会在应用程序执行过程中替换、删除或添加模块,而无需重新加载整个页面,主要通过一下几个方式:
- 保留在完全重新加载页面时丢失的应用程序状态。
- 只更新变更内容,以节省宝贵的开发时间。
- 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。
HMR功能应该只被应用于开发环境(develop environment)中。在开发过程中,可以将 HMR 作为 LiveReload
的替代。webpack-dev-server
支持 hot
模式,在试图重新加载整个页面之前,热模式会尝试使用 HMR 来更新;
借助style-loader
的帮助,它实现了HMR接口,可以轻松实现CSS的模块热替换;当更新CSS依赖模块时,style-loader
会在后台使用module.hot.accept
来修补(patch)style
标签;HMR工作的详情参考模块热替换;
生产/开发环境构建
开发环境(development)和生产环境(production)的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的source map
和localhost server
。
而在生产环境中,我们的目标则转向于关注更小的bundle
,更轻量的source map
,以及更优化的资源,以改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置;并通过webpack-merge
工具合并通用部分和独立部分;1
2
3
4
5
6
7
8
9webpack-demo
|- package.json
|- webpack.common.js
|- webpack.prod.js
|- webpack.dev.js
|- dist
|- src
|- node_modules
...
参考资料
- webpack官方文档
- An Annotated webpack 4 Config for Frontend Web Development 非常深入的webpack 4设置解析
- Webpack — The Confusing Parts 对webpack中一些容易混淆的概念进行了详细的解释