是JavaScript应用程序的静态模块打包器。当webpack处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有模块打包成一个或多个bundle。
四个核心概念:
- 入口(entry)
- 输出(output)
- loader
- 插件(plugins)
webpack优点
- 可以打包你的 JavaScript 应用程序(支持 ESM 和 CommonJS)
- 可以扩展为支持许多不同的静态资源
- 关心性能和加载时间
- 始终在改进或添加新功能
- 依赖自动收集:自动构建并基于你所引用或导出的内容推断出依赖的图谱
入口
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
默认值:./src/index.js。
- 也可在webpack.config.js中的module.exports里面配置entry,指定一个或多个不同的入口起点
配置方式
- 单个入口
- 用法:entry: string | Array
- 示例:entry: ‘./path/to/my/entry/file.js’
- 用法:entry: string | Array
- 对象语法:定义入口的最可扩展方式
- 用法:entry: {[entryChunkName: string]: string | [string]>}
- 示例:
1
2
3
4entry: {
app: './src/app.js',
adminApp: './src/adminApp.js'
}
描述入口的对象
- dependOn: 当前入口所依赖的入口。必须在该入口被加载前被加载。
- filename: 指定要输出的文件名称。
- import: 启动时需加载的模块。
- library: 指定 library 选项,为当前 entry 构建一个 library。
- runtime: 运行时 chunk 的名字。在 webpack 5.43.0 之后可将其设为 false 以避免一个新的运行时 chunk。
- publicPath: 当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 URL 地址。
常用场景
- 分离应用程序(app)和第三方库(vendor)入口
- 多页面程序
1
2
3
4
5
6// 解析:告诉webpack需要三个独立分离的依赖图
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
输出
告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件。只能有一个output
默认值: ./dist
- 也可在webpack.config.js中的module.exports里面配置output属性
配置方式:
- output最低要求是,将它的值设置为一个对象,然后给输出文件的文件名配置output.filename
- 多个入口起点:使用占位符(substitutions)来确保每个文件具有唯一的名称
1
2
3
4output: {
filename: '[name].js',
path: __dirname + '/dist', //写入到./dist/filename
}, - 高阶进阶
1
2
3
4
5
6output: {
path: '/home/proj/cdn/assets/[fullhash]',
publicPath: 'https://cdn.example.com/assets/[fullhash]/',
}
// publicPath: '' 时,在运行时通过入口起点文件中的 __webpack_public_path__ 动态设置
__webpack_public_path__ = myRuntimePublicPath;
loader
让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。
属性:
- test 属性,识别出哪些文件会被转换。
- use 属性,表示进行转换时,应该使用哪个 loader。
安装对应的loader
- npm install –save-dev css-loader ts-loader
配置方式:
- 在webpack.config.js中的config里的module.exports里面的module配置rules,指定loader
- 例:rules:[{test:/.css$/,use:’css-loader’},]
- loader执行顺序: 从右到左(或从上到下)地取值(evaluate)/执行(execute)
使用loader
- 内联方式:在每个import语句中显式指定loader
- 使用!前缀,将禁用所有已配置的normal loader
- import Styles from ‘!style-loader!css-loader?modules!./styles.css’;
- 使用!!前缀,将禁用所有已配置的loader(preLoader, loader, postLoader)
- import Styles from ‘!!style-loader!css-loader?modules!./styles.css’;
- 使用-!前缀,将禁用所有已配置的preLoader和loader,但是不禁用postLoaders
- import Styles from ‘-!style-loader!css-loader?modules!./styles.css’;
- 选项可以传递查询参数,例如 ?key=value&foo=bar,或者一个 JSON 对象,例如 ?{“key”:”value”,”foo”:”bar”}
loader 特性
- 支持链式调用。链中的每个 loader 会将转换应用在已处理过的资源上。一组链式的 loader 将按照相反的顺序执行。链中的第一个 loader 将其结果传递给下一个 loader,依此类推。最后,链中的最后一个 loader,返回 webpack 所期望的 JavaScript。
- 可以是同步的,也可以是异步的。
- 运行在 Node.js 中,并且能够执行任何操作。
- 除了通过 package.json 的 main 来将一个 npm 模块导出为 loader,还可以在 module.rules 中使用 loader 字段直接引用一个模块。
解析loader
- 遵循标准模块解析规则。多数情况下,loader 将从模块路径加载(通常是从 npm install, node_modules 进行加载)
- loader 模块会导出为一个函数,并且编写为 Node.js 兼容的 JavaScript。loader 通常被命名为 xxx-loader。
插件
webpack的支柱功能,用于执行从打包优化和压缩,一直到重新定义环境中的变量的任务。具有apply方法的js对象。
- 注意:如果在插件中使用了 webpack-sources 的 package,请使用 require(‘webpack’).sources 替代 require(‘webpack-sources’),以避免持久缓存的版本冲突。
配置方式:
- 在webpack.config.js中,首先需要require() 它,然后添加一个new实例到module.exports里的plugins数组
1
2
3
4const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 访问内置的插件
plugins: [new webpack.ProgressPlugin(), //用于自定义编译过程中的进度报告
new HtmlWebpackPlugin({template: './src/index.html'})] - Node API方式
1
2
3
4
5const webpack = require('webpack'); // 访问 webpack 运行时(runtime)
const configuration = require('./webpack.config.js');
let compiler = webpack(configuration);
new webpack.ProgressPlugin().apply(compiler);
compiler.run(function (err, stats) {});
配置文件
webpack 的配置文件是 JavaScript 文件,文件内导出了一个 webpack 配置的对象。
应避免操作
- 当使用 webpack CLI 工具时,访问 CLI 参数(应编写自己的 CLI 工具替代,或者使用 –env)
- 导出不确定的结果(两次调用 webpack 应产生相同的输出文件)
- 编写超长的配置(应将配置文件拆分成多个)
基本配置
1 | const path = require('path'); |
- 多个target: 可以将其导出为多个配置
模块
在模块化编程中,开发者将程序分解为功能离散的chunk,并称为模块
- 支持的模块类型
- ECMAScript 模块
- CommonJS 模块
- AMD 模块
- Assets
- WebAssembly 模块
模式
- 通过选择development或production其中一个,来设置mode参数,启用相应模式下的 webpack 内置的优化
- 配置方式: 在webpack.config.js中的module.exports里mode:’production’
- 也可以分别配置development和production的配置文件,然后启动时调用对应的文件即可
浏览器兼容及环境
- 支持所有符合 ES5 标准 的浏览器(不支持 IE8 及以下版本)
- import() 和 require.ensure() 需要 Promise
- 旧版本浏览器还需要提前加载 polyfill。
- Webpack 5 运行于 Node.js v10.13.0+ 的版本