工程化
1 Webpack 深入
Webpack 五大概念与构建流程
构建流程:1. 初始化参数(合并配置)→ 2. 开始编译(初始化 Compiler,加载插件)→ 3. 确定入口 → 4. 编译模块(Loader 翻译,递归依赖)→ 5. 完成模块编译(得到依赖图)→ 6. 输出资源(组装 Chunk,生成文件)→ 7. 输出完成(写入文件系统)。
生产环境构建优化
多线程/多进程:thread-loader、TerserPlugin 的 parallel 选项。
代码分割:SplitChunksPlugin 将应用拆成多个 bundle。
缓存:cache: { type: 'filesystem' }、babel-loader 的 cacheDirectory。
压缩:TerserPlugin 压缩 JS,css-minimizer-webpack-plugin 压缩 CSS,开启 cache 和 parallel。
Tree Shaking:ES6 模块 + optimization.usedExports,移除未使用代码。
其他:resolve.alias、resolve.extensions 减少查找范围;DllPlugin 预编译第三方库;stats: 'errors-only'。
开发环境构建优化
cache: { type: 'filesystem' };devtool: 'cheap-module-source-map';watchOptions.ignored: /node_modules/;loader 的 include/exclude;thread-loader;resolve.modules、alias、extensions;optimization.minimize: false。
2 Plugin 与 Loader
Plugin 实现原理:Tapable 钩子
class MyPlugin {
apply(compiler) {
compiler.hooks.done.tap('MyPlugin', (stats) => {
console.log('编译完成!', stats.endTime - stats.startTime, 'ms');
});
}
}
常用钩子:compile(编译开始前)、compilation(创建编译对象)、emit(生成文件前)、done(编译完成)。
Loader 链式处理与常用 Loader
Loader 链式操作:一个文件经多个 Loader 处理,前一个输出作为后一个输入。例如 LESS:less-loader → CSS → css-loader → JS 模块 → style-loader → 注入 DOM。最终产物是 JS 模块,运行时创建 style 标签。
常用:babel-loader、style-loader、css-loader、less-loader、sass-loader、file-loader、url-loader。
自定义 Loader 与 Plugin 示例
// 清除 console 的 loader
module.exports = function(source) {
return source.replace(/console\.log\(.*\);?/g, '');
};
// 简单 Plugin
class NotifyPlugin {
apply(compiler) {
compiler.hooks.done.tap('NotifyPlugin', () => console.log('Build done!'));
}
}
3 SplitChunks 配置
splitChunks 详细配置
splitChunks: {
chunks: 'all',
minSize: 20000,
maxSize: 70000,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
automaticNameDelimiter: '-',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
priority: -10,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
}
reuseExistingChunk 与 chunk/bundle/module 区分
reuseExistingChunk:若已有 Chunk 符合条件,复用而非新建。lodash 等公共依赖仍会被提取为独立 Bundle,A、B 页面共享引用。
Module:构建单元,通常一个源文件。Loader 处理后转为 Webpack 可管理格式。
Chunk:模块的集合,由 Webpack 根据依赖和配置分组。可包含多模块,或动态导入的单一模块。
Bundle:最终输出文件,由一个或多个 Chunk 打包而成。Tree Shaking 以 Module 为单位优化,Chunk 是代码分割的基本单位。
4 微前端
90+ 应用聚合方案与微前端通信
90+ 应用聚合:通过微前端框架(如 qiankun、single-spa)将多个子应用插到基座应用中。
通信方式:URL 参数;自定义事件;全局状态(Redux/Zustand);localStorage/sessionStorage;发布-订阅;Module Federation 共享模块;qiankun 的 props 机制。优先松耦合方式。
iframe vs qiankun vs Module Federation
iframe:各微应用独立运行,隔离性强,但用户体验和性能较差,通信复杂。
qiankun / single-spa:通过 JS 沙箱、样式隔离管理子应用,支持多技术栈,通信通过 props 或全局事件。适合 SPA 聚合。
Module Federation:Webpack 5 特性,应用间直接共享模块(组件、库),动态加载。适合组件和库共享,实现微前端时应用间可互相引用模块。
5 低代码
amis / dataseed 方案与低代码平台设计
常用手段:页面模板、组件库、表单/表格配置化、辅助函数。问题:辅助函数是黑盒,可能嵌套多层,样式难解耦,不便修改和调试。
改进方向:解耦型低代码框架,将逻辑、样式、配置分离,便于维护和扩展。