使用本地项目的“npm install”意外行为

时间:2018-04-01 10:42:09

标签: npm npm-link

方案

  • 我正在使用npm 5.8.0
  • 我有ProjectAProjectB
  • ProjectBProjectA
  • 的依赖关系
  • 这两个项目都是捆绑在一起并通过Webpack运行(如果需要,我可以提供我的配置)。

出于开发目的,我通过ProjectBProjectA的package.json中引用"projectB": "file:../projectB"。基本上我需要的唯一文件位于lib文件夹中,这是Webpack的输出。

问题

如果我使用上面的配置安装此依赖项,npm会将整个ProjectB - 文件夹安装到node_modules中。它将包含projectB的所有node_modules,配置文件,src文件夹等。

除了这不是预期的行为之外,这会导致错误。例如,某些已安装的@types会抛出错误,因为它们被视为重复。来自ProjectAProjectB的@types和其他软件包似乎“发生冲突”。这些包主要在"dependencies"ProjectA中引用为ProjectB

我尝试了什么

npm link

如果我使用npm链接,则会出现相同的(见上文)行为。整个文件夹将安装到ProjectA的node_modules中。

npm pack

可能重要我确实在.npmignore中有ProjectB个文件。因此,当我使用npm pack生成projectB.tgz文件时。如果我然后通过ProjectB安装"projectB": "file:../projectB.tgz",一切正常。我假设npm pack确实考虑了.npmignore - 文件。

我对此解决方案的问题是,我不仅需要在每次应用更改时构建ProjectB,还要npm pack

删除ProjectB的node_modules

我想这是最愚蠢的解决方法。如果我再次通过ProjectB引用"projectB": "file:../projectB"但在构建之后删除其node_modules,则在安装后不会显示它们。因此,我没有任何例外。

我想这不是一个有效的解决方案,因为仍然安装了整个ProjectB - 文件夹。

问题

这里的最佳做法是什么?为了从本地来源安装ProjectAProjectBProjectB的合理定制是什么?

3 个答案:

答案 0 :(得分:1)

如果projectA需要来自projectB/lib的文件,则可以按以下方式配置webpack的resolver(假设webpack 4):

resolve {
  alias: "projectB": "projectB/lib"
}

如果projectB是一个模块,则package.json应该包含相应的入口点(请参见this page)。

我还建议您尝试使用yarn而不是npm进行软件包管理。 Yarn的workspaces功能旨在用于多个相互依赖的程序包。

答案 1 :(得分:0)

您可以尝试将以下代码放入projectB的package.json文件中吗?

"files": [
    "lib/*"
]

这应该告诉所有npm安装只使用Array中指定的文件。您显然可以使用更多条目来扩展它们。有关更多详细信息,请参见documentation

答案 2 :(得分:0)

您可以在webpack配置中为项目A别名projectB/lib。这将告诉webpack在解析projectB模块时要在projectB的lib文件夹中查找。

示例webpack.config:

{
    resolve: {
        alias: {
            "projectB": path.resolve(__dirname, '../projectB/lib')
        }
    }
}

此外,如果projectA是将安装在另一个项目中的实用程序库,则使projectB成为projectA的peerDependency。这样,在安装projectA时,如果未安装projectB或安装了错误的版本,用户将收到警告。

示例package.json:

{
    "peerDependencies": {
        "projectB": "1.0.0"
    }
}