Webpack
本文最后更新于:8 个月前
现代网页越来越复杂,资源必须通过增量加载的方式来优化网页加载速度,在这个过程中,模块打包器发挥了关键作用,而webpack是目前主流的模块的打包器之一。本文记录了《webpack中文文档》阅读笔记,以及参照”指南“部分,实践的记录。
Webpack
《中文指南》阅读笔记
一本webpack中文文档,适合了解一些基本概念(不适合作为严格的参考指南)
链接:前言 | Webpack 中文指南 (zhaoda.net)
现代前端开发已经从单一网页向更庞大的webapp发展,同时前端产品交付基于浏览器,资源是通过增量加载的方式运行到浏览器的,但是大量资源的加载将增加浏览器加载的时间,降低用户体验。如何让用户能够快速地。优雅地加载和更新,模块化系统在这样的问题背景下应运而生。
模块化有很多标准:CommonJS(同步)、AMD(异步模块定义)、CMD(异步)、ES6Module(同步)
而Webpack是一个兼容上面许多规规范的模块打包器
各种Loader的作用,webpack只能处理原生javasrcipt模块,而Loader可以把各种类型文件转换为JS,这样就可以加载任何类型的模块或文件
《webpack指南》实践记录
链接:参照《webpack指南》,实践代码,可作为webpack入门实践 (github.com)
《webpack概念》笔记
链接:概念 | webpack 中文网 (webpackjs.com)
webpack做了什么
本质上,webpack 是一个现代 JavaScript 应用程序的**静态模块打包器(module bundler)*。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph)*,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle
一、入口
用法:entry: string|Array<string>
单个入口,两种写法
1 |
|
如果传入的是string数组,将创建多个主入口。在你想要多个依赖文件一起注入,并且将它们的依赖导向(graph)到一个“chunk”时,传入数组的方式就很有用
对象语法,常用,用法:entry: {[entryChunkName: string]: string|Array<string>}
1 |
|
常见场景
SPA,单页面应用常见的做法是:将应用程序和第三方库(vendor)分入口打包构建
MPA,多页面应用常见的做法是将每个页面作为一个入口,然后可以使用CommonsChunkPlugin
为每个页面间的应用程序共享代码创建 bundle,这样,多页应用能够复用入口起点之间的大量代码/模块
二、输出
配置 output
选项可以控制 webpack 如何向硬盘写入编译文件。注意,即使可以存在多个入口
起点,但只指定一个输出
配置
在 webpack 中配置 output
属性的最低要求是,将它的值设置为一个对象,包括以下两点:
filename
用于输出文件的文件名。- 目标输出目录
path
的绝对路径
1 |
|
三、模式
提供 mode
配置选项,告知 webpack 使用相应模式的内置优化
选项 | 描述 |
---|---|
development | 会将 process.env.NODE_ENV 的值设为 development 。启用 NamedChunksPlugin 和 NamedModulesPlugin |
production | 会将 process.env.NODE_ENV 的值设为 production 。启用 FlagDependencyUsagePlugin , FlagIncludedChunksPlugin , ModuleConcatenationPlugin , NoEmitOnErrorsPlugin , OccurrenceOrderPlugin , SideEffectsFlagPlugin 和 UglifyJsPlugin |
四、loader
loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import
CSS文件。借助于loader,webpack可以处理各种类型的文件(webpack本身只能处理JavaScript模块)
loader的3种使用方式
- 配置,在
webpack.config.js
文件中配置,推荐使用 - 内联,在每个
import
语句中指定 - CLI,在shell命令中指定
配置
1 |
|
内联
1 |
|
CLI
1 |
|
loader特性
- 支持链式传递。能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript
- loader 接收查询参数。用于对 loader 传递配置
- loader 也能够使用
options
对象进行配置 - loader 运行在 Node.js 中,并且能够执行任何可能的操作
- loader 可以是同步的,也可以是异步的
- loader 能够产生额外的任意文件
五、插件
插件目的在于解决 loader 无法实现的其他事,范围包括,从打包优化和压缩,一直到重新定义环境中的变量
由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins
属性传入 new
实例
下例展示插件在webpack.config.js
文件中的使用
1 |
|
六、配置
webpack 的配置文件,是导出一个对象的 JavaScript 文件。是标准的 Node.js CommonJS 模块,你可以做到以下事情:
- 通过
require(...)
导入其他文件 - 通过
require(...)
使用 npm 的工具函数 - 使用 JavaScript 控制流表达式,例如
?:
操作符 - 对常用值使用常量或变量
- 编写并执行函数来生成部分配置
1 |
|
七、依赖图
任何时候,一个文件依赖于另一个文件,webpack 就把此视为文件之间有 依赖关系。
webpack从指定的入口开始,递归地构建一个依赖图,这个依赖图包含应用程序所需的每个模块,然后将这些模块打包成少量的bundle
八、manifest
manifest是什么?
runtime,以及伴随的 manifest 数据,主要是指:在浏览器运行时,webpack 用来连接模块化的应用程序的所有代码
runtime
包含:在模块交互时,连接模块所需的加载和解析逻辑。包括浏览器中的已加载模块的连接,以及懒加载模块的执行逻辑
manifest
当编译器(compiler)开始执行、解析和映射应用程序时,它会保留所有模块的详细要点。这个数据集合称为 “Manifest”,当完成打包并发送到浏览器时,会在运行时通过 Manifest 来解析和加载模块。所有 import
或 require
语句现在都已经转换为 __webpack_require__
方法,此方法指向模块标识符(module identifier)。通过使用 manifest 中的数据,runtime 将能够查询模块标识符,检索出背后对应的模块。