前端工程化
聊一聊前端工程化
服务对象就是前端开发,涉及整个研发流程;通过工具、规范、流程 等系统性的解决研发中的问题,提高研发效率和质量。
- 创建项目:比如脚手架、模板、组件库
- 开发/联调:Mock工具
- 构建、测试、部署:CICD、自动化测试、CodeReview
- 质量:监控系统
前端基建可以做哪些
目的:提高研发效能,服务业务开发,更好地支撑业务发展。
基础/初期基建:脚手架、组件库
方向:
规范和文档建设
- 代码规范、git规范、流程规范
- 业务文档、技术文档、分享沉淀
脚手架
- 页面模板
联调工具
CICD
监控体系
微前端
低代码
团队建设、技术分享、技术输出
实践:
- 要识别问题,进行复盘和归类,用工程化的手段去解决
- 提高技术氛围、CR、技术分享、选择合适的人选
- 要向上获取授权,要结果导向,有数据支撑
脚手架要考虑哪些
通过命令行的交互,选择所需要的配置与集成,可快速完成初始项目的创建。
CLI(Command Line Interface)+模板
还要考虑:文件结构、http请求封装、组件库、工具方法、eslint、prettier、脚本命令、构建流程
好处:
- 快速初始化项目,减少重复工作
- 统一代码风格
- 降低上手成本,更专注于业务开发
说一下模块化方案
模块化是为了解决代码的复用和组织问题,可以说有了模块化才让前端有了工程的概念,模块化要解决两大问题 代码隔离和依赖管理,从node.js最早发布的commonjs 到浏览器端的 AMD,CMD 规范以及兼容的 UMD 规范,再到现在主流的ES Module规范。
- AMD CMD 都是为了解决浏览器端的模块化问题,区别就是代码执行时机不同,CMD是懒执行。
- UMD就是兼容CommonJS ,AMD 以及全局变量来加载模块。
- ESM是在语言标准的层面上实现了模块功能,Node.js也支持(13版本后,.mjs 或者声明 type:module),
CJS和ESM的区别:
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- CommonJS 模块的顶层
this
指向当前模块的输出module.exports
;ES6 模块之中,顶层的this
指向undefined
。 - CommonJS 模块的
require()
是同步加载模块,动态import
是异步加载,有一个独立的模块依赖的解析阶段。 - ESM生态在逐渐发展,随着 vite等工具的流行,no-bundle 也在逐渐推广,ESM取代CJS是大势所趋。
介绍一下vite 相比webpack的优缺点
- vite把自己定义为工具链,可以开箱即用,配置简单,生态也再不断完善,ESM,bundle-less 也是大势所趋。
- 基于 ESM 和 ESBuild 的Dev Server,冷启动速度快,按需编译
- webpack 兼容性好,生态完善
说一下Rollup
rollup是一款打包构建工具,通常用来构建一些库,比如Vue等都是用rollup构建的。是基于ESM的打包器,支持tree-shaking,scope hoisting等特性。 可以输出多种模块规范的代码,也有丰富的插件。Rollup 插件基本就是各种 Hook 函数的组合。
Rollup 的打包过程中,会定义一套完整的构建生命周期,从开始打包到产物输出,中途会经历一些标志性的阶段,并且在不同阶段会自动执行对应的插件钩子函数(Hook)。对 Rollup 插件来讲,最重要的部分是钩子函数,一方面它定义了插件的执行逻辑,也就是"做什么";另一方面也声明了插件的作用阶段,即"什么时候做",这与 Rollup 本身的构建生命周期息息相关。
AST和Babel
- 抽象语法树:对代码的一种抽象表示,是树形结构。
- 应用:代码高亮,JS转义,代码压缩,ESLint,Prettier等
- babel 编译 ES5 的过程:parse(解析代码生成AST)、transform(通过 traverse 遍历 AST 进行处理转换)、generator (生成代码)
包管理工具
- pnpm
- 硬链接可以避免重复安装,节省空间,速度更快
- 解决问题:幽灵依赖和分身依赖(相同依赖不同版本)
- 硬链接: 保证相同的包不会被重新新增,磁盘的目录下,inode相同,数据共享,节省内存,修改会同步更改
- 软链接(符号链接):相当于快捷方式,node_modules 里的软链接到对应的.pnpm下的依赖,解决幽灵依赖问题
- 符号链接是指向目标路径的链接,而硬链接则是指向目标数据对象的链接
- 自带monorepo
CICD
- CI:持续集成,拉代码,测试和构建,构建出成果物
- CD:
- 持续交付:将已验证的代码发布到存储库
- 持续部署:部署到生产环境
好处:流程自动化,减少人为失误,提高迭代效率。
演化过程:
- 前后端不分离,依赖后端
- 使用nginx管理前端静态文件
- 使用docker,优势:
- 部署高效,易于迁移
- 环境一致性
- 易于CICD
- 便于部署回滚
一些实践:
- 安装依赖:使用 npm ci 代替 npm i ,提升速度至少30%
- 部署优化
- springboot - tomcat
- maven - shell