【问题标题】:Is it possible to break down the dependency list of a (published) package by creating new (non-published) "sub"-packages?是否可以通过创建新的(未发布的)“子”包来分解(发布的)包的依赖列表?
【发布时间】:2018-04-21 07:00:36
【问题描述】:

我维护了一个发布在 npm 注册表上的 JavaScript 库,它有很多依赖项。很难跟踪代码的哪些部分取决于哪些外部包。

不幸的是,lerna、yarn 的工作区、npm link 或 npm 的本地路径依赖关系声明都没有帮助。 (我在例子之后解释了原因。)

我希望能够通过将一些依赖项提取到新的“子包”中来分解package.json 中声明的dependencies 列表。

所以,不要有下面的依赖列表

// ~/code/example-lib/package.json
{
  "name": "example-lib",
  "dependencies": {
    "lodash": "*",
    "request": "*",
    "chalk": "*",
    "bluebird": "*",
    "mz": "*",
    "moment": "*",
    "socket.io": "*",
    "socket.io-client": "*",
    "react": "*",
    "react-dom": "*"
  }
}

我想将一些依赖项提取到一个新的本地包example-lib-subpackage 中。对于本地,我的意思是 example-lib-subpackage 仅供 example-lib 使用。

example-lib-subpackage 的依赖列表是;

// ~/code/example-lib/packages/example-lib-subpackage/package.json
{
  "name": "example-lib-subpackage",
  "dependencies": {
    "lodash": "*",
    "request": "*",
    "bluebird": "*",
    "moment": "*",
    "socket.io-client": "*",
    "react": "*",
    "react-dom": "*"
  }
}

然后example-lib的依赖列表将大大减少到;

// ~/code/example-lib/package.json
{
  "name": "example-lib",
  "dependencies": {
    "chalk": "*",
    "example-lib-subpackage": "./packages/example-lib-subpackage",
    "mz": "*",
    "socket.io": "*"
  }
}

注意example-lib 现在如何依赖本地包example-lib-subpackage;

  ...
  "name": "example-lib",
  "dependencies": {
  ...
    "example-lib-subpackage": "./packages/example-lib-subpackage",
  ...

有人做到了吗?会超级方便的。

请注意,lerna 和 yarn 的工作区功能仅在您可以将本地包发布到 npm 注册表时才有帮助。但在我的情况下,将本地包 example-lib-subpackage 发布到 npm 注册表没有意义。

另外,npm link 和 npm 的本地路径依赖功能仅适用于未发布但 example-lib 需要在 npm 注册表中的包。

将包发布到公共注册表时,不应使用本地路径 [...]。

引用https://docs.npmjs.com/files/package.json#local-paths

【问题讨论】:

  • 你为什么不用devDependencies?这看起来基本上就像您正在尝试做的事情。
  • @PatrickRoberts 因为这些不是 devDependencies,它们应该在用户安装软件包时安装。
  • 如果这些是构建代码 dst 所需的包,那么它们是 devDependencies。否则,您尝试执行的操作(如 npm 故意阻止的那样)将被视为反模式。
  • @PatrickRoberts 好的,我知道你来自哪里。 dependencies 列出了诸如 babel 和 webpack 之类的构建库,因为 buidnserve 本身就是一个构建库。因此buildnserve 用户会将buildnserve 添加到devDependencies。这就是我们想要的;在开发代码时,由库的用户决定该库是“真正的”依赖项还是仅仅是一个依赖项。
  • 啊,谢谢你提到这一点。这可能应该在您的问题中提到,因为这与您应该如何处理您的依赖组织有关。也许您可以发布一个 github 存储库并将您的构建代码链接到该存储库,而无需在 npm 上独立发布它?据我所知,除了通过以某种方式公开您想要细分的代码之外,没有真正的方法可以绕过本地链接。

标签: javascript node.js npm yarnpkg lerna


【解决方案1】:

由于package.json 只是一个 JS 对象,您可以在发布到 NPM 之前对其进行扩展。

开启prepublish:

  • 更新包版本
  • 移除 package.json 本地 example-lib-subpackage 依赖
  • 扩展example-lib 依赖项与在 example-lib-subpackage
  • 可选择在更新后的package.json 上运行一些测试
  • 发布
  • 还原原始依赖对象
  • 提交新版本

PouchDb 遵循一种模糊相似的方法,在here 和here 中有更详细的描述。

【讨论】:

  • 可能是一个有趣的项目来实现一个 lib 这样做,让我们看看我是否有时间去做。至于 PouchDb,它们似乎来自不同的地方,有着不同的目标。
  • 当然可以。但在意见中,该团队制作了关于如何处理 monorepo 项目中父包和子包之间共享依赖关系的无价文档和示例。
【解决方案2】:

我在想你可以使用构建工具来维护多个 package.jsons 并将它们编译成真正的 - 但你会一直与平台作斗争。你必须有自己的 CLI 才能安装,这会很麻烦。

你说:

请注意,lerna 和 yarn 的工作区功能只有在您没问题的情况下才有帮助 将本地包发布到 npm 注册表。但就我而言 将本地包 example-lib-subpackage 发布到 npm 注册表 没有意义。

我不认为你会找到一个完全合理的解决方案(如果你正在尝试用 npm 做完全非标准的事情),我很好奇你为什么要排除爆发example-lib-subpackage 进入它自己的仓库——这似乎是显而易见的解决方案。

【讨论】:

  • compile down to the real one 是的,我也想到了这一点,并使用 npm 的本地依赖特性来声明依赖关系。它将避免您对fighting the platform the whole way 的关注。 @toumuchdesign 的回答很好地阐述了这一点。
  • 也许我遗漏了一些东西,但是当团队想要安装新包或更新时,你不是一直在手动编辑 json 文件吗?
  • 诀窍是使用docs.npmjs.com/files/package.json#local-paths 进行开发。并且在发布时,您将解析所有本地路径到本地包的依赖项。 Npm 将不再看到任何本地路径,Local paths [...] should not be used when publishing packages to the public registry. 将不再存在。
猜你喜欢
  • 2022-01-24
  • 2013-01-21
  • 2018-08-04
  • 1970-01-01
  • 2020-05-20
  • 2011-07-12
  • 1970-01-01
  • 2019-01-12
  • 2016-08-20
相关资源
最近更新 更多