美文网首页
lerna管理开源前端项目

lerna管理开源前端项目

作者: pansly | 来源:发表于2019-09-29 17:48 被阅读0次

    前言

    由于公司项目大多采用react-native实现,在APP内部运行,但也要有H5的使用场景,以前很多项目都开发多套代码, 造成人力成本大幅浪费,基于此, 我主导开发了一套RN转H5的一套开发框架以及一整套的代码规范、推送CND等一系列的前端工程化体系, 然而有较多的私有库发布到公司内部NPM镜像上,私有库多了,每个库之间又相互依赖,一段时间下来,版本号就很难管理,大多数时候需要手动更新版本依赖;

    其实babel的重要贡献者Jamie Kyle1,在为 Babel 6 工作的过程中发现所有东西都拆分成漂亮的小插件包,但同时也就需要管理数十个软件包, 也遇到同样的问题。因此,多包存储库管理工具 Lerna 应运而生。为让项目更好用,他对项目进行了多次重写,试图让架构更完善。

    什么是Lerna

    Lerna官网对此给出了官方的解释:Lerna是一个管理包含多个软件包的JavaScript项目的工具。它可以:

    1、解决包之间的依赖关系。

    2、通过git仓库检测改动,自动同步。

    3、根据相关的git提交的commit,生成CHANGELOG。

    Lerna是一个命令行工具,可以将其安装在系统全局。简单的命令说明,可以使用:lerna -h查看命令帮助。

    两种包管理模式

    1. 默认的为固定模式(Fixed mode),当使用lerna init命令初始化项目时,就默认为固定模式,也可以使用 lerna init --independent 命令初始化项目,这个时候就为独立模式(Independent mode)。

    2. 固定模式中,packages下的所有包共用一个版本号(version),会自动将所有的包绑定到一个版本号上(该版本号也就是lerna.json中的version字段),所以任意一个包发生了更新,这个共用的版本号就会发生改变。
      独立模式允许每一个包有一个独立的版本号,在使用lerna publish命令时,可以为每个包单独制定具体的操作,同时可以只更新某一个包的版本号。此种模式时,lerna.json中的version字段指定为independent即可。

    添加lerna.json配置

    {
        "version": "0.7.30", 
        "packages": [
            "packages/package-1",
            "packages/package-2",
            "packages/package-3",
            "packages/package-4"
        ],
        "command": {
            "publish": {
                "message": "chore(release): publish %s"
            },
            "bootstrap": {
                "npmClientArgs": [
                    "--no-package-lock"
                ]
            }
        },
        "npmClient": "npm"
    }
    
    

    备注: 上面的配置文件中,部分字段做下如下说明:

    1. version指定的是所有包的统一版本号;对于independent模式,这个字段请指定为independent;

    2. npmClient指定的是npm的客户端。默认的,lerna将使用npm。读者也可依所需将程序设置为yarn,甚至cnpm等等。

    3. command字段,可以对publish和bootstrap命令进行参数传递和命令定制。如:command.publish.ignoreChanges,用来设置一些忽略的文件,以避免无关文件的提交对于版本号的变更,如README.md等等。command.bootstrap.npmClientArgs指定在bootstrap命令时,传递的默认参数,比如我们会常常使用--no-package-lock来禁止package-lock.json或yarn.lock等等。

    4. packages字段指定包所在的目录。

    常用命令

    Lerna命令

    初始一个多包的工程

    lerna init
    

    上述命令会初始化一个多包工程。初始化之后会在根目录生成packages目录、lerna.json,如果使用independent模式,请使用命令:lerna init --independent

    创建子包

    lerna create <package> [-y]
    

    在packages所指目录下创建package包。

    添加包

    lerna add <package>[@version] [--dev] [--exact] [--scope=module名]
    

    上述命令会添加一个包package指明的软件包。

    指定--dev是添加在devDependencies中。

    指定--exact,则将用精确匹配的版本添加包。

    指定--scope将只在此指明的模块中安装这个软件包,否则将在所有packages目录中的包中安装。

    对于packages目录下的子包,将通过设立systemlink来解决依赖。

    对于npm镜像中存在的包,将安装镜像中的包。

    运行命令

    运行命令分为两种:任意命令和npm scripts定义的命令。

    对于任意命令使用,lerna exec;对于npm scripts定义的命令使用lerna run

    以lerna exec为例:

    lerna exec [--concurrency number] [--stream] [--parallel] -- <command> [..args]此命令,在所有包中运行所指定的命令。

    特别地,lerna exec -- rm -rf ./node_modules将删除所有包中的依赖。lerna exec -- npm uninstall <package>将移除所有的package依赖。

    lerna exec 和 lerna run 如需要每个子模块相继的执行并按顺序输出,可以指定--concurrency 1。

    对于指定了--stream的命令,将把所有子进程的输出立即回显此举可能造成子进程显示顺序交叉,为了分辨输出来源,每个输出,会带上包名;指定了--parallel的命令,则会在scope指定的范围内,并行地执行相关地命令。

    lerna run与上述命令不一样的情况在于,lerna run build将在每一个包中scripts字段中执行定义的build命令。

    安装所有依赖

    lerna bootstrap
    

    上述命令安装所有的依赖、将所有的相关链接做好,同时在所有的包中运行npm run prepublish。随后,在所有包中运行npm run prepare。此时,所有的依赖均已完备。

    发布

    lerna publish  // 发布所有的包。
    

    清理

    lerna clean // 删除所有的node_modules
    

    一些优化

    合并公共依赖

    我们在开发过程中,经常发现包依赖类似。这样,我们发现运行lerna bootstrap之后,会重复安装依赖包,这样会造成空间的浪费和效率的降低。为此,我们可以把同样的依赖包在根目录安装一次即可。此时,可以使用lerna bootstrap --hoist命令,则公用的依赖,只会在顶层目录安装一次。

    发布带有scope公有包

    带有scope的包,需要发布时候,如果是公有的包,需要在npm publish时候使用npm publish --access public。为了能够成功publish,并使用lerna流程,请在每个子包的lerna.json中加入:

    "publishConfig": {
        "access": "public"
      }
    

    检测循环依赖

    lerna本身内置了检测循环依赖的功能,如果出现循环依赖。会在bootstrap时候给出提示:

    image.png

    此时,请依照提示去掉循环依赖,以保证软件包的正常运行。

    配置lerna后目录结构

    .
    ├── CHANGELOG.md
    ├── README.md
    ├── docs
    ├── lerna.json
    ├── package.json
    ├── packages
    │   ├── package-1
    │   ├── ── package.json
    │   ├── package-2
    │   ├── ── package.json
    │   ├── package-3
    │   ├── ── package.json
    │   ├── package-4
    │   ├── ── package.json
    │   └── package-5
    │   ├── ── package.json
    ├── tslint.json
    └── website
    

    运行脚本

    "scripts": {
        "bootstrap:ci": "lerna bootstrap --npm-client=npm",
        "bootstrap:lerna": "lerna bootstrap -- --ignore-engines",
        "release:lerna": "lerna publish --exact --skip-temp-tag --registry http://127.0.0.1:4873",
         "release:beta": "lerna publish --exact --skip-temp-tag  --preid=beta --npm-tag=beta --registry http://127.0.0.1:4873"
    }
    
    

    相关文章

      网友评论

          本文标题:lerna管理开源前端项目

          本文链接:https://www.haomeiwen.com/subject/oxlnuctx.html