前端工程设计范式
工程设计范式
Rails Style
-
专注于纵向的“层”的划分。
-
同一类文件放置在同一目录下。
优势:
-
便于合并导出,通过定义统一的index出口,统一导出文件。
-
便于进行“层”的扩展。
不足:
-
依赖关系难以直观地分析。
-
对功能的修改会涉及到大量的目录切换。
-
难以水平拆分,不能很好地单独拆包,发布。
Domain Style
-
专注于横向的“功能”的划分。
-
同一个feature放置在同一目录下。
优势:
-
便于水平拆分,单独分包,独立部署发布(微服务,单组件发包)。
-
便于进行“功能”的扩展,直接通过对应的cli,即可创建相同的开发目录。
不足:
- 会产生大量的重复结构。
- 难以垂直拆分,不能统一管理相同的功能模块。比如测试模块。
工程化设计范式的选择
单一功能的项目
由于不存在水平拆分的必要性,故可以选择Rails Style。比如库、三方包:fs-extra、axios等。
-
易于纵向扩展。
-
减少重复代码。
聚合功能型项目
纵向分层少,极易横向扩展—故选择Domain Style。比如组件池、utils:ant-design,element-plus,lodash等。
-
易于添加新feature。
-
便于横向拆分。
业务工程项目
既有大量的垂直分层,又有大量的feature聚合,所以选择 Rails Style + Domain Style。
大型项目工程管理方式
multi-repo
把每个项目都分别用git托管。
大多数工程,其实都是以multi-repo方式管理的。
优势: 可以让各项目团队根据需要定制更适合自己的workflow。
不足:
- 难以对所有项目统一进行操作(git checkout / npm publish / npm run build...)
- 难以追踪依赖关系。
multi-repo管理
git submodule
- git提供的一种管理子仓库的方案。
- 可以批量管理和维护多个git repo。
- 本质上是一个父repo维护了一份各个子repo的清单。
mono-repo
统一用一个git
仓库管理所有的项目。
下面是通过lerna创建的mono-repo目录。
优势:
- 方便统一地操作各个项目。
- 利用工具,可以方便地追踪项目间的依赖关系。
不足:
- 代码仓库随着业务发展会非常巨大。
- 失去了部分的灵活性。(workflow必须统一)
- 强制依赖moo-repo的管理工具。
mono-repo管理
lerna,为js生态下的mono-repo管理提供一站式的解决方案。解决mono-repo下的依赖管理,版本管理,开发提效,工作流等等。
目录结构
- 更替作为一个git仓库,也是一个npm包(私有)
- lerna.json是整个mono-repo的配置文件。
- 每个真正的项目平铺在packages中。
- 整个项目可以统一管理所有依赖。(也可以分别管理)
Lerna 管理模式
lerna 管理项目可以使用两种模式,默认固定模式,当使用 lerna init -i
命令初始化项目时,此时为独立模式。(模式是用来管理多个 package 发包时的方式)
- 固定模式(默认模式): 在发包时会检测 packages 下涉及到变更的包,给这些变更的包使用同一版本,未发生变更的包不应用改变版本,且不做发布升级;发布时可通过 lerna publish major(大) | minor(中) | patch (小)自定义版本。如果每个项目有依赖,那么发布一个项目包,其他的项目的版本也会跟着变动。
- 独立模式(常用的模式): 允许每个包有自己独立的版本号,在
lerna publish
发布时,需要为每个改动的库指定版本号(逐个询问需要升级的版本号)。此模式,lerna.json
中的version
字段指定为independent
。
在固定模式中,如果 packages 下,其中一个包发生改动,另一个包依赖了这个包,即使它没有发生改动,也会被进行发布更新。
一个案例
一些命令
安装lerna。npm install lerna -g
初始化lerna工程结构。 lerna init
创建工程包,创建在packages目录下。 lerna create <pro-name>
增加本地或者远程package
做为当前项目packages
里面的依赖。 lerna add <pro-name> packages/<pro-name>
。通过软连接方式,将项目连接到对应的项目下的node_modules中。
// 将pro-1工程作为pro-2的一个依赖项
lerna add pro-1 packages/pro-2
// or
lerna add pro-1 --scope=pro-2
如果想要给每个包都安装同一个库,那么直接使用add就可,不需要指定作用域。他会在packages下的每个package.json中添加对应的依赖项版本号。
lerna add axios
将项目间相同的依赖添加到根目录的node_modules中。lerna bootstrap --hoist
。--hoist
:依赖提升,把每个 package 下的依赖包都提升
到工程根目录(删除包下的 node_modules,将依赖安装在根目录,但依赖注册不会在 package/package.json 内删除,也不会在 root/package.json 内添加此依赖)
清除项目中的node_modules。 lerna clean
将该项目发布到npm上。 lerna publish
这里有一个小知识,每个工具的配置文件配置项都会很多,我们很多时候不是很清楚,我们可以设置$schema
字段,让他指向一个json配置文件的解释文件。这样就有提示每个字段的作用和描述了。可以在这个网站中查找
比如lerna
// lerna.json
{
"$schema": "http://json.schemastore.org/lerna",
"useWorkspaces": true,
"npmClient": "yarn",
"version": "0.0.0"
}
lerna exec <cmdname>
,在每个包中执行任意命令。他可以执行package.json中事先未定义的命令。
lerna run <cmdname>
,在每个包含该脚本的包中运行一个 NPM 脚本命令。
lerna配置文件
主要是version、npm*、command、packages
几个配置。
command 可以指定lerna命令的一些参数配置。
npmClient 指定lerna底层调用的包管理器。默认是npm。
version 决定lerna管理多个包的模式。fixed,independent。
pacakges 表示项目的路径。
参考
转载自:https://juejin.cn/post/7239515356523937849