foreword
Some time ago, because the tool used in the Monorepo project used by the team was Lerna , so thinking about how to transform it, the final overall technology selection was PNPM + Changeset + Turborepo . Accordingly, it is necessary to support the capabilities of Lerna originally used in the context of this selection.
Among them, the more interesting is the need to publish the Package to the private Registry . Because, here Changeset
is selected, so the last command to execute and publish will be:
pnpm changeset publish
At this time, it involves a question, where should the private Registry in the project be configured? Here we are not in a hurry to find the answer, let's first understand the 4 postures of configuring a private registry.
1 Global registry
We can set the Global Registry by setting npm
or pnpm
of config
, for example:
# npm
npm config set registry=http://localhost:2000
# or pnpm
pnpm config set registry=http://localhost:2000
In this way, at the code level, the configuration here can be read through process.env.npm_config_registry
.
2. npmrc
Whether it is npm
or pnpm
the configuration will be read from the project's .npmrc file by default, so when we need a private registry for package distribution, we can set it like this:
registry = http://localhost:2000
3 --registry
When executing npm publish
or pnpm publish
, we can also bring the --registry
Option to tell the corresponding package management tool what the registry is to publish the package. E.g:
# 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
to publish, for example:
{
...
"publishConfig": {
"registry": "http://localhost:2000"
}
...
}
5 Changeset publish principle
After understanding the 4 postures of setting up a private registry, let's go back to the question at the beginning of the article, how to let pnpm changeset publish
know to release the package to the specified private registry? If you think you can choose one of the above 4, then you may need to step on some pits.
First of all, what we need to know is pnpm changeset publish
the essence of the command is to execute changeset
publish
. Then, that is, the above four ways of setting the Registry, it is very likely that not all of them will take effect, because Changeset has its own publish
mechanism . In this process, it will mainly do three things:
1. First, get Package Info, it will get Package Info from the specified Registry . For example, if it is to get the Package Info of rollup
, then it will be like this:
npm info rollup --registry="https://registry.npmjs.org/" --json
2. Secondly, according to the versions
field in the Package Info obtained above (it is an array containing all the released versions), compare the local package.json
version
field, to determine whether the current version has been released
3. Finally, if the current version is not released, the publish
command will be executed according to the currently used package management tool, and a Registry address that it thinks should be released will be constructed at this time, and then rewritten env
on the configuration, the corresponding code will be like this:
// 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)
}
);
It can be seen that the whole process of changeset publish
is still very simple and easy to understand. And, very importantly, what this process involves in the Registry is done by a function named getCorrectRegistry()
, which is defined like this:
// 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;
}
So looking at it, I think everyone understands why the four ways to set up the Registry mentioned above are probably not all effective.
因为,在Changeset 中只支持publishConfig
f011f1d5121e82d819dfea0b95fc46b5---或---1e80c06844c63cf3b3cc7d595381df39 env
Registry 的方式,所以如果你尝试其他2 种publish
到https://registry.yarnpkg.com
or https://registry.npmjs.org
, and the first step to get Package Info may fail.
Epilogue
I think the article is short, but the knowledge points conveyed are quite interesting. As for the PNPM + Changeset + Turborepo technology selection mentioned above, at least I'm still experiencing a very smooth experience, no matter in terms of dependency installation, multi-package task execution, Version Or Publish and so on. So, interested students can try it.
Finally, if there are inappropriate expressions or mistakes in the text, you are welcome to raise an Issue~
like
By reading this article, if you have gained something, you can give a like, this will become the motivation for me to continue to share, thank you~
I am Wuliu. I like to innovate and fiddle with source code. I focus on learning and sharing technologies such as source code (Vue 3, Vite), front-end engineering, and cross-end. Welcome to my WeChat public account Code center or GitHub .
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。