前言
前段时间,因为团队应用的 Monorepo 工程应用的工具是 Lerna,所以在思考如何革新的问题,最终整体的技术选型是 PNPM + Changeset + Turborepo。相应地,就须要在这个选型的背景下反对原先应用到的 Lerna 的能力。
其中,比拟有意思的就是须要把 Package 公布到 公有 Registry。因为,这里抉择了 Changeset
,所以最初执行公布的命令会是:
pnpm changeset publish
那这个时候,就牵扯到一个问题,我的项目中的公有 Registry 要配置在哪?这里咱们不焦急找答案,先来理解一下配置公有 Registry 的 4 种姿态。
1 Global registry
咱们能够通过设置 npm
或者 pnpm
的 config
来设置 Global Registry,例如:
# npm
npm config set registry=http://localhost:2000
# or pnpm
pnpm config set registry=http://localhost:2000
这样一来,在代码层面就能够通过 process.env.npm_config_registry
读取到这里的配置。
2 .npmrc
无论是 npm
或 pnpm
默认都会从我的项目的 .npmrc 文件中读取配置,所以当咱们须要 包的公布要走私有 Registry 的时候,能够这样设置:
registry = http://localhost:2000
3 –registry
在执行 npm publish
或 pnpm publish
的时候,咱们也能够通过带上 --registry
Option 来告知对应的包管理工具要将包公布的 Registry 是什么,例如:
# npm
npm publish --registry=http://localhost:2000
# or pnpm
pnpm publish --registry=http://localhost:2000
4 PublishConfig
PublishConfig 指的是咱们能够在要执行 publish
命令的我的项目 package.json
中的 publishConfig.registry
来告知 npm
或 pnpm
要公布的 Registry,例如:
{
...
"publishConfig": {"registry": "http://localhost:2000"}
...
}
5 Changeset publish 原理
在理解完 4 种设置公有 Registry 的姿态后,咱们回到文章开始的这个问题,如何让 pnpm changeset publish
晓得要把公布包到指定的公有 Registry?如果,你感觉以上 4 种任选一种即可,那你可能须要踩些坑。
首先,咱们须要晓得的是 pnpm changeset publish
命令的实质是执行 changeset
的 publish
。那么,也就是下面的 4 种设置 Registry 的形式,很可能不是每种都失效的,因为 Changeset 有一套 本人的 publish
机制。而这个过程它次要会做这 3 件事:
1. 首先,获取 Package Info,它会从 指定的 Registry 获取 Package Info。举个例子,如果是获取 rollup
的 Package Info,那么在这里会是这样:
npm info rollup --registry="https://registry.npmjs.org/" --json
2. 其次,依据下面拿到的 Package Info 中的 versions
字段(它是一个蕴含所有已公布的版本的数组),比照本地的 package.json
的 version
字段,判断以后版本是否已公布
3. 最初,如果未公布以后版本,则会依据以后应用的包管理工具执行 publish
命令,并且此时会结构一个 它认为应该公布的 Registry 地址,而后重写 env
上的配置,对应的代码会是这样:
// packages/cli/src/commands/publish/npm-utils
const envOverride = {npm_config_registry: getCorrectRegistry()
};
let {code, stdout, stderr} = await spawn(
// 动静的包管理工具,例如 pnpm、npm、yarn
publishTool.name,
["publish", opts.cwd, "--json", ...publishFlags],
{env: Object.assign({}, process.env, envOverride)
}
);
能够看到,整个 changeset publish
的过程还是很简略易于了解的。并且,十分重要的是 这个过程牵扯到 Registry 获取的都是由一个名为 getCorrectRegistry()
的函数实现的,它的定义会是这样:
// packages/cli/src/commands/publish/npm-utils.ts
function getCorrectRegistry(packageJson?: PackageJSON): string {
const registry =
packageJson?.publishConfig?.registry ?? process.env.npm_config_registry;
return !registry || registry === "https://registry.yarnpkg.com"
? "https://registry.npmjs.org"
: registry;
}
那这么一看,我想大家都明确了,为什么后面提及 4 种设置 Registry 的形式,很可能不是每种都失效的。
因为,在 Changeset 中只反对了 publishConfig
或 env
配置 Registry 的形式,所以如果你尝试其余 2 种形式就会 publish
到 https://registry.yarnpkg.com
或 https://registry.npmjs.org
,并且在第一步获取 Package Info 的时候可能就会失败。
结语
我想文章虽短,然而传播的知识点还是蛮乏味的。至于后面所说的 PNPM + Changeset + Turborepo 技术选型,起码目前我体验起来还是很丝滑的,无论是在依赖装置、多包工作执行、Version Or Publish 等方面都很优良。所以,有趣味的同学倒是能够尝试一下。
最初,如果文中存在表白不当或谬误的中央,欢送各位同学提 Issue ~
点赞
通过浏览本篇文章,如果有播种的话,能够 点个赞,这将会成为我继续分享的能源,感激~
我是五柳,喜爱翻新、捣鼓源码,专一于源码(Vue 3、Vite)、前端工程化、跨端等技术学习和分享,欢送关注我的 微信公众号 Code center 或 GitHub。