大前端项目代码重用也许lerna是最好的选择

43次阅读

共计 3022 个字符,预计需要花费 8 分钟才能阅读完成。

我前段时间参加了一个 react 为主的大前端我的项目,笼罩 Web、Android、Ios 三个平台。因为整个业务逻辑偏重在手机端,且 Web 端也是到了我的项目中期才开始启动,我在搭底层框架时就没有思考用相似 react-native-web 这样的框架把三端对立,而是别离以 react-nativereact为主起了两个我的项目来应答。

因为无论哪一端,调用的后端微服务集群都是同一个,导致两个我的项目中还是不可避免的呈现了一些反复逻辑,我尝试了封装成 npm 包来重用逻辑,但仅限于哪些通用且变动较少工具类代码,对于变动频繁的业务逻辑代码,封装进去的 npm 包时不时就要更新版本,且抽出到我的项目之外也不易开发和调试,用起来分外麻烦,得失相当。

最近尝试了lerna,惊喜的发现它岂但能解决过后我的项目的痛点,还能额定带来一些多项目管理相干的益处。

引入 lerna

lerna的名字来源于希腊神话中的九头蛇海德拉(Lernaean Hydra),长相可参考我的项目 logo,拿它形容多我的项目工程是再贴切不过了。

lerna的引入比设想中简略,其实,与其说引入 lerna,倒不如说是导入到lerna 更适合,因为具体的做法是通过命令行创立了一个新的 lerna 我的项目,而后把所有我的项目导入进去。而且在导入的同时,每个我的项目的 git 提交记录也都合并在了一起。

lerna init
lerna import 你本地的我的项目门路

每个被导入的我的项目都会被寄存在根门路的 packages 目录下,上面是我 demo 我的项目的截图。

应用 lerna 来治理我的项目依赖

引入 lerna 后,第一件事就是要解决装置依赖的问题,咱们须要用 lerna add 命令来代替咱们习惯的npmyarn,比如说当初给截图中的 rntest 我的项目装置 lodash,就要执行上面的命令,该命令的底层实现也还是调用哦npm install 之类的命令。

lerna add lodash --scope=rntest

不过,执行后你会发现其余我的项目中 package-lock.json 都产生了变动,让人十分困惑,这背地的起因是跟增加依赖后主动执行的装置命令 lerna bootstrap 无关。

lerna 的依赖晋升

lerna能够通过 lerna bootstrap 一行命令装置所有子项目的依赖包,而且在装置依赖时还有依赖晋升性能,所谓“依赖晋升”,就是把所有我的项目 npm 依赖文件都晋升到根目录下,这样能防止雷同依赖包在不同我的项目装置屡次。比方多个我的项目都用了 redux,通过依赖晋升,只须要下载一次放到根目录的 node_modules 目录下,就可供其余所有我的项目来应用。不过,须要额定的参数--hoist 让依赖晋升失效。

lerna bootstrap --hoist

然而主动执行 lerna bootstrap 命令是不带依赖晋升参数的,这就导致下面每个我的项目的 lock 文件都会被批改的起因。

当然,要解决这个问题也容易,能够通过 lerna 的配置来防止 npm 对 lock 文件的批改即可,写法如下:

yarn 是 lerna 的最佳搭档

lerna默认应用 npm 作为装置依赖包工具,但也能够抉择其余工具。yarn在 1.0 版本之后提供了 workspaces 的性能,该性能从更底层的中央提供了依赖晋升,做的事件跟 lerna 一模一样。把它跟 lerna 放在一起看,几乎就像是为 lerna 量身定做一样。因而,举荐在 lerna 中搭配 yarn 一起应用。

把 npm 替换成 yarn 只需在 lerna 的配置文件增加两行代码即可,配置完当前立即顺畅百倍。

高效的代码重用

在我参加的这个大前端我的项目里,多端之间代码反复的局部蕴含 redux 中的业务逻辑、http 申请的解决、代码标准工具的查看、git钩子中的自定义脚本等等。在 lerna 架构下,前两者可间接抽取到一个独立的我的项目,而后被其余我的项目援用,比方在我的 demo 中,能够像其余依赖包一样间接引入 shared 我的项目, lerna 会自动识别并把它导向外部我的项目。

import shared from 'shared'

这跟间接封装成 npm 包的一大区别就是实时更新,批改立即可见,就像在同一个我的项目一样,不影响开发和调试。

git 钩子和自定义脚本的重用

我尝试把解决 git 钩子的工具 husky 装置到了根目录,触发的事件和自定义脚本能笼罩到每个我的项目,给这部分代码重用带来了极大遍历。比方,不少我的项目会增加自定义脚本来束缚 git commit 提交时的音讯形容,在 lerna 架构下,只需写一次即可。

eslint 的重用

那些经常须要在根目录增加配置文件的第三方依赖,比方 eslintprettierbabel 等,在 lerna 中无奈简略粗犷的晋升合并到一处。因而,对于 eslint 这种前端开发已不可或缺的工具,能够尝试将所有配置项抽取到独立我的项目,而后装置第三方依赖的形式引入,相似 eslint-config-airbnbeslint-config-prettiereslint-config-google 这样。

不得不说,即使不必 lerna 框架咱们也能够这么做,只不过在 lerna 框架下批改立即可见,不便了调试和开发。

lerna 框架下的 CI/CD

多我的项目的构造无疑给 CI/CD 带来挑战,好在支流的 CI 框架能完满解决这个问题。比方在 gitlab 上,only/changes参数齐全满足了咱们的需要,让咱们能够为每一个子项目设置独自的 pipeline,比方当初咱们设置一个 pipeline,只当 rntest 我的项目下的文件被批改时才会触发:

在 lerna 框架下,所有我的项目都合在一个工程里,但 CI/CD 并不用这样。通过把脚本中的要害参数配置到 CI/CD 的我的项目内里,共用同一份 .gitlab-ci.yml 文件,从而可能实现每个子项目对应一个独立的 CI/CD 我的项目,最终 CI/CD 构造如下图:

lerna 框架下的子项目权限

因为所有的我的项目都归并到了一个 lerna 工程下,一旦有了拜访权限意味着你能够批改所有子项目中的代码,在理论的开发工作中多多少少会带来一些麻烦。比如说,开发 web 和开发 mobile 平台的是两个不同的团队,如果我作为 web 组的一员,一不小心批改了或删除了 mobile 我的项目的文件该怎么办?如果不退出任何限度,这种事件迟早会产生,我想这可能是 lerna 框架与生俱来的的痛点。

可怜的是,在 lerna 框架下,gitlab 或 github 这类第三方代码托管平台,自身的权限治理性能无奈解决这问题。但好在有其余工具的帮忙能够缓解这种痛,我尝试用来束缚开源贡献者提交 PR 标准的工具 dangerjs 来实现权限分隔,利用的信息就是以后 gitlab 账号的用户名,看起来成果还不错。

这个工具会在合并 MR 的时候,判断出我 gitlab 账号没有权限批改 rntest 子项目内的文件,因而禁止合并此 MR,并将这些信息主动增加到 MR 的评论里。当然,脚本判断的逻辑比拟简陋,仅用来做演示用,而对于 dangerjs 的局部我会另写一篇文章具体介绍。

结语

大前端我的项目将会是前端倒退的趋势,如何更好的治理大前端我的项目是每一位前端开发躲不开的课题。lerna框架通过合而为一的理念提供了一种解决方案,通过取长补短,咱们能够施展出 lerna 的最大效用。如果你还没有用过,兴许,下一个我的项目就能够试试看。

相干材料

lerna 的 github 地址

文章中的 demo

正文完
 0