webpack-common
v2.1.0
Published
webpack 前端构建工具
Readme
webpack-common
让 webpack 拥有 Vite 级别的开发体验 —— 零配置、可扩展、即插即用。
webpack-common 是一个面向生产环境的 webpack 配置封装库。它将 Vite 的开发者体验引入 webpack 生态,提供零配置启动、Vite 风格的 API 和构建输出,同时保留 webpack 的完整生态兼容性。
目录
特性
开发体验
- React Refresh:开发模式自动启用 Fast Refresh,保留组件状态
- 错误覆盖:编译错误实时显示在浏览器 overlay 中
- 开发日志:启动时打印 Local / Network URL,支持 HTTPS 和
0.0.0.0 - Lazy Compilation:可选的按需编译模式(
server.lazyCompilation: true),加速大型项目首次启动
构建输出
- Vite 风格报告:gzip 大小、文件类型彩色高亮、超大文件
⚠警告 - Contenthash 命名:自动文件指纹,长效缓存友好
- 文件系统缓存:基于配置版本自动失效,增量构建极快
CSS 与资源
- CSS Modules:
.module.css自动启用,camelCase 导出 - PostCSS:自动检测
postcss.config.js,无配置文件时使用内置插件(autoprefixer、normalize) - 预处理器:Less、Sass 开箱即用,支持
css.preprocessorOptions深度配置 - 资源策略:统一 asset 处理,
assetsInlineLimit内联阈值,assetsInclude自定义资源类型
生态兼容
tsconfig.jsonpaths 集成:自动读取compilerOptions.paths生成别名postcss.config.js自动检测:存在配置文件时自动加载,不再被内置插件覆盖- Monorepo dedupe:默认去重
react/react-dom,避免 Hooks 失效;支持dedupe自定义 - 自定义模式:
--mode staging加载.env.staging,不再局限于 dev/prod 二选一
Vite API 对齐
defineConfig(同步/异步/函数形式)、loadEnv、import.meta.envalias、define、publicDir、server、extensionsbuild.target/minify/cssCodeSplit/watch/chunkSizeWarningLimit/terserOptions/manualChunks
工程扩展
- 多页面:
pages配置多入口 + 多 HTML - 库模式:
build.lib支持 UMD / ESM / CJS 多格式输出,自动 external peerDependencies - Module Federation:webpack 5 内置,
federation一键配置 - Bundle Analyzer:
analyze选项按需启用 - Vue / Svelte:可选框架支持
双格式发布
同时提供 ESM(dist/index.mjs)与 CJS(dist/index.cjs),兼容所有项目类型。
安装
npm i webpack-common -DNode.js >= 18,webpack 5+
快速开始
CommonJS(webpack.config.js)
const { defineConfig } = require('webpack-common');
module.exports = defineConfig({
server: { port: 3000, open: true },
});ESM(webpack.config.mjs)
import { defineConfig, loadEnv } from 'webpack-common';
export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, ['APP_']);
return {
env,
server: { port: 3000, open: true },
build: command === 'build' ? { target: 'es2020' } : {},
};
});配置项
| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| base | string | "/" | 公共路径,支持绝对路径、"./"、"auto"、HTTPS URL |
| outputDir | string | "dist" | 构建输出目录 |
| assetsDir | string | "assets" | 静态资源子目录 |
| publicDir | string \| false | "public" | 静态文件目录(同 Vite publicDir),false 禁用 |
| sourcemap | boolean \| "inline" \| "hidden" | false | 生产 source map 模式 |
| envPrefix | string \| string[] | "APP_" | 注入 process.env 的变量前缀 |
| envDir | string | cwd() | .env 文件查找目录 |
| assetsInlineLimit | number | 4096 | 图片内联阈值(字节),超过则输出为文件 |
| assetsInclude | string \| RegExp \| string[] | - | 额外识别为静态资源的文件类型(如 .gltf) |
| reactRefresh | boolean | true | 开发模式启用 React HMR(Vue/Svelte 时自动关闭) |
| css | CSSOptions | {} | CSS 相关配置 |
| alias | object \| array | - | 手动路径别名,与 @ 自动别名和 tsconfig paths 合并 |
| define | object | - | 全局常量替换(同 Vite define) |
| extensions | string[] | - | 额外的文件扩展名(追加到默认列表后) |
| json | { stringify?: boolean } | - | stringify: true 时 import json 返回字符串 |
| dedupe | string[] | - | 强制去重的依赖列表(monorepo 支持),默认去重 react/react-dom |
| ignoreMomentLocales | boolean | true | 是否忽略 moment.js locale 文件,false 可恢复 |
| server | ServerShortcuts | - | DevServer 便捷配置 |
| proxy | object | - | DevServer 代理配置 |
| build | BuildOptions | - | 构建选项 |
| pages | object \| array | - | 多页面配置 |
| vue | boolean \| object | - | Vue SFC 支持(需安装 vue-loader) |
| svelte | boolean \| object | - | Svelte 支持(需安装 svelte-loader) |
| analyze | boolean \| object | - | 打包分析(需安装 webpack-bundle-analyzer) |
| federation | object | - | Module Federation 配置 |
| presets | array | - | Vite 风格 preset 数组,每个返回部分 webpack 配置并依次合并 |
BuildOptions
| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| lib | LibBuildOptions | - | 库构建模式(见库模式) |
| target | string | "es2020" | SWC 编译目标(jsc.target),如 "es2015"、"es2020"、"es2022" |
| minify | boolean \| "terser" \| "esbuild" | true | 是否压缩。"esbuild" 已废弃(回退 Terser 并警告) |
| terserOptions | object | - | 自定义 Terser 配置(与默认配置合并) |
| cssMinify | "css-minimizer" \| false | "css-minimizer" | CSS 压缩器,false 禁用 |
| cssCodeSplit | boolean | true | true 提取 CSS 到独立文件;false 内联到 JS |
| chunkSizeWarningLimit | number | 500 | 块体积警告阈值(KB),0 关闭 |
| manualChunks | function | - | 自定义 chunk 分割策略(同 webpack splitChunks.manualChunks) |
| emptyOutDir | boolean | true | 构建前是否清空输出目录 |
| watch | boolean | false | 开启 webpack watch 增量构建 |
| externals | object | - | 手动 externals(与自动 peerDependencies external 合并) |
| externalPeerDeps | boolean | true | 自动将 peerDependencies 设为 external(仅 lib 模式) |
CSSOptions
| 选项 | 类型 | 说明 |
|------|------|------|
| modules | object \| false | CSS Modules 配置;false 全局禁用 |
| postcss | string \| object | PostCSS 配置。不设置时自动检测 postcss.config.js |
| preprocessorOptions | object | 预处理器选项,键名 less 或 scss/sass |
| devSourcemap | boolean | 开发时启用 CSS source map |
ServerShortcuts
| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| port | number | - | DevServer 端口 |
| host | string | - | 监听主机 |
| open | boolean \| string | - | 启动后自动打开浏览器 |
| https | boolean | - | 启用 HTTPS |
| allowedHosts | "all" \| "auto" \| string[] | "all" | 允许的主机列表 |
| cors | boolean \| Record<string, string> | true | CORS 配置,false 禁用,对象则自定义 headers |
| lazyCompilation | boolean | false | 启用按需编译,加速大型项目 dev 启动 |
import.meta.env
构建时自动注入以下变量,Vite 项目迁移无需修改源码:
import.meta.env.MODE // 'development' | 'production' | 自定义模式
import.meta.env.DEV // boolean — 开发模式 true
import.meta.env.PROD // boolean — 生产模式 true
import.meta.env.BASE_URL // 归一化后的 base 路径
import.meta.env.SSR // false
import.meta.env.APP_* // 来自 .env 文件(由 envPrefix 过滤)process.env 同步注入,process.env.NODE_ENV 始终可用。
环境变量
自动加载以下文件(优先级从高到低):
.env.[mode].local > .env.[mode] > .env.local > .envmode 默认为 development(serve)或 production(build),可通过 --mode 指定自定义模式(如 staging)。
仅注入以 envPrefix 为前缀的键到 process.env 和 import.meta.env,NODE_ENV 始终注入。
import { loadEnv } from 'webpack-common';
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, ['APP_', 'VITE_']);
return {
env,
define: {
__API_URL__: JSON.stringify(env.APP_API_URL || 'http://localhost:3000'),
},
};
});.env 文件示例
# .env
APP_TITLE=My App
# .env.development
APP_API_URL=http://localhost:8080/api
# .env.staging (--mode staging)
APP_API_URL=https://staging-api.example.com
# .env.production
APP_API_URL=https://api.example.com路径与别名
自动 @ 别名
src/ 下的每个直接子目录自动生成别名:
src/ -> @
src/utils/ -> @utils
src/components/ -> @components
src/hooks/ -> @hookstsconfig.json paths 集成
自动读取 tsconfig.json 的 compilerOptions.paths,转换为 webpack alias。例如:
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"]
}
}
}等价于 alias: { "@": "src", "@components": "src/components" }。
手动别名
通过 alias 选项覆盖或扩充,优先级:手动别名 > tsconfig paths > 自动 @ 别名。
export default defineConfig({
alias: {
'@utils': 'src/utils',
mylib: 'node_modules/mylib',
},
});base 路径
export default defineConfig({
base: '/app/', // 绝对路径(部署到子目录)
// base: './', // 相对路径(Electron / 离线场景)
// base: 'auto', // webpack 自动计算
// base: 'https://cdn.example.com/v2/', // CDN 地址
});多页面
export default defineConfig({
pages: [
{ name: 'main', entry: 'src/main.tsx', html: { template: 'index.html' } },
{ name: 'admin', entry: 'src/admin.tsx', html: { filename: 'admin.html' } },
],
});也支持对象格式:
export default defineConfig({
pages: {
main: 'src/main.tsx',
admin: { entry: 'src/admin.tsx', template: 'public/admin.html', filename: 'admin.html' },
},
});库模式
export default defineConfig({
build: {
lib: {
entry: 'src/index.ts',
name: 'MyLib', // UMD 全局变量名
formats: ['umd', 'esm', 'cjs'],
fileName: 'my-lib', // 或 (format) => `my-lib.${format}`
},
externalPeerDeps: true, // 自动 external peerDependencies
externals: { react: 'React', 'react-dom': 'ReactDOM' },
},
});输出格式:
umd→my-lib.js(含globalObject: 'globalThis')esm→my-lib.mjs(启用experiments.outputModule)cjs→my-lib.cjs
多格式构建时返回配置数组,webpack CLI 逐一独立构建。
CleanWebpackPlugin自动排除,不会互相删除产物。
框架支持
Vue
npm i vue-loader vue -Dexport default defineConfig({
vue: true,
// 或传入 vue-loader options
// vue: { hotReload: true, transformAssetUrls: { img: 'src' } }
});Svelte
npm i svelte-loader svelte -Dexport default defineConfig({
svelte: true,
// 或传入 svelte-loader options
// svelte: { emitCss: true, preprocess: require('svelte-preprocess')() }
});启用 Vue 或 Svelte 时,React Refresh 自动关闭。
Module Federation
webpack 5 内置,无需额外安装:
// 宿主应用(Host)
export default defineConfig({
federation: {
name: 'host',
remotes: { app1: 'app1@http://localhost:3001/remoteEntry.js' },
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
},
},
});
// 远程应用(Remote)
export default defineConfig({
federation: {
name: 'app1',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/components/Button',
'./utils': './src/utils/index',
},
shared: { react: { singleton: true } },
},
});打包分析
npm i webpack-bundle-analyzer -Dexport default defineConfig({
analyze: !!process.env.ANALYZE,
// 或自定义参数
// analyze: { analyzerMode: 'static', reportFilename: 'report.html', openAnalyzer: false },
});ANALYZE=true npx webpack build构建输出
生产构建自动输出 Vite 风格报告:
✓ 67 modules transformed.
computing gzip size...
dist/index.html 0.45 kB │ gzip: 0.28 kB
dist/assets/179.8ad6fc18.js 140.81 kB │ gzip: 45.21 kB
dist/assets/main.3e5055c1.js 1.53 kB │ gzip: 0.66 kB
dist/assets/main.47965963.css 0.64 kB │ gzip: 0.36 kB
dist/assets/react.f4beffb2..svg 3.74 kB │ gzip: 1.85 kB
✓ built in 2321ms文件名按类型着色:.js 青色、.css 紫色、.html 绿色、图片黄色、字体蓝色。超过 chunkSizeWarningLimit(默认 500 KB)的文件以粗体黄色显示并附 ⚠ 警告。
开发服务器日志
➜ Local: http://localhost:3000/
➜ Network: http://192.168.1.100:3000/支持 HTTPS、0.0.0.0 监听、CDN base 路径。重新编译后仅在 host/port/base 变化或错误恢复时重新打印。
TypeScript 支持
ImportMetaEnv 类型声明
import.meta.env 提供了 ImportMetaEnv 接口,在项目的 env.d.ts 中引用即可获得类型提示:
/// <reference types="webpack-common/env" />
// 或手动扩展 ImportMeta
interface ImportMeta {
readonly env: ImportMetaEnv
}默认 resolve.extensions
.js .jsx .ts .tsx .mjs .json .vue .svelte通过 extensions 选项追加:
export default defineConfig({
extensions: ['.mdx', '.graphql'],
});迁移指南
从 v2.0.x 升级
v2.1 向后兼容,绝大多数项目无需修改配置。以下为行为变更说明:
| 变更 | 影响 | 处理方式 |
|------|------|---------|
| Terser ecma 从 5 改为跟随 build.target | 产出代码语法可能从 ES5 变为 ES2020 | 需要 ES5 产出时设 build.target: 'es5' |
| postcss.config.js 自动检测 | 有配置文件的项目行为更正确(之前被忽略) | 如需使用内置插件,删除 postcss.config.js |
| tsconfig.json paths 自动集成 | 有 paths 配置的项目自动获得别名 | 可通过 alias 覆盖 |
| splitChunks.maxSize: 244KB | 大 chunk 自动拆分 | 可通过 optimization.splitChunks 覆盖 |
从 Vite 迁移
- 将
vite.config.ts中的选项映射到defineConfig(大部分选项名称一致) import.meta.env.*无需改动,自动注入loadEnv函数签名一致- 插件系统不同:Vite plugins 需适配为 webpack presets
兼容性
- Node.js >= 18
- webpack 5
- 浏览器:默认 target 为
web,SWC 编译目标es2020 - ESM/CJS:同时提供
dist/index.mjs与dist/index.cjs
示例
demo/— CommonJS 项目示例(React + TypeScript,单页面)demo-esm/— ESM 项目示例(React + TypeScript,多页面,函数形式defineConfig)
运行前需在根目录执行 npm install,再 cd demo && npm run start。
