【问题标题】:Substitute an npm package with own implementation用自己的实现替换 npm 包
【发布时间】:2016-11-03 10:11:55
【问题描述】:

在我的 package.json 中,我有一个依赖项 "protractor": "2.1.0"。该软件包又依赖于"jasminewd2": "0.0.5"

那个jasminewd2 包有一些我想修改的行为。我下载了它的源代码并进行了我需要的更改。 Yarn's documentation 讲述了使用本地资源包的可能性:

yarn add file:/path/to/local/folder 安装本地文件系统上的软件包。这对于测试您尚未发布到注册表的其他包很有用。

当我执行那个命令时

  1. "jasminewd2": "file:\\CustomNodeModules\\jasminewd2" 被添加到我的 package.json
  2. 这是我的 yarn.lock 文件:

    "file:\\CustomNodeModules\\jasminewd2", jasminewd2@0.0.5:
      name jasminewd2
      version "0.0.5"
      resolved "https://registry.yarnpkg.com/jasminewd2
         /-/jasminewd2-0.0.5.tgz#528609a124dfc688c1e3f434a638e047066cd63e"
    

因此,node_modules/jasminewd2 包含来自 npm 存储库的原始版本。如何让 yarn 安装我的版本?

【问题讨论】:

    标签: javascript npm yarnpkg


    【解决方案1】:

    我相信您的解决方案不起作用,因为jasminewd2 是传递依赖项(protractor)而不是直接依赖项。所以当你直接添加它时,传递的不受影响。

    您可以使用 3 种方法解决这个问题:

    1. 如果您的更改是临时的(用于开发或故障排除),您应该按照documentation 中的说明yarn link
    2. 否则,您可以分叉protractorjasminewd2 包并在各自的package.jsons 中引用它们。 package.jsons syntax for that"protractor": "<githubUser>/<githubRepo>"
    3. 使用yarnresolutionsfield:"resolutions": { "jasminewd2": "desired-version-or-url-or-path" }。我知道 PNPM 也有一个等效的功能(但我自己没有使用过)。

    根据我的经验,选项 2 和 3 以包管理器缓存的形式有一个警告:您的 git repo 的 HEAD 仅在该依赖项首次安装时才会被提取。之后,它每次都会被缓存并重新安装——即使你的 repo 的HEAD 已更改。

    解决方法是引用提交哈希作为依赖项的一部分,如下所示:"dependency": "user/repo.git#aef38fb2adc73304ae1ea87b0d607ad7fadc4d0g"

    【讨论】:

    • link 的问题是 package.json 中没有写入任何内容,因此每次我们的 CI 服务器在干净的文件夹中构建项目时都必须执行此操作。换句话说yarn install 突然不足以准备构建环境。
    • 在这种情况下,我认为您唯一的选择是分叉protractorjasminewd2 包并在各自的package.jsons 中引用它们。如果你不熟悉,here's how:"protractor": "<githubUser>/<githubRepo>".
    • 谢谢,成功了。您可以修改您的答案并包含第二种方法吗?那我就接受了。
    • @Monsignor 完成,我添加了更多细节 :) 谢谢!
    • 另一种使用 Yarn 2 临时修复软件包的好方法是使用 yarn patch 对其进行修补。
    【解决方案2】:

    使用 postinstall 和 git 覆盖子模块

    npm 方式”需要特定的提交(或版本/标签)才能从 git 存储库 more info on npm install 安装包。我通常会创建一个自定义分支并推送它,因此我希望能够克隆一个自定义分支以测试特定功能或仅保留 master。

    要覆盖一个包,我使用了 npm 的 postinstall hook 钩子。

    我在package.json中添加了一个脚本到postinstall

    "scripts": {
      "postinstall": "./postinstall.sh",
      "start": "node index.js"
    },
    

    然后我使用 bash 脚本 (postinstall.sh) 删除包并从 github 克隆它们:

    #!/bin/sh
    
    function override_pkg {
      USER=$1
      REPO=$2
      DEST=$3
    
      rm -rf node_modules/$DEST
    
      echo "Overriding $DEST..."
    
      if [ -d custom_modules/$DEST ]; then
        cd custom_modules/$DEST
        git pull
        cd ../../
      else
        case $REPO in
          *:*)
          REPOBR=(${REPO//:/ })
          git clone -b ${REPOBR[1]} https://github.com/$USER/${REPOBR[0]}.git custom_modules/$DEST
          ;;
          *)
          git clone https://github.com/$USER/$REPO.git custom_modules/$DEST
          ;;
        esac
      fi
    
      npm install custom_modules/$DEST
    }
    
    # func       user    repo   branch dest
    override_pkg johndoe myrepo:branch mynpmpackage
    

    该脚本在custom_modules 文件夹中克隆一个包,然后它使用npm 将本地包安装到node_modules: 后面的分支名称是可选的。

    在 OP 的情况下应该是这样的:

    override_pkg johndoe jasminewd:jasminewd2 jasminewd2
    

    然后纱线:

    yarn
    

    如果我在 custom_modules\mypackage 的本地 git 存储库上进行一些本地更改,我会再次调用 yarn 以重新覆盖 pacakge。

    如果我更换机器并且我已经获得了自定义包的本地版本,那么调用 yarn 将从存储库中提取并覆盖 pacakge。

    PS。 npm install 也可以,但yarn 快一点。

    用于测试目的的多个环境

    这是一个不同的想法,但有时我用它来测试不同的配置。也许人们会发现它很有用,或者如果有人知道这样做的工具或东西,请告诉我。

    我在本地为node_modules 创建了两个不同的文件夹,如下所示:

    首先是原始模块:

    yarn --modules-folder=original-modules
    

    标志:

    • --modules-folder <path> 不是将模块安装到相对于 cwd 的 node_modules 文件夹中,而是在此处输出。

    然后对于自定义的,我可以简单地复制original-modules 进行克隆:

    cp -r original-modules custom-modules
    

    或者我可以使用 yarn 添加更多自定义模块:

    yarn add <modulename> --no-lockfile --modules-folder=custom-modules
    

    标志:

    • --no-lockfile 不要读取或生成锁文件

    当我对custom-modules 文件夹感到满意时,我可以使用NODE_PATH 在这样的环境之间切换:

    对于普通环境:

    NODE_PATH=original-modules npm start
    

    自定义环境:

    NODE_PATH=custom-modules npm start
    

    重要的是node_modules文件夹不存在否则覆盖将不起作用,本地node_modules文件夹的优先级高于NODE_PATH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-10
      • 2017-09-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-22
      • 2011-06-27
      • 2020-10-29
      • 2019-11-08
      相关资源
      最近更新 更多