【问题标题】:how to make npm install dependencies on custom location and avoid wrapping in node_modules?如何使 npm install 依赖于自定义位置并避免包装在 node_modules 中?
【发布时间】:2018-12-05 08:31:12
【问题描述】:

我已经发布了一个包 parent-package,它有一个依赖项,它是另一个名为 child-package 的包,它已经在 npm 上发布了。当我安装父包时,它被包裹在 node_modules 中,它的依赖项也被包裹在与父包相同级别的 node_modules 中。我不希望 parent_package 被包装在 node_modules 中,并且 child-package 应该存储在项目文件夹下,因为在我的情况下 child-package 是一个独立的库,将在 parent-package 中使用。根据默认行为,我的文件夹结构如下所示;

Present Working Director: |-- node_modules |-- parent-package |-- child-package |-- other dependencies

我想在安装时默认实现这个文件夹结构;

Present Working Director: |-- parent-package |-- projects |-- child-package |-- other libraries |-- src

如何更改 npm 安装的默认行为来实现这种结构?任何帮助将不胜感激。

【问题讨论】:

    标签: angular dependencies npm-install


    【解决方案1】:

    您可以采用两种、三种(或更多)方式来解决这个问题:npm 方式和 Angular 方式。

    npm 方式

    一种方法是对 npm 使用postinstall 脚本 - 正如您所怀疑的,在安装软件包后执行。下面是一个幼稚的例子。

    将此添加到package.json

    "scripts": {
      ...
      "postinstall": "./postinstall.sh"
    }
    

    并创建一个postinstall.sh bash 脚本:

    #!/bin/sh
    cp -r node_modules/parent_project .
    cp -r node_modules/child_package ./parent_project
    ...other things to copy.
    

    这将创建您想要的结构。

    请注意,这存在一些问题。一个是,这不完全是跨平台的。另一个问题是它会在一些较旧的 npm 版本上失败(将依赖项嵌套在嵌套的 node_modules 中)。最后,我会非常警惕将脚本直接复制到我的源文件夹的包,除非明确指定和说明,否则可能会覆盖内容。

    所有这些问题都可以解决,但需要一些思考。

    角度方式

    Angular 方式实际上是其中的一部分。最直接的方法是创建一个 Angular Schematic 并发布它,而不是直接发布库。

    当我使用 npm 库时,我希望它位于 node_modules 中,而不是在我的源代码中。我不希望它在我的来源中,只是我实际导出的东西。例如。 @angular/core 本身在 node_modules 中,不会妨碍我。

    原理图

    但是当我确实希望这个库以某种方式帮助我时,我希望它是明确的——通过调用一个命令。 Angular Schematics 为您提供了这个。

    stackoverflow 的答案太复杂了,无法详细说明您的问题。您最好在线阅读 Schematics,例如this 教程可以帮助你。然后,如果您遇到具体问题,请返回 SO 并提出具体问题。

    Monorepo

    如果您只是为自己开发包,另一种可能的方法是使用 Monorepo 策略,例如,ng-packager 来处理您的“子包”和库。

    其他生成器

    您也可以将其作为 yeoman 生成器、独立的 github 包或许多其他方式来生成一些源。查看代码生成工具,将您的东西设置为代码模板并使用代码生成器复制所需的结构。


    编辑:您在 cmets 中提到您想采用“npm 方式”,但您提到了一个用例,您似乎希望将 npm 库和可编辑包合二为一。那么为什么不这样对待呢?这显然不仅仅是“npm 方式”,因为修改源不是 npm 安装/更新机制的用途——它是用来管理依赖关系的。

    同时使用(双关语)最简单的方法是使用 npm 安装/更新机制来管理“用作库”用例,并使用常规 git 来管理“用作源”用例。

    将您的父项目作为常规 Angular 项目 (new new parent)。然后在该项目中,还创建一个库 (ng generate library child)。

    最后,在tsconfig 路径中有一个指向dist/library/ 的引用,因此您只能在父项目中使用“已编译”版本的库。

    现在,像这样设置你的 npm 脚本:

    "build.parent": "regular parent build stuff"
    "build.child": "build the child library"
    "publish.parent": "stuff to publish the parent to npm"
    "publish.lib": "ng-packagr stuff to publish the library to npm"
    

    所以,用例:

    1. 您只想将这些用作 npm 库。超级简单直接。

      npm install parent-package child-package --save-dev

    2. 你想要本地的东西:

      git clone github.com/you/repo.git

    现在您可以使用本地版本和库版本。但说真的,不要。如果它是一个库,那么它就是一个库。否则,当 git 为此创建时,不要使用 npm 管理它,版本控制。

    如果你弄乱了你的 npm 安装,如果你在进行 npm 安装时去修改源,这会带来不好的事情。你想避免它。

    但是,如果您真的必须这样做,那么安装后脚本应该这样做。但是这些脚本确实需要先进,足够聪明,才能检测到你已经更新了项目,有合理的合并策略,迁移等。最终你实际上编写了一个 Angular Schematic,而不是使用 Angular。

    【讨论】:

    • 我想以 npm 方式进行。但是安装更新不会因为手动操作目录结构而产生问题吗?
    • 实际上,我希望子包在安装到父包后可以编辑,以便用户可以对其初始结构进行所需的增强,并且它也应该作为一个独立的库。如果我操纵目录结构,它可以正常工作,但是当我尝试在 npm 上使用最新版本更新子包时会出现问题。 NPM 尝试在 node_modules 中查找它,即使尝试使用像这样的 --prefix 参数更新它“ npm install --prefix ./projects/ child-package@lates --save ”并且它在那里找不到它。跨度>
    • 继续之前的评论,因此它不会更新已放置在项目目录下的子包,而是在项目下创建新目录 node_module 并将其放置在那里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 2016-01-13
    • 2020-04-06
    • 2017-09-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    相关资源
    最近更新 更多