目录
十、HMR - Hot Module Replacement 热更新
一、webpack 是什么
答:webpack 是 javascript 应用程序的静态模块打包器。它会从一个或多个入口构建依赖关系,然后将项目组合成一个或多个包。
二、webpack 核心概念
答:Entry(入口)、Output(输出)、Loaders(预处理)、Plugins(插件)、Mode(模式)、Browser Compatibility(浏览器兼容性)
三、Entry 入口
简例如下:
// webpack.config.js
// entry: string | [string]
// 单入口
module.exports = {
entry: './path/to/my/entry/file.js',
};
// 将依赖关系绘制成一块
module.exports = {
entry: {
main: './path/to/my/entry/file.js',
},
};
// 多个入口
module.exports = {
entry: ['./src/file_1.js', './src/file_2.js'],
};
入口对象属性以下
-
dependOn
: 当前入口所依赖的入口。它们必须在该入口被加载前被加载。
module.exports = {
entry: {
a2: 'dependingfile.js',
b2: {
dependOn: 'a2', // 将会在 a2 之前加载
},
},
};
-
filename
: 指定要输出的文件名称。 -
import
: 启动时需加载的模块。 -
library
: 指定 library 选项,为当前 entry 构建一个 library。 -
runtime
: 运行时 chunk 的名字。如果设置了,就会创建一个新的运行时 chunk。在 webpack 5.43.0 之后可将其设为false
以避免一个新的运行时 chunk。 -
publicPath
: 当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 URL 地址。
注意问题
runtime
和dependOn
不能在同一个入口上同时使用- 确保
runtime
不能指向已存在的入口名称 - 另外
dependOn
不能相互入口引用
四、Output 输出
通过 output 选项,输出打包文件。要注意的是,我们可以设置多个 entry 入口,但只能配置一个 output 。
简例:
module.exports = {
output: {
filename: 'bundle.js',
},
};
// 多个入口
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js',
},
output: {
filename: '[name].js',
path: __dirname + '/dist',
},
};
// 写入到硬盘:./dist/app.js, ./dist/search.js
如果在编译时,不知道最终输出文件的 publicPath
是什么地址,则可以将其留空,并且在运行时通过入口起点文件中的 __webpack_public_path__
动态设置。
// webpack.config.js
module.exports = {
//...
output: {
path: '/home/proj/cdn/assets/[fullhash]',
publicPath: 'https://cdn.example.com/assets/[fullhash]/',
},
};
__webpack_public_path__ = myRuntimePublicPath;
// 应用程序入口的其余部分
五、Loaders(预处理)
loader 用于对模块的源代码进行转换。loader 可以使你在 import
或 "load(加载)" 模块时预处理文件。
简例:
npm install --save-dev css-loader ts-loader
// webpack.config.js
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' }, // 每个 .css 文件使用 css-loader
{ test: /\.ts$/, use: 'ts-loader' }, // 每个 .ts 文件使用 ts-loader
],
},
};
loader 特性
- 支持链式调用。并且 loader 的执行顺序是相反的,所以上述例子实际顺序是:ts > css
- 可同步,可异步
- 运行在 node.js 中,并且能执行任何操作
- 通过 options 对象配置
- 除了常见的通过
package.json
的main
来将一个 npm 模块导出为 loader,还可以在 module.rules 中使用loader
字段直接引用一个模块。 - 插件可以为 loader 带来更多特性
- 可以产生额外的任意文件
六、Plugin 插件
plugin 主要的目的是解决 loader 无法解决的事情
简例:
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // 访问内置的插件
module.exports = {
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({ template: './src/index.html' }),
],
};
七、Targets 构建目标
由于 javascript 可以编写浏览器代码,也可以编写服务端代码,所以 webpack 提供了多种部署的 Target ,点击这里查看 Target 可用值 ,默认值为 web 。
简例
// webpack.config.js
module.exports = {
target: 'node',
};
八、Runtime 与 Manifest
runtime 和 manifest 都用来管理所有模块的交互。当 compiler 开始执行、解析和映射应用程序时,它会保留所有模块的详细要点。这个数据集就是manifest。当把这些打好的包送到浏览器时,runtime 会通过 manifest 来解析和加载模块
九、Module 模块
模块化编程下,开发者将程序分解为功能离散的 chunk(块),称为模块。
webpack 支持的模块类型:
- ECMAScript 模块
- CommonJS 模块
- AMD 模块
- Assets
- WebAssembly 模块
十、HMR - Hot Module Replacement 热更新
HMR 功能会在应用程序运行过程中进行替换、添加或删除模块,而无需重新加载整个页面。