我正在管理一个最近使用yarn进行依赖管理的包,但由于各种问题,我正在重新使用npm。为了帮助贡献者,我希望他们在尝试使用纱线安装依赖项时看到错误。这并不是绝对必要的,因为他们的贡献将在代码审查阶段被标记,但为了减少他们的挫败感,我想让他们尽早知道不再允许使用纱线。
但是,重要的是其他项目可以使用纱线导入我们 - 此限制必须仅适用于该包的贡献者。
使用
engines
中的 package.json
字段不起作用(请参阅https://stackoverflow.com/a/58087572/5009210),因为我的包拒绝作为其他项目的依赖项安装。
同样,在预安装脚本 (https://stackoverflow.com/a/57329003/5009210) 期间检查 npm execpath 变量会中断其他项目的安装,因为该脚本也在安装过程中运行。
我需要在预安装脚本中使用某种方法来区分本地贡献者和作为依赖项的包的安装。所以我需要一个函数到这里:
#!/usr/bin/env node
// This script runs during the npm "preinstall" hook
const isYarn = () => process.env.npm_execpath.includes('yarn');
const isLocalDev = () => /* ??? */;
if (isYarn() && isLocalDev()) {
console.error('Yarn not allowed for dependency management!');
process.exit(1);
}
我确实尝试过这个选项:
// compare the current working directory, which should be my project root
// to the cwd where the original install script was run, which is either my project root
// or the root of a project that uses my package
const isLocalDev = () => process.cwd() === process.env.INIT_CWD;
...但这可能不是很可靠,因为安装脚本可以从项目树中的任何位置运行,所以我需要做更多的逻辑来弄清楚 INIT_CWD 的真正行为。
这是我使用的方法:
const fs = require('fs');
// My cypress dir is not part of the published package,
// so if it's present then we must be doing local dev.
const isLocalDev = () => fs.existsSync('./cypress');
仅当您的
package.json
使用 "files"
选项指定已发布目录时,这才有效(请参阅 https://docs.npmjs.com/cli/v10/configuring-npm/package-json#files)。只需确保您选择的目录或文件不属于已发布的包,即使您在子目录中运行纱线,此解决方案也能像梦想一样工作。
我希望你发现这个技巧很有用!