.pnpmfile.cjs
pnpm 允许你通过特殊函数(hooks)直接连接到安装过程。Hooks 可以在一个名为 .pnpmfile.cjs 的文件中声明。
🌐 pnpm lets you hook directly into the installation process via special functions
(hooks). Hooks can be declared in a file called .pnpmfile.cjs.
默认情况下,.pnpmfile.cjs 应位于与锁文件相同的目录中。例如,在具有共享锁文件的 工作区 中,.pnpmfile.cjs 应位于 monorepo 的根目录下。
🌐 By default, .pnpmfile.cjs should be located in the same directory as the
lockfile. For instance, in a workspace with a shared lockfile,
.pnpmfile.cjs should be in the root of the monorepo.
钩子
🌐 Hooks
长话短说
🌐 TL;DR
| 钩子函数 | 过程 | 用途 |
|---|---|---|
hooks.readPackage(pkg, context): pkg | 在 pnpm 解析依赖包的 package 清单后调用 | 允许你修改依赖的 package.json |
hooks.afterAllResolved(lockfile, context): lockfile | 在依赖解析完成后调用 | 允许你修改锁文件 |
hooks.beforePacking(pkg): pkg | 在打包/发布期间创建 tar 包之前调用 | 允许你自定义发布的 package.json |
hooks.readPackage(pkg, context): pkg | Promise<pkg>
允许你在解析之后、解析前更改依赖的 package.json。这些更改不会保存到文件系统,但它们会影响锁文件中解析的内容,从而影响安装的内容。
🌐 Allows you to mutate a dependency's package.json after parsing and prior to
resolution. These mutations are not saved to the filesystem, however, they will
affect what gets resolved in the lockfile and therefore what gets installed.
请注意,如果你已经解决了想要修改的依赖,则需要删除 pnpm-lock.yaml。
🌐 Note that you will need to delete the pnpm-lock.yaml if you have already
resolved the dependency you want to modify.
如果你需要将对 package.json 的更改保存到文件系统中,你需要使用 pnpm patch 命令并修改 package.json 文件。例如,如果你想移除某个依赖的 bin 字段,这可能会很有用。
🌐 If you need changes to package.json saved to the filesystem, you need to use the pnpm patch command and patch the package.json file.
This might be useful if you want to remove the bin field of a dependency for instance.
参数
🌐 Arguments
pkg- 软件包的清单。可以是来自注册表的响应,或者是package.json内容。context- 步骤的上下文对象。方法#log(msg)允许你为该步骤使用调试日志。
用法
🌐 Usage
示例 .pnpmfile.cjs(更改依赖的依赖):
🌐 Example .pnpmfile.cjs (changes the dependencies of a dependency):
function readPackage(pkg, context) {
// Override the manifest of foo@1.x after downloading it from the registry
if (pkg.name === 'foo' && pkg.version.startsWith('1.')) {
// Replace bar@x.x.x with bar@2.0.0
pkg.dependencies = {
...pkg.dependencies,
bar: '^2.0.0'
}
context.log('bar@1 => bar@2 in dependencies of foo')
}
// This will change any packages using baz@x.x.x to use baz@1.2.3
if (pkg.dependencies.baz) {
pkg.dependencies.baz = '1.2.3';
}
return pkg
}
module.exports = {
hooks: {
readPackage
}
}
已知的限制
🌐 Known limitations
通过 readPackage 从依赖的清单中移除 scripts 字段并不会阻止 pnpm 构建该依赖。在构建依赖时,pnpm 会从包的归档中读取包的 package.json,这不会受到钩子的影响。若要忽略某个包的构建,请使用 neverBuiltDependencies 字段。
🌐 Removing the scripts field from a dependency's manifest via readPackage will
not prevent pnpm from building the dependency. When building a dependency, pnpm
reads the package.json of the package from the package's archive, which is not
affected by the hook. In order to ignore a package's build, use the
neverBuiltDependencies field.
hooks.updateConfig(config): config | Promise<config>
新增于:v10.8.0
🌐 Added in: v10.8.0
允许你修改 pnpm 使用的配置设置。当与 configDependencies 配合使用时,此钩子最为有用,它可以让你在不同的 Git 仓库之间共享和重用设置。
🌐 Allows you to modify the configuration settings used by pnpm. This hook is most useful when paired with configDependencies, allowing you to share and reuse settings across different Git repositories.
例如,@pnpm/plugin-better-defaults 使用 updateConfig 钩子来应用一组精心挑选的推荐设置。
🌐 For example, @pnpm/plugin-better-defaults uses the updateConfig hook to apply a curated set of recommended settings.
使用示例
🌐 Usage example
module.exports = {
hooks: {
updateConfig (config) {
return Object.assign(config, {
enablePrePostScripts: false,
optimisticRepeatInstall: true,
resolutionMode: 'lowest-direct',
verifyDepsBeforeRun: 'install',
})
}
}
}
hooks.afterAllResolved(lockfile, context): lockfile | Promise<lockfile>
允许你在序列化之前更改锁定文件输出。
🌐 Allows you to mutate the lockfile output before it is serialized.
参数
🌐 Arguments
lockfile- 序列化到pnpm-lock.yaml的锁文件解析对象。context- 步骤的上下文对象。方法#log(msg)允许你为该步骤使用调试日志。
使用示例
🌐 Usage example
function afterAllResolved(lockfile, context) {
// ...
return lockfile
}
module.exports = {
hooks: {
afterAllResolved
}
}
已知限制
🌐 Known Limitations
没有——任何可以通过锁文件完成的操作都可以通过这个函数修改,你甚至可以扩展锁文件的功能。
🌐 There are none - anything that can be done with the lockfile can be modified via this function, and you can even extend the lockfile's functionality.
hooks.beforePacking(pkg): pkg | Promise<pkg>
新增于:v10.28.0
🌐 Added in: v10.28.0
允许你在 pnpm pack 或 pnpm publish 期间将 package.json 清单打包为 tar 包之前进行修改。这对于在不影响本地开发的 package.json 的情况下自定义发布的包非常有用。
🌐 Allows you to modify the package.json manifest before it is packed into a tarball during pnpm pack or pnpm publish. This is useful for customizing the published package without affecting your local development package.json.
与在安装过程中修改依赖解析方式的 hooks.readPackage 不同,beforePacking 仅影响最终发布的压缩包的内容。
🌐 Unlike hooks.readPackage, which modifies how dependencies are resolved during installation, beforePacking only affects the contents of the tarball that gets published.
参数
🌐 Arguments
pkg- 将包含在发布的 tar 包中的包清单对象。
使用示例
🌐 Usage example
function beforePacking(pkg) {
// Remove development-only fields from published package
delete pkg.devDependencies
delete pkg.scripts.test
// Add publication metadata
pkg.publishedAt = new Date().toISOString()
// Modify package exports for production
if (pkg.name === 'my-package') {
pkg.main = './dist/index.js'
}
return pkg
}
module.exports = {
hooks: {
beforePacking
}
}
此钩子所做的修改仅影响压缩包内的 package.json。你本地的 package.json 文件保持不变。
🌐 The modifications made by this hook only affect the package.json inside the tarball. Your local package.json file remains unchanged.
hooks.preResolution(options): Promise<void>
此钩子在读取和解析项目的锁文件之后执行,但在解析依赖之前执行。它允许对锁文件对象进行修改。
🌐 This hook is executed after reading and parsing the lockfiles of the project, but before resolving dependencies. It allows modifications to the lockfile objects.
参数
🌐 Arguments
options.existsCurrentLockfile- 如果node_modules/.pnpm/lock.yaml位置的锁文件存在,则布尔值为 true。options.currentLockfile-node_modules/.pnpm/lock.yaml的锁文件对象。options.existsNonEmptyWantedLockfile- 如果pnpm-lock.yaml位置的锁文件存在,则布尔值为 true。options.wantedLockfile-pnpm-lock.yaml的锁文件对象。options.lockfileDir- 所需锁文件所在的目录。options.storeDir- 存储目录的位置。options.registries- 范围到注册表 URL 的映射。
hooks.importPackage(destinationDir, options): Promise<string | undefined>
这个钩子允许更改如何将包写入 node_modules。返回值是可选的,用于说明用于导入依赖的方法,例如:克隆、硬链接。
🌐 This hook allows to change how packages are written to node_modules. The return value is optional and states what method was used for importing the dependency, e.g.: clone, hardlink.
参数
🌐 Arguments
destinationDir- 包写入的目标目录。options.disableRelinkLocalDirDepsoptions.filesMapoptions.forceoptions.resolvedFromoptions.keepModulesDir
hooks.fetchers
此钩子允许覆盖用于不同类型依赖的获取器。它是一个对象,可能具有以下字段:
🌐 This hook allows to override the fetchers that are used for different types of dependencies. It is an object that may have the following fields:
localTarballremoteTarballgitHostedTarballdirectorygit
查找器
🌐 Finders
新增于:v10.16.0
🌐 Added in: v10.16.0
查找器功能通过 --find-by 标志与 pnpm list 和 pnpm why 一起使用。
🌐 Finder functions are used with pnpm list and pnpm why via the --find-by flag.
示例:
🌐 Example:
module.exports = {
finders: {
react17: (ctx) => {
return ctx.readManifest().peerDependencies?.react === "^17.0.0"
}
}
}
用法:
🌐 Usage:
pnpm why --find-by=react17
详情请参阅[查找器]。
🌐 See Finders for more details.
相关配置
🌐 Related Configuration
ignorePnpmfile
- 默认:假
- 类型:布尔
.pnpmfile.cjs 将被忽略。与 --ignore-scripts 一起使用非常有用,当你想确保在安装期间没有脚本被执行时。
pnpmfile
- 默认: ['.pnpmfile.cjs']
- 类型:path[]
- 示例:['.pnpm/.pnpmfile.cjs']
本地 pnpm 文件的位置。
🌐 The location of the local pnpmfile(s).
globalPnpmfile
- 默认:空
- 类型:路径
- 示例:~/.pnpm/global_pnpmfile.cjs
全局 pnpmfile 的位置。全局 pnpmfile 在安装过程中被所有项目使用。
🌐 The location of a global pnpmfile. A global pnpmfile is used by all projects during installation.
建议使用本地 pnpmfiles。只有在项目不以 pnpm 作为主要包管理器时,才使用全局 pnpmfile。
🌐 It is recommended to use local pnpmfiles. Only use a global pnpmfile if you use pnpm on projects that don't use pnpm as the primary package manager.