You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何禁止包贡献者使用Yarn安装依赖且不影响外部项目引入?

限制包贡献者使用Yarn,允许外部项目通过Yarn引入该包

我正在维护一个曾使用Yarn进行依赖管理的包,现计划转回npm。希望贡献者尝试用Yarn安装依赖时能看到错误提示(代码审查阶段也会标记相关问题,但提前告知可减少不必要的困扰)。但必须确保其他项目仍可通过Yarn引入该包,此限制仅适用于本包的贡献者。

已尝试方案

  • 使用package.json中的engines字段无法满足需求,会导致包无法被其他项目作为依赖安装。
  • 在preinstall脚本中检查npm execpath变量也不可行,因为该脚本在外部项目安装包时也会执行,破坏其安装流程。

需求

需要在preinstall脚本中区分本地贡献者和包作为依赖的安装场景,实现如下代码中的isLocalDev函数:

// 该脚本在npm "preinstall"钩子阶段运行

const isYarn = () => process.env.npm_execpath.includes('yarn');
const isLocalDev = () => /* ??? */;

if (isYarn() && isLocalDev()) {
  console.error('本项目依赖管理禁止使用Yarn,请使用npm!');
  process.exit(1);
}

实现方案

以下几种方法可实现isLocalDev函数,精准区分两种场景:

方法1:检查.git目录(最可靠)

贡献者克隆仓库后,本地项目根目录会存在.git文件夹;而包作为依赖被安装到外部项目的node_modules时,不会包含该目录。代码实现:

const fs = require('fs');
const path = require('path');

const isLocalDev = () => {
  return fs.existsSync(path.join(process.cwd(), '.git'));
};

方法2:验证包根目录

通过读取当前目录的package.json,验证其包名是否与你的包一致,判断是否处于本地开发场景:

const fs = require('fs');
const path = require('path');

const isLocalDev = () => {
  try {
    const pkgPath = path.join(process.cwd(), 'package.json');
    const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
    // 替换为你的包实际名称
    return pkg.name === 'your-package-name';
  } catch (err) {
    return false;
  }
};

方法3:利用npm环境变量

借助npm的npm_config_local_prefix环境变量,判断当前工作目录是否为包的根目录:

const path = require('path');

const isLocalDev = () => {
  // 本地开发时,执行install命令的目录就是包根目录,与当前工作目录一致
  return process.env.npm_config_local_prefix === process.cwd();
};

内容的提问来源于stack exchange,提问作者Duncan Thacker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:37:51