本文为全栈开发学习笔记 —— webpack实现前端工程化
一、前端工程化理解
前端工程化的核心逻辑:开发者在语义化、结构化的业务文件目录下编写内容,通过解析引擎对业务文件进行分析、转换与优化,编译、打包成符合生产环境标准的产物文件。这些产物文件最终在运行时环境中,严格遵循预先定义的规则与协议,完成页面渲染、交互响应等功能。
二、工程化目标
前端工程化的目标旨在构建高效、规范且可维护的开发体系,主要涵盖以下几个方面:
1.提升开发效率与可维护性
通过建立语义化、结构化的业务文件目录,如将配置文件、组件代码、样式文件等分类存放,使开发人员能快速定位和理解代码逻辑,便于后续代码的修改与维护。
2.实现代码标准化与规范化
制定统一的代码编写规范、文件命名规则以及目录组织方式,确保团队成员的代码风格一致,提高协作效率。
3.自动化处理与构建优化
在开发、测试、生产等不同环境中,通过工程化的配置和部署流程,保证代码运行的一致性和稳定性。
4.确保多环境一致性与可靠性
通过环境分流(开发、测试、生产),支持不同环境能够按照各自的需求进行参数配置和运行。
三、解析引擎实现
解析引擎选择webpack实现,它可以将多个模块按照依赖关系进行静态分析,并生成一个或多个打包后的文件,其工作流程如下:
1.解析编译
-
依赖分析
Webpack可以分析模块之间的依赖关系,根据配置的入口文件找出所有依赖的模块
-
文件转换(即编译)
Webpack本身只能处理 JavaScript模块,但通过 加载器(Loader) 的使用,可以将其他类型的文件(如vue、css、Less、图片等)转换为有效的模块,使其能够被打包到最终的结果中。
2.模块拆分
将输出的大 js 、css等文件按规则拆分成多个小文件,为不同入口页面提供专用资源,避免资源浪费,提升性能。
3.环境分流处理
在Webpack中,可以通过配置不同的Webpack配置文件来区分开发环境和生产环境的配置。
常见做法是创建两个独立的Webpack配置文件,分别针对开发环境和生产环境配置。 开发环境的配置侧重于开发体验和调试工具,而生产环境的配置则更关注代码优化、压缩和资源的优化。具体实现:
(1)配置打包命令
(2)配置启动文件
(3)webpack配置文件
webpack.base.js— webpack基础配置:
关键处理:
- entry:动态获取app/pages目录下所有入口文件,支持多页面入口;
- rules:添加vue-loader/babel-loader/style-loader...等指定要加载解析的模块及解析方式;
- plugins:添加基础插件,用于在打包过程中注入各种各样的能力;
- splitChunks:分包策略,用于区分改动和引用频率不同的JS,使浏览器可以更高效地利用缓存机制。如JS文件通常采用如下分包策略:
(1)vendor包:用于存放第三方库代码。通常只在第三方库版本升级时才会发生变化,具有较高的稳定性;
(2)common包:用于抽取业务组件中的公共代码部分,改动频率较低;
(3)entry包:存放不同页面业务组件代码的差异化部分,更新频率较高。
对于改动较少的 vendor 包和 common 包,能够直接从缓存中读取,无需重复加载;而对于经常变动的 entry page 包,则按需更新。
注:vendor优先级要高于common,否则会把第三方包打包到common中!
webpack.dev.js— devServer配置
目标:需具备监控业务文件变化的能力,以及代码与浏览器之间的双向通知能力,实现代码保存时自动重新解析模块并通知浏览器更新页面。
实现:为方便调试和实时保存页面变化,采用热更新方案,将输出代码片段存于内存,通过 HMR 机制实现更新。具体实现参考juejin.cn/post/750411…
webpack.prod.js— 生产环境webpack配置
需求:对文件进行全面压缩,输出结果文件到指定目录;
关键处理:
- 引入HappyPack实现多线程打包js、css, 加快打包速度;
- 引入CSSMinimizerPlugin优化并压缩css资源;
- 引入TerserWeapackPlugin,使用并发和缓存,提升压缩阶段的性能;
打包命令:npm run build:dev(开发)/ npm run build:prod(生产)
四、总结
工程化工具多样,如 Webpack、Gulp、rollup 等,工具只是上层形式,要掌握工程化底层思想,以便在不同项目中进行工具选型和创新实践。
五、思考
-
多线程打包除了使用HappyPack,还有什么工具可以实现?
thread-loader (Webpack 官方推荐)
原理:将耗时的 Loader(如 Babel、TypeScript)放到 Worker 线程池中执行。
优点:
-官方维护,兼容性好;
-按需启用多线程,灵活控制资源消耗;
-适用于:针对耗时的 Loader(如 Babel)。
module.exports = {
module: {
rules: [{
test: /\.js$/,
use: [
'thread-loader', // 放在其他 Loader 之前
'babel-loader',
],
},
],
-
Vue3项目中使用Proxy,是否还需要babel-loader?
babel作用:将ES6+的代码转换成ES5、引入第三方 polyfill 模块。
-如果项目需要支持旧版本浏览器(不支持es6):需要babel转译,并引入polyfill处理Proxy;
-如果目标浏览器原生支持 ES6 和 Proxy:不需要 Babel。
注:抖音“哲玄前端”,《全栈实践课》