对前端工程化的理解
能够提升开发效率,保证代码质量,降低沟通成本,提升性能的工作都算是工程化的范畴
比如说
- 模块化开发
- 组件化开发
- 包管理
- 代码规范,代码提交规范,接口规范降低沟通成本
- 多线程打包提高打包速度,分包处理,开发服务器热更新,代码压缩
- 自动化工具链
- 等等
前端工程化的一般配置
-
基本配置
- 入口配置
- 模块配置 - 决定要解析哪些模块以及用何种方式解析
- 产物输出路径
-
优化配置
-
插件配置
-
打包输出优化
- 代码分割
- 模块合并
- TreeShaing
- 压缩
- ...
-
多页面打包
-
单页面打包过程
- 读取入口文件,分析依赖
- 解析引擎编译
- 使用模板文件注入代码块生成最终产物(服务端渲染)
- 输出到产物出口路径
-
多页面打包的额外处理
- 动态构建入口文件对象并将代码块注入到相应的模板中
- 每个模板对应一个页面
- 每个页面都是一个单页面应用,通过前端路由跳转
多页面与单页面的区别
- 多页面每个页面都需要请求服务器获取完整的 html 完成渲染,由服务端生成页面,页面与 url 相对应
- 单页面只有一个 html 文件,首次加载所有资源。前端路由监听 url 变化动态渲染组件,数据通过 http 请求异步获取
- 该框架结合多页面与单页面。多页面由 BFF 层控制,每个 page 是一个单独的页面(SSR),而每个 page 都是一个单页面应用,由前端路由控制(CSR)
多线程打包
利用多核 cpu 的能力分解打包过程,打包完成后进行合并,从而提升构建速度
实施方案
-
thread-loader(首选)将
thread-loader置于其他 Loader 之前,后续 Loader 会在子线程池中并行执行 -
HappyPack兼容性较差,仅支持部分 loader,社区已不再维护
-
其他多线程打包方案
针对具体项目,分析优劣,选用更适合的多线程打包方案
选择
- 文件数量多,依赖复杂的大型项目适合使用,小型项目效果不大
- 线程数设置为 cpu 核心数,充分利用 cpu 资源
- 启用缓存,进一步提升构建速度
分包策略
为什么要进行分包
-
不进行分包
- 包体积会很大,影响资源加载速度,并且多个页面引入相同代码,有代码冗余,导致系统性能降低
-
分包的好处
- 减少包的体积,对重复代码进行拆分加以复用,配合浏览器缓存策略提升加载性能
-
分包策略
- 按照代码改动频率进行分包,将高频改动的业务组件代码的差异部分和相对稳定的业务组件的公共部分、长期稳定的第三方库分离开来。分离后,公共代码和第三方库利用浏览器缓存,高频改动代码独立重新加载,不影响其他缓存资源
- vendor 包。第三方库 node_modules 拆分为一个独立的包,这部分代码基本不会改动,除非版本依赖升级
- common 包。抽取业务组件的公共代码,这部分代码相对稳定,改动较少
- 其他分包策略 - 根据项目具体情况而定
-
注意进行代码拆分的优先级 - 构建工具会按照配置的优先级进行拆分,如果拆分顺序设置不当,代码拆分不会达到预期结果
热更新
利用开发服务器的监控能力和通知能力实现热更新
- 解析引擎解析业务文件为产物文件后,通过 koa 服务渲染模板文件到浏览器 - 注入 HMR 模块
- js, css 等资源通过访问开发环境服务器获取
- 监控业务文件改动,保存改动时重新编译业务文件
- 热更新模块通知浏览器重新加载资源
环境分流
开发环境进行开发,联调的时候,通过定位代码,代码热更新等手段提升开发效率
要跟生产环境区分
方案
-
定义基本配置,然后通过 webpack merge 分别合并开发环境和生产环境的配置,达到环境分流的目的
-
共同配置
-
动态构建入口文件并注入对应代码块
-
模块解析基本配置,模块解析的具体行为控制
-
分包策略
-
必备插件
- VueLoaderPlugin
- 全局暴露第三方库
- 定义全局常量
-
-
生产环境
- 指定生产环境
- 生产环境 output
- 多线程打包
- 提取 css 公共资源,提升缓存利用率
- css 资源优化压缩
- 使用 TerserPlugin 的并发和缓存,提升压缩阶段的性能
-
开发环境
-
指定开发环境
-
开发环境 output ,指定外部资源公共路径(热更新)
-
第三方包不作为 hmr 入口
-
sourcemap 呈现代码的映射关系,便于在开发过程中调试代码
-
hmr 插件
-
启动开发服务器
- 分配更多的内存提升开发服务器的性能
- 指定静态文件目录
- 落地模板文件
- headers 配置解决跨域问题
- hotMiddleware 中间件实现 hmr
-
其他优化
-
配置模块解析的具体行为 - resolve
-
extensions 扩展名自动补全
- 遗漏扩展名时导致加载失败,扩展名补全避免了这种情况的发生
-
alias 路径别名
- 定义常用文件目录路径(可能很长,容易写错)的简短别名,语义明确,提升开发效率
- 目录结构调整时,只需修改 alias 配置,无需全局替换路径
- 直接映射绝对路径,减少路径解析的递归查询,提升编译性能
-