这是最传统的方式了
坏处也很明显,想复用一个组件或者一段逻辑
ctrl c+v 很麻烦,会造成很多维护上的问题,难以追踪
即使用软连接,也经常要初始化同步,每次都要拉好几个版本的 git 仓库
靠 .gitmodules
来管理,git 自带的一种多包管理方式
但是面对 js/node
项目时,往往会出现心有余而力不足的情况
举个例子
project
// index.js
const Koa = require('koa');
const MyMidway = require('./submodule/my-midway');
const app = new Koa();
app.use(MyMidway);
app.listen(3000);
即 cjs 需要引入对应的 git 子模块的路径
这时候就有问题了,为什么另外一个仓库,我们不能像 npm 那样
又能对包进行安装,又能进行版本管理呢?
lerna 作为一种专为 node/npm 设计的工具
在一定程度上解决了这个问题
🐉 A tool for managing JavaScript projects with multiple packages.
用起来很简单
npm i -g lerna
lerna init
# package.json and lerna.json
lerna create package-1
lerna create package-2
上面其实就是初始化和创建本地包的指令
使用它的命令,我们就可以基于 lerna 本身创建注册本地包
比如我要在 package-2 里用 package-1 里的组件
lerna add package-1 --scope=package-2
这时候 lerna
会在所有 lerna.json>packages>[glob]
路径
去寻找非 private
的包,找到了,就在 package-2
的 node_modules
里建立 软连接
把 package-1
link 过去,并且在 package-2
的 package.json
的依赖里把版本定上
默认就是 package-1>package.json>version
这样就可以直接像 npm 包那样进行管理
不过也有缺点,比如这时候去 yarn upgrade, 是没法运行的
因为 yarn/npm 默认自个去 npmjs.com 找包,本地包找不到会报错
这时候,我们要不用 lerna 自己的命令替代
要不就 yarn add 一个一个升级
当然对于公司来说
最佳方案还是私有化 npm
打造一套 本地源 --> 私有源 --> 公共 npm 源 / 淘宝 的包安装系统
lerna publish 到 private npm registry (verdaccio)
这样 yarn /npm i 安装升级就不会产生错误
同时大量的公共逻辑和组件都作为私有包,发布在私有源上
同时,本地调试也简单
因为开发环境,跑的所有代码都注册在本地
不需要去 node_modules 这个巨大的黑洞里面 寻找目录,设置断点啥的
直接边写边调试
当然 lerna 注册包,也有 整体和独立 2 种模式
lerna/packages 也可以使用 useWorkspaces 选项,用 package.json 里的字段去检测字段
甚至 lerna 基于软连接,能够把所有子包的 node_modules 全部指向 项目根目录下的 node_modules
不过这玩意还是有一定的学习成本,而且在通过 lerna 跑一些 npm 指令的时候
子进程的 stdout 没有很好的 pipe 进父进程的 process.stdout
这导致我们在使用 sh/cmd 的时候,针对一些过程比较长的 task,比如 webpack 打包
终端没有啥显示,心里就比较慌
软连接: symbolic link
git 子模块:git submodule