Webpack 核心概念
javascript module.exports = { entry: './src/index.js', };
### 多入口配置
如果你的应用需要构建出多个独立的包(例如一个页面有多个入口),可以使用对象语法:
```javascript
module.exports = {
entry: {
main: './src/index.js',
admin: './src/admin.js',
},
};
这样 Webpack 会输出两个互不干扰的产物。
核心概念二:输出(Output)
输出告诉 Webpack 将打包后的资源放到哪里,以及如何命名它们。输出配置只在有多入口时才能真正体现出其灵活性。
基本配置
output 包含两个最重要的字段:path 和 filename。
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
};
多入口输出命名
当存在多个入口时,可以用占位符生成不同的文件名,避免相互覆盖:
module.exports = {
entry: {
app: './src/app.js',
vendor: './src/vendor.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
},
};
[name] 会被替换为入口的名称(如 app、vendor),[contenthash] 会根据文件内容生成哈希,用于浏览器缓存策略。
核心概念三:加载器(Loaders)
Webpack 自身只能处理 JavaScript 和 JSON 文件。加载器允许 Webpack 去处理其他类型的文件,并将它们转换为可以在应用中使用的有效模块。
工作原理
加载器本质上是一个函数,接收源文件内容作为参数,返回转换后的结果。你可以在 module.rules 中为不同的文件类型配置相应的加载器。
示例:处理 CSS 和图片
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif)$/,
type: 'asset/resource', // webpack 5 内置资源模块
},
],
},
};
css-loader解析 CSS 中的@import和url(),把 CSS 文件处理成模块。style-loader将解析后的 CSS 注入到 DOM 中的<style>标签。asset/resource会将图片文件单独输出,并返回最终路径。
常用加载器
| 文件类型 | 加载器示例 | 作用 |
|---|---|---|
| 新版 JavaScript (ES6+) | babel-loader |
将 ES6+ 代码转译为兼容老浏览器的版本 |
| TypeScript | ts-loader / babel-loader |
将 TS 编译为 JS |
| CSS / Sass / Less | sass-loader → css-loader → style-loader |
处理预处理器样式并注入 |
| 图片 / 字体 | asset/resource 或 file-loader |
输出文件并返回路径 |
| Vue 单文件组件 | vue-loader |
解析 .vue 文件 |
核心概念四:插件(Plugins)
插件可以执行比加载器更广泛的任务,包括打包优化、资源管理、注入环境变量等。插件在 Webpack 构建流程中的“钩子”上执行操作,是 Webpack 的骨干功能。
如何使用
使用插件时,需要先 require 引入,然后在 plugins 数组中实例化。
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
],
};
HtmlWebpackPlugin 会自动生成一个 HTML 文件,并将打包后的 JavaScript 文件(或其他资源)通过 <script> 标签自动注入到页面中。
常用插件
- MiniCssExtractPlugin:将 CSS 提取到独立的文件,而不是通过 JS 注入样式。
- CleanWebpackPlugin:每次构建前自动清理输出目录。
- DefinePlugin:在编译时创建全局常量,常用于注入环境变量
process.env.NODE_ENV。 - CopyWebpackPlugin:将静态文件直接复制到输出目录。
核心概念五:模式(Mode)
模式是 Webpack 提供的一键式配置,用于启用对应环境的内置优化。它有三个可选值:development、production、none。
各模式区别
| 模式 | 默认优化 | 适用场景 |
|---|---|---|
development |
启用 NamedChunksPlugin 和 NamedModulesPlugin,关闭压缩 |
本地开发,需要快速构建和友好报错 |
production |
启用 TerserPlugin 压缩代码,作用域提升,tree shaking 等 |
线上部署,需要最小体积和高性能 |
none |
不使用任何默认优化 | 需要完全自定义配置时使用 |
配置方式
module.exports = {
mode: 'development', // 或 'production'
};
核心概念六:代码拆分(Code Splitting)
代码拆分是 Webpack 最引人注目的特性之一。它将代码分割成多个较小的包,从而实现按需加载或并行加载,显著提升首屏加载速度。
三种常用方法
-
入口拆分
通过配置多个入口手动分离代码,适用于简单场景。entry: { page1: './src/page1.js', page2: './src/page2.js', }, -
防止重复(共享依赖)
使用SplitChunksPlugin自动将公共模块提取到一个单独的文件中。Webpack 4+ 默认包含该插件。optimization: { splitChunks: { chunks: 'all', }, },上述配置会将
node_modules中的第三方库抽取到名为vendors的块中,将公共业务模块抽取到common块中。 -
动态导入(Dynamic Imports)
使用 ES2020 的import()语法,Webpack 会自动将动态导入的模块分离出来。这是实现路由懒加载的经典方式。// 某个按钮点击后才加载模块 button.addEventListener('click', () => { import('./module').then(module => { module.default(); }); });