如何管多包单仓库项目

多项目多包

github.com/webpack

多个包对应多个独立项目,好处是符合单一职责原则,简单可靠,但是这种方案在某些情况下会有一些问题

问题:ssp 中的代码同步问题

ssp 项目前端部分区分了两个项目,但两个项目实际上基于一致的框架实现业务逻辑,因此有很多通用的业务逻辑,组件需要在两个项目中共享,

初期是 ctrl + c/v

后来项目组内搭建了私有 npm 仓库,所以考虑用 npm package 同步代码,假如按照多包多项目的管理方式 Ï · 代码/组件相对细小,如果单独拆分项目则过于零散。

· 独立项目会有重复的依赖/构建流等配置,如 webpack 配置代码

· 同步代码组件的开发环境严重依赖主项目本身,独立项目不利于开发维护。

· 多个子包需要一个统一的管理方式

于是需要考虑另一种管理方式

单项目多包

顾名思义,单项目多包,就是虽然划分多个子包,但是都放到同一个项目进行管理。

举例 :github.com/vuejs/vue-c...

这样,就解决了多个独立子项目配置重复,不便于开发维护的问题。

但是还有一个的统一管理的问题又该如何解决呢?

Lerna 解决单项目多包的管理问题

所谓的统一管理问题,举个简单的例子如果所有包都需要发布一个新版本,那么是逐个 npm publish 好还是统一执行 xxx publish 合理?

本质上这就是 lerna 在干的事

github.com/lerna/lerna

lerna 命令初见

lerna 项目中最常用到的命令是 lerna init, lerna bootstrap 和 lerna publish

lerna init 初始化项目

go 复制代码
multi-packages/

 package.json

 packages/

   package-1/

     package.json

   package-2/

     package.json

命令执行以后,主要就是生成了以上的一个结构,其中 packages 就是默认存放多个子包的目录

lerna create 创建子包

相当于执行 npm init ,不过在执行的时候自动将创建的 package.json 放到 package/ 目录下, 比如执行 lerna pacekage-3

go 复制代码
multi-packages/

 package.json

 packages/

   package-1/

     package.json

   package-2/

     package.json

   package-3/

     package.json

lerna publish 发布版本,这是 lerna 最核心的命令了,运行这个命令以后会出发以下的一些东西

  1. 运行lerna updated来决定哪一个包需要被publish

  2. 如果有必要,将会更新lerna.json中的version

  3. 将所有更新过的的包中的package.json的version字段更新

  4. 将所有更新过的包中的依赖更新

  5. 为新版本创建一个git commit或tag

  6. 将包publish到npm上

lerna publish 有两种管理模式

· 一种是 fixed 模式 -- 统一版本号 @babel

· 一种是 independent 模式 -- 独立管理各个包的版本号

可以通过 lerna.json 进行配置

同时,该命令也有许多的参数,例如 --skip-git 将不会创建git commit或tag,--skip-npm将不会把包publish到npm上。

除此之外其他大都是 命令都是统一对 package/ 下的包执行某些操作不再一一赘述

有需要可以参考官方文档

npm @scope

npm 在 5.0.0 之后就全面支持了 @scope 包作用域的功能,这个功能最大的初衷就是更好的管理包的命名问题

比如以下这些包 babel- 开头的包

· babel-runtime-core

· babel-core

· babel-php-transfer

由于 npm 采取先到先得的原则,基本上没有什么办法很好的区分第三方和 babel 官方的包

而启用 @babel 命名空间之后,只要看到 @babel 就知道一定是 babel 官方的包

npm registry

不过对于我们私有包的作用上来说,规范命名还是其次,最重要的是 npm 设置 registry 的时候不仅可以全局设置,也可以针对单个 @scope 定义。

perl 复制代码
// 在 @myco 命名空间下登陆状态总是指向 http://reg.example.com

npm login --registry=http://reg.example.com --scope=@myco


// 同样的,通过单独设置 @myco 命名空间的 registry ,那么就只有这个命名空间下的包,无论是 npm install/publish 都会指向你所设置的地址

npm config set @myco:registry http://reg.example.com

如果我们的给所有私有包都定义一个scope,这样的话当我们就可以根据 scope 分配私有仓库的 registry 。

从而有效区分公共/私有仓库,做到私有包访问私有仓库,公共包访问公共包仓库,不需要全部流量都走私有仓库再转发出去。

基于 npm 管理包还会遇到一个问题,当 package-A 依赖 package-B, 而 package-B 包由于某些原因需要频繁编辑,同时需要立刻在 package-A 环境下查看效果。,由于npm 包每次更新都需要修改版本号(或者 npm unpublish && npm publish强制覆盖),如果按照正常流程则需要

css 复制代码
vim package-B/package.json       // 除了关键代码文件修改,还需要修改 package.json 的 version 字段

npm publish                     // 推送 package-B 到仓库

cd package-A/ && npm i package-B // 在 package-A 更新 package-B ,然后才能查看效果

如果是 package-B 处于一种频繁修改的状态,以上流程就会让开发调试 package-B 的过程变得非常繁琐。

npm link 相当于一个软链,可以将你想要安装的包软链到本地项目中。比如:

perl 复制代码
cd package-B && npm link // 在 package-B 下执行,为 package-B 建立一个软链

这个时候如果再别的项目中安装 package-B,那么并不会实际安装 package-B,而是通过软链指向 package-B/文件夹

perl 复制代码
cd package-A && npm link package-B // node_modules/package-B 自动软链到 package-B/

这样,你对 package-B 的修改就可以及时反馈在 package-A 项目中了

总结

· 介绍多包多仓库,多包单仓库之间的区别,以及多包多仓库这种管理方法的一些问题

· 介绍 lerna 如何管多包单仓库项目

· 介绍基于 npm 两个有用的特性 npm @scope / npm link

Extra

cz-cli -- The commitizen command line utility.

这个工具提供一个 cli 界面帮助你规范 commit

npm install -g commitizen

使用方法

arduino 复制代码
git cz // 用 cz 替换 commit 命令
相关推荐
Good_Luck_Kevin201813 分钟前
速通sass基础语法
前端·css·sass
大怪v25 分钟前
前端恶趣味:我吸了juejin首页,好爽!
前端·javascript
反应热40 分钟前
浏览器的本地存储技术:从 `localStorage` 到 `IndexedDB`
前端·javascript
刘杭41 分钟前
在react项目中使用Umi:dva源码简析之redux-saga的封装
前端·javascript·react.js
pan_junbiao1 小时前
Vue使用axios二次封装、解决跨域问题
前端·javascript·vue.js
秋沐1 小时前
vue3中使用el-tree的setCheckedKeys方法勾选失效回显问题
前端·javascript·vue.js
浮华似水1 小时前
Yargs里的Levenshtein距离算法
前端
_.Switch2 小时前
Python Web 架构设计与性能优化
开发语言·前端·数据库·后端·python·架构·log4j
libai2 小时前
STM32 USB HOST CDC 驱动CH340
java·前端·stm32
Java搬砖组长3 小时前
html外部链接css怎么引用
前端