Jonathan Saring 原作,授权 New Frontend 翻译。

如安在选用多个库房、monorepo、微服务的项目间复用代码,关于这个话题的讨论最近越来越多。

跨项目、跨库房复用代码是达到更好的模块化、更快开发的要害W O A : c w P因素,但也很杂乱。我以前根据咱们团队的经历写过一篇文章。

本文盘点了跨项目复用前端代码的 5 种方法。别忘了,] 8 q p 9 ~代码复用归根到底是一个关于人际沟通的文明问题,最重要的是不忘模块化这一初心。

1. Bit

Bit(GitHub)是一个流行的 JS 东西,一起办理代, [ B Z码改变和组件依靠,让团队内部跨项目复用代码更便利。

Bit 支撑在多个库房间别离和复用代码,一致控制改变,因而有利于在团队内部增进代码复用,削减代码复用的额外负担。

Bit 支撑无缝别离s % ( I z、复用任何库房中的模块,主动定义相应的环境和依靠树。无z v U Z Q e 4 V ;需重构,立刻发布来自恣意库房的组件。

跨项目复用前端代码的 5 种方法

发布组件之后,可以经过 npm/yarn 在其他项目中装置组件,也可以在其他项目中直接基于 Bit 导入、修正代码。改变代码后,可以经过 Bn 7 S xit 更新版别、兼并改变。

Bit 既是一个开4 s S H ` ; T e 6源项目,也是一个组件渠道% } o r +,协助团队将可复用的代码单元转换为共用组件。

跨项目复用前端代码的 5 种方法

BB p o ! (it(bit.dev)也提供了发现、协作的渠道,支撑安排、测验、构建、烘托等功能。

跨项目复用前端代码的 5 种方法

下面是一个比方:一个 React 项^ s W目用到的组件。

跨项目复用前端代码的 5 种方法

2. NPM with / withoutR p = ( Lerna

跨项目复用前端代码的 5 种方法

npm 是 JavaScript 生态– 9 t F ? e G 7 t的一大亮点,经过复用模块和库敞开了复用代码和协作开发的大门。虽然人们对这一生态系统多有抱怨o q ^ Y,却无法幻想没有 npm 的日$ ? , % 8子该怎么过。

你八成已经对 npm 有所了解,因而这里重点讨论 npm 的一些约束以及相应的应对办法。开端行动之前进行明智的决议计划能为以后省下时刻。

跨项目复用前端代码的 5 种方法

首先,为多个软件包配置和保护多个库房可能很困Z q a } g 2 j % F难。
所以有些项! u #目选用「多软件包库房」(也叫 mono) e I = W I 9 ^r5 $ w yepo)。
Bit、Lerna(详见下文)之类的东西可以协助咱们将项目转换为多软件包库房。
你可以浏览这篇文章了解详情。

这也导致许多团队分发多个小组件时选用了公共库方案I ) E ] B,由于每个小组件发布一个软件包比较麻烦。

其次,运用其他人发布的库约束了你改动的才能,通常你需求给软件包的库房提一个 pull request。像 Bit 这样的东西可以让你引进c * P恣意库房的组件,修正后发d { ( $ r 1 /布新版别,然后缓解这一问题。

P ] h 5 z r )三,项目扩张时存在可发现性问题。在许多细碎的软件包中寻觅、挑选组件很困难,常常需求访问许多 wik_ 7 5 – | g +i 站点和长篇文档。正如 Rollup 作者 Rich Harris 所说:

为了缓解在 npm 中寻觅需求的包这一难题,人们写下了许多博客文章(划掉,创建了许多完好网站)……

L 7 z V z ;需求自行评估软件库:写了测验吗?代码易于了解吗?保护是否活跃?文档易于查找和参阅吗?

Lerna

跨项目复用前端代码的 5 种方法

不同的包放不同的库房,这样做很d ) = i 3 v快就会超出掌控范围,P Y ( x : U很难在项目3 # T ) – M + % P间更新改变。

Lerna可以协助你在单个库房h h h z b中办理、配置多个软件包,一致构建和测验流程,然后削减不同的包放不同的库房带来的麻烦。这样你就不用为不同的软件 m ` 2 ^ w ! u ;包配置、保护不同g j A 6 B Q的库房了。

可以参阅下面这篇文章了解更多关} F E a于 monorepo 的信息:Monorepos MaZ a Dde Simpler

3. 公共库

公共库的优势在于可以把一切需求复用的代码放在一个库房里,这样比选用多个小软件包更容易保护和分发。和 Lerna monorepo 的差异在于,公共库会作为一个& y [ T软件包运用。

把一切需求复用的代码放在一个库O F m o !房里有一个问题,运用时需求将整个公共库引进项目,会引进冗余的代码、依靠,也会添加项目的大小和杂乱度。

跨项目复用前端代码的 5 种方法

这也导致更新和修正十分笨拙,任何改变都需求项目一切者更新整个软件包。这阻* p T e碍了在安排内部选用公共库。公共库内组件的可发现性也欠好。

这些问题导致 LodashV / V | C W [ i 之类的社区花了很长时刻和许多精力将组件拆成单独软件包发布b I Z到 NPM 上。Google 的 PoB llymer 项目(由 Eric Bidelman 等开源巨擘主导)也把超越一百个 web 元素放在超越一百个库房里。

Lerna 可以将公共库库房中的组件拆成多个软件包。Bit 可以9 y x w用来分发公共库中的组件。

下面~ X O j两篇文章可以参阅:

  • How Do We Really Use Reusable Components?
  • Shared Components Best` z m C 7 @ Practices for 2019

4. Git sub-module

跨项目复用前端代码的 5 种方法

submodule 实际上是从父库h @ h U r + U房的目录树中独立出来的库房,与父库房的仅有联系是 submodule 签出的 SHA 值,这个 SHA 值存 L l f在父库房的提交中。这个储存的 SHA 值的变动不会主动反映在 submodule 中。

但是,C ^sub6 1 4 v / Jmodule 有许许多多问题。I ` E 6 o直接 Gx 7 { e Toogle「git submodules) F v ! : ( o S S」,就能在查找成果中看到许多 submod} | y + ? y 7 Pule– d o 的问题。submodule 不! o } P B H r `会办理模块间的依靠联系,这是它X Q O I q f ,的首要问题。还有其他一些问题,X , a ( P o | D比方在父目录下 pull 不会主动更新 submodule。

别的,git 在处理抵触时不会保存 s1 ^ o f q h lubmod! A ) ~ _ f S # Fule 的指针。也就是说,如果没有手动更新指针J ) R g V,兼并更改时会丢失已处理的抵触。在 submodule 提交后,父库房中的 submodule 会是一个 detaO e F !ched head,由于它指向旧 head,而不是当时的 head。你猜怎么着?在父库房或者 submodule 下 push,不会发布其他父库房的改动。

有各种东西为 submodule 添加了额外的主动化,比方 git-subtree、gitslaver [ p、braid、giternal。不过,现在而言,跨项目、跨库房的 JS 模块,仅有可以一起办理源码改变和依靠联系的东西是 Bit。

5. 复制粘贴代码

由于让咱们面对现实吧,未来的我又为我做过什么呢?

跨项目复用前端代码的 5 种方法

说实话,在实践中,这也许是世界上最常用的代码复用方案。我想,在大多数情况下,这是由于短3 : ) e 8 * 4少「廉价的」、有用的+ = | B / * /替代方案,以及混乱的交给周期。

问题是,代码重复一点也不廉价。远非如此。

跨项目复用前端代码的 5 种方法

Y * & 0 4 m 1 a @码重复就像不断增长的债务,很快会让项7 | n u | W目失控,让项目保护成为噩梦,让交给周期越来越长。许多问题只要在交给生产环境后才会被发现。

最近h K Q的一项研究表明,GitHub 上有一半的代码是重复的。比方,在一v n 7万个库房中,is-string 这个 JavaScript 函数的一百多种不同的? L o V w完成被重复了一千次。

想一想,如果有更多的人愿意复用代码,而不是复制或K / D & I 5从头完成代3 , s r p n }码,省下的时刻可以完成多少新功能。想想代码重复给你的安排添* H H : 2加的保护成本和加长的交给周期。

代码复用以人为本

每个项目和每个开发者在乎的事情、运用w ; = 9 /的东西和流程不尽相同。但复用代码仍是真正完成模块化的要害。在当今的生态系统中,代码复用提供了十分大的优势,正变得越来越流行。

咱们创建了 Bit。不管你挑选什么样的方法和东西,重要的是鼓励6 Z ? / l K % z B一种倡议f H y H N P V同享和协作的文明。

毕竟,项目之间的同享从[ ^ C 8 [人与人之间的同享开端。