乐趣区

关于javascript:结合-lerna-和-yarn-workspace-管理多项目工作流

名词解释

  • 多个我的项目的代码放在在同一存储库中这种开发策略称之为 Monorepo
  • lerna Babel 开发用来治理多包的工具,基于 Monorepo 理念在工具端的实现
  • yarn Facebook 奉献的 Javascript 包管理器
  • commitlint 用来标准 git commit 信息

背景

在 vue-json-schema-form 我的项目中,须要把 libdocdemo 放在同一个我的项目中治理,彼此独立,又能够相互依赖。

应用 yarn workspace 能够很好的解决下面的问题,搭配 lerna 做 npm 公布治理。目前大型仓库都应用这种形式,比方 Vue Vuepress 等。

因为 yarn workspacelerna 有较多的性能重叠,这里重叠的局部优先应用 workspace。最初就是只有公布治理应用了 learn 其它应用 workspace

具体的可参考 https://github.com/lljj-x/vue… 配置。

创立我的项目

目录构造

├── packages
|   ├── lib
|   |   ├── package.json
|   ├── demo
|   |   ├── package.json
├── package.json

packages 下每个文件夹为一个独自残缺的包

package.json 配置

{
   "private": true, // 禁止公布
   "repository": "https://github.com/lljj-x/vue-json-schema-form",
   "workspaces": [
       "packages/lib",
       "packages/demo",
       // "packages/*" // 能够单个指定 也可间接配置 *
   ]
}

子 package 配置

子 package 即为每个独立的工作区。

如:packages/demo,应用 vue-cli

cd packages && vue create demo

demo/package.json 配置:

{
    "private": true, // 禁止公布

    "publishConfig": {"access": "publish" // 如果该模块须要公布,对于 scope 模块,须要设置为 publish,否则须要权限验证}
}

yarn workspace

yarn install

装置所有依赖,蕴含子 package 依赖,如果子 package 之间存在相互依赖会通过创立 软链 的形式援用,而非 npm 下载,这里可能会影响 webpack 配置中应用 node_modules 做门路判断的中央。

yarn install

依赖树关系

yarn workspaces info

装置 / 删除依赖模块

单个 package 工作区

# packageA 装置 axios
yarn workspace packageA add axios

# packageA 移除 axios
yarn workspace packageA remove axios

packageA 是须要装置依赖的包名,即 package.json 中的 name 字段,而非目录名

root package

# root package 装置 commitizen
yarn add -W -D commitizen

# root package 移除 commitizen
yarn remove -W commitizen

运行单个 package 的 scripts 命令

# 运行 packageA 的 dev 命令
yarn workspace packageA dev
# 这里是在每个工作区运行 run build 命令
yarn workspaces run build

Tips:这里运行命令的时候不会检测依赖树关系,只是 package.json 文件 workspaces 配置工作区一一运行,这里举荐应用 lerna build 见下文 lerna build

到这里对于不须要推送 npm 的状况下曾经能够满足根本须要了。

lerna

目前应用 lerna 次要来做公布和版本治理

  • 全局装置
npm i -g lerna
  • 初始化一个我的项目
lerna init

蕴含两种工作模式:

  1. Fixed/Locked mode (default)

固定模式,默认 packages 下的所有包共用一个版本号(version),会主动将所有的包绑定到一个版本号上(该版本号也就是 lerna.json 中的 version 字段),所以任意一个包产生了更新,这个共用的版本号就会产生扭转。

  1. Independent mode

独立模式,容许每一个包有一个独立的版本号,在应用 lerna publish 命令时,能够为每个包独自制订具体的操作,同时能够只更新某一个包的版本号。

lerna.json 中的 version 字段指定为 independent 即可,或者 lerna init --independent 命令初始化

lerna.json 文件配置大抵如下

{
    "npmClient": "yarn",
    "useWorkspaces": true, // 应用 yarn workspaces
    "version": "0.0.1", // 以后版本 或者 independent 独立模式 
    "command": {
        "version": {
            "allowBranch": "master",
            "exact": true,
            "ignoreChanges": ["**/*.md"],
            "message": "build: release version %v"
        }
    }
}

lerna clean

革除所用的 node_modules 目录

lerna clean

lerna diff

显示批改内容 相似 git diff

lerna diff

lerna ls

列出所有的子 package

lerna ls -l

lerna changed

列出批改过的子 package

lerna changed

lerna build

build 所有子 package,​子 package 别离执行 build--sort ​参数能够管制以拓扑排序规定执行命令

lerna run --stream --sort build

lerna version

lerna version 的作用是进行 version bump,反对手动和主动两种模式

手动确定新版本

# 按着提醒抉择版本即可
lerna version

主动确定版本

主动依据 conventional commit 标准确定版本

存在 feat 提交:须要更新 minor 版本
存在 fix 提交:须要更新 patch 版本
存在 BREAKING CHANGE 提交:须要更新大版本

# 生成 changelog 文件以及依据 commit 来进行版本变动
lerna version --conventional-commits

# 生成 changelog 文件以及依据 commit 来进行版本变动, 不提醒用户输出版本
lerna version --conventional-commits --yes

可参见官网文档 lerna version

version 胜利后会主动推送以后分支,能够联合配置 lerna.json文件 commandversion字段 配置容许 version 的分支,commit 信息等

{
    "npmClient": "yarn",
    "useWorkspaces": true,
    "version": "0.0.1", 
    "command": {
        "version": {
            "allowBranch": "master",
            "exact": true,
            "ignoreChanges": ["**/*.md"],
            "message": "build: release version %v"
        }
    }
}

lerna publish

lerna publish 的性能能够即蕴含 version 的工作,也能够单纯的只做公布操作。

可参见官网文档 lerna publish

lerna publish

lerna publish 会先调用 lerna version,再确定是否要公布到 npm

lerna publish from-git

from-git 基于以后 git 提交的软件包做公布,个别都是通过 lerna version 提交的版本

lerna publish from-package

from-package 在注册表中不存在该版本的最新提交中公布程序包(这个我没用过)

lerna 不会公布标记为公有的软件包(package.json"private": true

changelog

依据 conventional commit 提交标准,即可通过工具为每个 package 生成 changelog 文件。

conventional commit 反对

conventional commit 标准应用也能够看这个:Commit message 和 Change log 编写指南

装置如下依赖:

yarn add -W -D commitizen cz-conventional-changelog @commitlint/cli @commitlint/config-conventional husky conventional-changelog-cli

commitizen:

一个撰写合格 Commit message 的工具

cz-conventional-changelog:

用于使 commitizen 反对 Angular 的 Commit message 格局

配置 package.json 增加如下配置

{
    "config": {
        "commitizen": {"path": "./node_modules/cz-conventional-changelog"}
    }
}

至此就能够通过 git cz 命令替换 git commit 生成合乎格局的 Commit message。

git cz 命令呈现如下选项

@commitlint/cli:
commitlint 用于查看您的提交音讯是否合乎提交格局,相似 eslint 校验 js 语法

@commitlint/config-conventional:
commitlint 校验规定,相似 eslint-config-standard

增加并配置 .commitlintrc.js 文件

module.exports = {extends: ['@commitlint/config-conventional'],
    rules: {...otherRules // 能够持续配置你的规定}
};

husky:
husky是 Git hooks 工具,这里用于在 commit 时校验 message 内容

配置 package.json 文件,增加如下

{
    "husky": {
        "hooks": {"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"}
    }
}

至此当新提交的 commit message 不符合规范便会阻止提交。

conventional-changelog-cli:
依据 commit message 生成 changelog.md 文件(这里性能和 lerna version --conventional-commits 生成 changelog 有局部重叠,下文会具体辨别)。

如:conventional-changelog -p angular -i CHANGELOG.md -s -r 2

留神:这里生成的是整个仓库的 changelog,而非每个 package 生成 changelog

生成 changelog

生成 changelog 依赖如上 conventional-commit 标准 message

整个仓库 changelog

生成自从上次公布以来的变动:

conventional-changelog -p angular -i CHANGELOG.md -w

如果这是您第一次应用此工具,并且想要生成所有以前的变更日志,则能够执行:

conventional-changelog -p angular -i CHANGELOG.md -s -r 0

参见:conventional-changelog-cli

每个 package 工作区独立 changelog

lerna version 时,主动模式 --conventional-commits 命令会同时为每个 package 工作区生成 changelog

lerna version --conventional-commits

注:lerna version 胜利之后便会为每个 package 生成 changelog,包含 root package

npm scripts

如下:本人常配的一些 script

{
    "scripts": {
        "demo:dev": "yarn workspace demo dev",
        "demo:build": "yarn workspace demo build",
        "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 2",
        "clean": "lerna clean && rm -rf node_modules",
        "packages:diff": "lerna diff",
        "packages:list": "lerna ls -l",
        "packages:changed": "lerna changed",
        "packages:build": "lerna run --stream --sort build",
        "publish": "lerna publish",
        "autoPublish": "lerna publish --conventional-commits --yes",
        "version": "lerna version --conventional-commits --yes"
    }
}
  • changelog 生成整个仓库 changelog
  • publish 手动抉择版本并发包 (其实我本人平时个别用这个)
  • autoPublish 主动确定版本并发包同时生成每个 package changelog
  • version 主动确定版本不公布和生成每个 package changelog

参考:https://zhuanlan.zhihu.com/p/…

原文公布在:https://www.lljj.me/

退出移动版