多包管理工具lerna
通常,我们在开发前端项目时都是单个包的,也就是只有一个package.json文件以及一个node_modules文件夹。单个包项目的优点不言而喻,简单,可靠,便于管理。但是,当一个大的项目库代码量剧增之后,管理起来就是一件比较麻烦的事情,为了方便代码的共享,就需要将代码库拆分成独立的包。lerna便是优化和管理js多包项目的利器
最近有这么一个项目,这个项目需要依赖多个npm包,这些npm包有部分依赖是相同的(或者包与包之间有相互联系),如下:
如上图所示,这里有两个npm包:npm1和npm2,它们有公共的依赖base2。这种情况下我们该如何管理本地代码呢? 如果npm1和npm2本地代码分别存入一个单独的仓库,那么base2就需要copy一份,并且更新时两侧都要保持同步,另外如果还有更多的包,更多的公共依赖,那代码的维护就更加麻烦了!解决方法:可以令npm1依赖npm2,这样就不需要依赖两次base2
1.全局安装lerna npm install lerna -g
安装完成后,我们看一下控制台有没有这个命令:
2.初始化我们的项目仓库
先创建一个lerna-repo目录,然后进入此目录运行下面的命令lerna init
生成目录结构如下:
lerna 初始化项目,有两种模式:
1)lerna init --independent 命令初始化项目,这个时候就为独立模式(Independent mode)
2)lerna init 默认的为固定模式(Fixed mode)
固定模式中,packages下的所有包共用一个版本号(version),会自动将所有的包绑定到一个版本号上(该版本号也就是lerna.json中的version字段),所以任意一个包发生了更新,这个共用的版本号就会发生改变。而独立模式允许每一个包有一个独立的版本号,在使用lerna publish命令时,可以为每个包单独制定具体的操作,同时可以只更新某一个包的版本号
3.lerna的配置文件lerna.json
打开这个json文件,如下图:
1)packages属性,它是一个数组,每个元素代表可以发布的npm包的目录,比如图4中代表packages目录(初始化生成的)下所有的文件夹都是可以发版的npm包,另外也可以自定义npm包的目录。比如可以自定义一个目录——packages/plugins,则该目录下所有的文件夹都是可以发版的npm包。一般lerna-repo目录下可以存放各种依赖lib和入口entry,通过构建工具script tool将这些代码打包进packages目录中
2)启用 yarn Workspaces,下面的解释都来自百度,未试验过:
必须是 private 项目才可以开启 workspaces。
hoist: 提取公共的依赖到根目录的node_moduels,可以自定义指定。其余依赖安装的package/node_modeles中,可执行文件必须安装在package/node_modeles。
workspaces: 所有依赖全部在跟目录的node_moduels,除了可执行文件
3.生成一个npm包 lerna create <包名> [目录]
使用lerna create npm1 命令,生成npm1包,目录没有指定(大家可以验证下,我这指定了packages/plugins无效,还是生成在packages,而不是packages/plugins下)
我们在packages/plugins目录下生成一个名为npm1的包,生成后的目录结构如下:
4.为packages文件夹下的package安装依赖
lerna add 命令,其命令签名是:
lerna add [@version] [–dev]
该命令有许多的用法,通常说来有如下几种:
1)lerna add babel , 该命令会在npm1和npm2下安装babel
add后,npm1包下,node_modules文件夹多了bable如下
add后,npm2包下,node_modules文件夹多了bable如下
2)lerna add react --scope=npm1 ,该命令会在npm1下安装react
add后,npm1包下,node_modules文件夹多了react,而npm2包怎么没有添加:
3)lerna add npm2 --scope=npm1,该命令会在npm1下安装npm2
add后,npm1包下,node_modules文件夹多了npm2
5.删除包下面的node_modules
上面的命令安装依赖会在每个包目录下生成node_modules,lerna clean命令就是将node_modules删除
6.将本地 package 链接在一起并安装依赖
lerna bootstrap命令,将本地 package 链接在一起并安装依赖
执行该命令式做了一下四件事:
1)为每个 package 安装依赖
2)链接相互依赖的库到具体的目录,例如:如果 npm1 依赖 npm2,且版本刚好为本地版本,那么会在 node_modules 中链接本地项目,如果版本不满足,需按正常依赖安装
3)在 bootstraped packages 中 执行 npm run prepublish
4)在 bootstraped packages 中 执行 npm run prepare
7.导入外部的包
导入外部的包(这个命令比较有意思) lerna import 外部包的位置 --dest=工程下的位置。来自百度,未试验过。
8.运行包
运行包的script命令 lerna run 命令 [–scope=特定的某个包] 和npm run [命令] 没什么区别,如果没有scope选项,lerna会运行每个包的script命令,如下:
9.查看整个工程目录下有哪些包
查看整个工程目录下有哪些包 lerna list [-l],lerna list -l 信息更全面一些:
10.发布更新
lerna publish了,用于发布更新,运行该命令会执行如下的步骤:
1)运行lerna updated来决定哪一个包需要被publish
2)如果有必要,将会更新lerna.json中的version
3)将所有更新过的的包中的package.json的version字段更新
4)将所有更新过的包中的依赖更新
5)为新版本创建一个git commit或tag
6)将包publish到npm上