# 什么是前端工程化
随着 npm 及 webpack 的问世,前端的开发方式发生了天翻地覆的变化,生产力大幅提高。而生产力得以提高的一切措施都可称之为前端工程化。
随着工程化的发展,前端开发的以下界限渐渐明晰起来,我把它总结为四个方面。相互促进,相互发展。
- 构建
- 开发
- 测试
- 部署
由于涉及到方方面面,这里总结一个大纲。
- 编译原理
- 操作系统
- 数据结构
- 网络编程
# 构建
前端构建由以前的 CDN + Server Template
的方式对前端进行构建,甚至直接引用 CDN 无构建,比如一六年之前各种各样关于 jquery 的 CDN。
而目前流行的方式是使用 webpack(rollup) 打包成一个 bundle 进行构建。
而未来的趋势是 bundleless,如 vite 和 snowpack(2w+ 颗星星,最近已弃坑)。
- CDN + Template 方式往往前后端一起开发而显得很分裂,后端的模板引擎有
jinja2
、django template
等,及 Node 开始兴起时的ejs
、jade
(pug) 等。此时的前端更像是后端的附属。由此引发出前后端分离,以 ajax 请求数据作为二者桥梁。前后端可独立部署。 - Javascript 全局变量如何避免命名冲突,大项目中的 JS 如何控制脚本依赖。由此引发出 JS 的模块化:
amd
、cjs
、umd
、esm
,开发的 package 往往会打多个格式出来,如同时支持 esm(module) 与 cjs(main) - 模块化后有依赖关系的 JS 如何工作。由此引发了构建工具的发展,如以 cjs/es 为基础的 webpack 等(rollup),找出所有模块的依赖图,将其打包成一个大 bundle
- 如何更好地利用 HTTP 缓存。由此引发了构建工具并持续改进它的永久缓存功能
- 把所有模块打成一个超级大包并计算 hash (利用永久缓存)
- 根据模块使用频繁度分包 (改进永久缓存的失效算法,避免一行代码的更新造成了整个 bundle 的失效)
- 改进 hash 算法 (避免因变量名改变及增减备注造成永久缓存失效)
- 模块联邦 (永久缓存可放入云端使多项目共享)
- 如何更好的减小 JS 打包体积。由此引出了用以减小体积的各种构建工具及方案
- 如何更好地压缩混淆 (uglifyjs、terser 与 swc)
- 编译器预计算 (prepack、uglify)
- 得益于 ESM 的 Tree Shaking (解析深度依赖的 Tree Shaking)
- 更先进的浏览器支持,往往需要的代码更少,如 CSS 不需要厂商前缀,ES 代码量更少,不需要 poyfill。(browserlist -> @babel/preset-env -> postcss-preset-env )
- CSS 选择器如何避免命名冲突,如何更好地维护 CSS。由此引发出多个 CSS 的方法论,如 OOCSS、BEM 等,及构建工具的自动化处理。由此引发出多种方案
- CSS Module: 把你的选择器打包成 带 hash 选择器
- 以及更简单的 CSS Scope: 给该模块的每一个元素带上一个随机属性/类名
- CSS 如何建立更好的逻辑性,如根据几个变量的改变设置多套皮肤,而非处处手写同一个 RGB 造成维护。由此引发出静态编译的
Sass
、Less
等,及最新的标准:可与 JS 交互的CSS Variable
,拥有了运行时的能力 - CSS 浏览器厂商前缀处理。得益于 postcss 插件生态的
autoprefixer
- 等等...
- 最后发现,不打包竟然也可以?依赖于
script="module"
# 开发
- CDN + Template 的开发方式,此时还是依赖于后端的发展模式,甚至需要熟知后端的模板语法,而模板引擎自然也是依赖于后端模板。此时使用
- 前后端
- React/Vue/Angular 的
UI = f(State)
公式