工程化
什么是工程化
前端开发的管理工具
降低开发成本,提升开发效率
一定从宏观视角去分类和理解各种工程化工具
模块化和包管理
模块化
分解和聚合的思想。 分解契合的是主观规律。聚合契合的是客观规律。
问题
对于js来讲。分开各种function和分开各种文件就是分解的直观表现。
但是对于js来说分开文件存在问题。
全局污染(分解问题)
1.js有一个sort()。2.js也有一个sort()同时被 html import 就会冲突依赖混乱 (聚合问题)
html import js是需要按照顺序的。 举例
1.js有一个sort()。2.js也有一个isPrime()。假如sort()依赖isPrime(), 那么必须先引入2.js再引入1.js。 如果文件足够大,那这个依赖顺序就非常复杂了。 而且在 html 的角度,由于是按顺序引入,是无法看出来文件之间的依赖关系<body> <script src="./2.js"></script> <script src="./3.js"></script> <script src="./1.js"></script> //cannot see 1.js is depend on 2 or 3 </body>
标准
js 社区设计了很多标准来解决这个问题。
CommonJs(CJS)- node 使用的。还大量存在
CMD AMD UMD - 很少使用
官方标准 Ecmascript Module(ESM)
CJS vs ESM
| 名字 | CJS | ESM |
|---|---|---|
| 来源 | 民间 | 官方 |
| 设计方式 | 运行时 | 编译时 |
| 语言特点 | require(‘1.js’) | import xxx from ‘1.js’ |
实现
由运行环境支持。
- 浏览器 - ESM only
<script src="./2.js" type="module"></script>- node - cjs and esm
- 构建工具 - cjs and esm
- webpack both
- rollup ESM
- esbuilder ESM
包管理
包:package 一系列模块的聚合
package > file > function
问题
一个项目会有大量的package。那如何下载,升级,删除,发布,版本控制?
标准
npm
- package 属性 - package.json
- registry
- cli
pnpm vs yarn
JS 工具链
- API兼容 polyfill (corejs). 例如:没有a.flatMap. 就是写一个 Array.prototype.flatMap
- 语法兼容/语法增强 syntax transformer。例如:不认识async
语法兼容 一般只能一次处理一个问题(await/spread operator/。。。)
那我需要个工具链一次处理一个。把它串联起来。
Babel @babel/preset-env
CSS工具链
- 语法缺失(循环,判断,拼接)
- 功能缺失(颜色函数,数学函数,自定义函数)
当然在不断完善中
方法
scss/less/stylus –css预编译器–> css –后处理器-> css
postCss接受各种插件来转换css。包括(css module/autoprefixer/cssnano/purgecss)
构建工具和脚手架
构建工具
工程级别的转换
为什么要转换:可以是为了兼容性,增强,或是可维护。但本质是开发维护的代码和运行的代码不一样。因为开发需要便捷,运行只需要最纯粹的。
工程也是开发维护的工程和运行的工程不一样。
开发维护的工程 —构建工具—-> 运行时需要的工程
那我们需要解决的问题是:
- 哪种工程更适合开发和维护
- 哪种工程更适合运行
- 如何打包
没有绝对的标准
webpack, rollup, esbuild
webpack 如何解决问题的呢
- 哪种工程更适合开发和维护 —> 一切皆是模块
- 哪种工程更适合运行 —> 传统工程(html/css/js)
- 如何打包 —> 从一个入口开始,不断寻找依赖,打包合并
入口:AST + 规则(比如index/package.json 里的main/alias)
开发服务器:通过命令webpack serve
文件指纹
- express构建一个服务器(在内存打包->浏览器地址->浏览器访问->浏览器向server请求信息->server返回内存中打包结果)
- 检测源代码 源代码变化->页面刷新 (通过websocket)
脚手架
vite create-react-app
- 交互界面 cli
- 工程模版