JavaScript 模块打包工具(Webpack、Rollup)
模块打包工具将多个模块合并为浏览器可用的文件,Webpack 和 Rollup 是最主流的两种选择。
Webpack 基本概念
JavaScript
// webpack.config.js 基础配置
const path = require('path');
module.exports = {
// 入口:打包起点
entry: './src/index.js',
// 输出:打包结果
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
clean: true // 每次构建清理 dist
},
// 模式:development / production
mode: 'development',
// Loader:处理非 JS 文件
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|jpg|gif)$/,
type: 'asset' //Webpack 5 资源模块
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
// 插件:扩展功能
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
};
Webpack 核心概念
| 概念 | 描述 | 示例 |
|---|---|---|
| Entry | 入口起点 | entry: './src/index.js' |
| Output | 输出配置 | output: { filename: 'bundle.js' } |
| Loader | 文件转换器 | css-loader、babel-loader |
| Plugin | 功能扩展 | HtmlWebpackPlugin |
| Mode | 构建模式 | development / production |
Webpack 常用配置
JavaScript
// 多入口配置
module.exports = {
entry: {
main: './src/index.js',
admin: './src/admin.js'
},
output: {
filename: '[name].[contenthash].js', // 带哈希的文件名
path: path.resolve(__dirname, 'dist')
}
};
// 开发服务器
module.exports = {
devServer: {
static: './dist',
hot: true, // 热更新
port: 3000,
open: true // 自动打开浏览器
}
};
// 代码分割(优化加载)
module.exports = {
optimization: {
splitChunks: {
chunks: 'all', // 分割所有 chunk
minSize: 20000
}
}
};
// Source Map 配置
module.exports = {
devtool: 'source-map', // production 用 'hidden-source-map'
};
Webpack 常用插件
JavaScript
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const DefinePlugin = require('webpack').DefinePlugin;
module.exports = {
plugins: [
// 生成 HTML 并自动引入资源
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
}),
// 提取 CSS 为单独文件
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
}),
// 清理构建目录
new CleanWebpackPlugin(),
// 定义环境变量
new DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
};
Rollup 基本配置
JavaScript
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import terser from '@rollup/plugin-terser';
export default {
// 入口
input: 'src/index.js',
// 输出(可多格式)
output: [
{
file: 'dist/bundle.js',
format: 'umd', // Universal Module Definition
name: 'MyLibrary', // UMD/IIFE 格式需要
sourcemap: true
},
{
file: 'dist/bundle.esm.js',
format: 'esm' // ES Module
},
{
file: 'dist/bundle.cjs.js',
format: 'cjs' // CommonJS
}
],
// 插件
plugins: [
resolve(), // 解析 node_modules
commonjs(), // 转换 CommonJS 为ESM
babel({ babelHelpers: 'bundled' }),
terser() // 压缩
]
};
Rollup 输出格式
| Format | 适用场景 | 特点 |
|---|---|---|
esm | ES Module 环境 | 最简洁,保留 import/export |
cjs | Node.js | CommonJS 格式 |
umd | 多环境兼容 | 同时支持 AMD、CommonJS、全局变量 |
iife | 浏览器直接引用 | 自执行函数,适合 CDN |
system | SystemJS | SystemJS 模块格式 |
Webpack vs Rollup 对比
JavaScript
// Webpack:功能全面,适合应用开发
// - 支持代码分割、懒加载
// - 强大的 Loader 和插件生态
// - 开发服务器、热更新
// - 复杂应用的首选
// Rollup:输出简洁,适合库开发
// - 输出代码干净,无冗余
// - 支持 Tree Shaking(移除未使用代码)
// - 多格式输出(ESM、CJS、UMD)
// - 库开发的首选
// 示例:同样的代码打包结果对比
// Webpack 输出(包含运行时)
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({...});
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/ ...
/******/ })();
// Rollup 输出(直接合并,更简洁)
function hello(name) {
return `Hello, ${name}`;
}
export { hello };
| 特性 | Webpack | Rollup |
|---|---|---|
| 定位 | 应用打包 | 库打包 |
| 代码分割 | ✅ 强大 | ✅ 基础支持 |
| HMR热更新 | ✅ 完整 | ❌ 需额外插件 |
| Tree Shaking | ✅ | ✅ 原生支持 |
| 输出格式 | 单一 | 多格式 |
| 输出代码 | 有运行时 | 简洁干净 |
| 开发体验 | ✅ 完善 | 基础 |
Tree Shaking
JavaScript
// Tree Shaking:移除未使用的代码
// src/utils.js
export function usedFunc() {
console.log('used');
}
export function unusedFunc() {
console.log('unused');
}
// src/index.js
import { usedFunc } from './utils';
usedFunc();
// Rollup 打包后(unusedFunc 被移除)
function usedFunc() {
console.log('used');
}
usedFunc();
// Webpack production模式同样支持 Tree Shaking
// 需要 ES Module 语法(不能用 CommonJS)
实际使用命令
Bash
# Webpack 常用命令
# 安装
npm install webpack webpack-cli --save-dev
# 构建
webpack --config webpack.config.js
npx webpack
# 开发模式
npx webpack serve
# 监听模式
webpack --watch
# Rollup 常用命令
# 安装
npm install rollup --save-dev
# 构建
rollup -c rollup.config.js
npx rollup
# 监听模式
rollup -c -w
注意事项
- Webpack 5 内置资源模块,无需
file-loader、url-loader- Rollup 默认不解析 node_modules,需
@rollup/plugin-node-resolve- Tree Shaking 需要 ES Module 语法,CommonJS 不支持
- Webpack 开发用
eval-source-map,生产用hidden-source-map
JavaScript
// CommonJS 无法 Tree Shaking
const { usedFunc, unusedFunc } = require('./utils');
// Webpack/Rollup 无法确定未使用代码,全部打包
// ES Module 可以 Tree Shaking
import { usedFunc } from './utils';
// 只打包 usedFunc,移除 unusedFunc
// 避免 side effect(副作用)阻止 Tree Shaking
// package.json 添加:
{
"sideEffects": false
}
// 或指定有副作用的文件:
{
"sideEffects": ["*.css", "./src/polyfill.js"]
}
要点总结
- Webpack:功能全面,代码分割、HMR、插件生态丰富,适合应用开发
- Rollup:输出简洁,多格式支持,Tree Shaking 原生支持,适合库开发
- Webpack 核心:Entry、Output、Loader、Plugin、Mode
- Rollup 核心:input、output(多格式)、plugins
- Tree Shaking 需要 ES Module,CommonJS 不支持
- Webpack 5 内置资源模块和更好的 Tree Shaking
- 选择:应用开发用 Webpack,库开发用 Rollup
📝 发现内容有误?点击此处直接编辑