简体   繁体   English

用自己的实现替换npm包

[英]Substitute an npm package with own implementation

In my package.json I have a dependency "protractor": "2.1.0" . 在我的package.json中,我有一个依赖"protractor": "2.1.0" That package in turn depends on "jasminewd2": "0.0.5" . 该包依次取决于"jasminewd2": "0.0.5"

That jasminewd2 package has some behavior which I want to modify. 那个jasminewd2包有一些我想要修改的行为。 I downloaded its sources and made the changes I need. 我下载了它的源代码并进行了我需要的更改。 Yarn's documentation tells about a possibility to use a local source for packages: Yarn的文档说明了使用本地源包的可能性:

yarn add file:/path/to/local/folder installs a package that is on your local file system. yarn add file:/path/to/local/folder安装本地文件系统上的软件包。 This is useful to test out other packages of yours that haven't been published to the registry. 这对于测试未发布到注册表的其他您的包非常有用。

When I execute that command 当我执行该命令时

  1. "jasminewd2": "file:\\\\CustomNodeModules\\\\jasminewd2" gets added to my package.json . "jasminewd2": "file:\\\\CustomNodeModules\\\\jasminewd2"被添加到我的package.json中
  2. And this to my yarn.lock file: 这到我的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" 

As a result, node_modules/jasminewd2 contains the original version from the npm repository. 因此, node_modules/jasminewd2包含npm存储库中的原始版本。 How can I make yarn install my version instead? 如何让纱线安装我的版本?

I believe your solution doesn't work because jasminewd2 is a transitive dependency (of protractor ) and not a direct one. 我相信你的解决方案不起作用,因为jasminewd2是一个传递依赖( protractor )而不是直接依赖。 So when you add it directly, the transitive one isn't affected. 因此,当您直接添加时,传递的不受影响。

You can work around that using two approaches: 您可以使用两种方法解决这个问题:

  1. In case your change is temporary (meant for development or troubleshooting), you should yarn link as described in the documentation . 如果您的更改是临时的(用于开发或故障排除),您应该按照文档中的说明进行 yarn link
  2. Otherwise, you can fork both protractor and jasminewd2 packages and reference them in the respective package.json s. 否则,您可以分叉protractorjasminewd2包并在相应的package.json引用它们。 package.json s syntax for that is "protractor": "<githubUser>/<githubRepo>" . package.json语法"protractor": "<githubUser>/<githubRepo>"

From my experience, the second approach has a caveat in the form of npm's cache: your git repo's HEAD is only pulled when that dependency is first installed . 根据我的经验,第二种方法有一个npm缓存形式的警告:只有在首次安装该依赖项时才会拉出你的git repo的HEAD After that, it is kept cached and keeps getting reinstalled every time - even when your repo's HEAD has changed. 在那之后,它会被缓存并且每次都会重新安装 - 即使你的repo的HEAD已经改变了。

That's why I usually reference a commit hash as part of the dependency like so: "dependency": "user/repo.git#aef38fb2adc73304ae1ea87b0d607ad7fadc4d0g" . 这就是为什么我通常引用提交哈希作为依赖的一部分,如下所示: "dependency": "user/repo.git#aef38fb2adc73304ae1ea87b0d607ad7fadc4d0g" I didn't try this trick with yarn , but assume it behaves the exact same way (by design via the lockfile). 我没有用yarn尝试这个技巧,但假设它的行为完全相同(通过锁定文件设计)。

Overriding a submodule using postinstall and git 使用postinstall和git覆盖子模块

The " npm way " requires a specific commit (or version/tag) to install a package from a git repository, more info on npm install . npm方式 ”需要特定的提交(或版本/标记)来从git存储库安装包, 有关npm install的更多信息 I usually create a custom branch and push on that, so I wanted the possibility to clone a custom branch for testing a specific feature or just leaving master alone. 我通常会创建一个自定义分支并推送它,因此我希望能够克隆自定义分支以测试特定功能或者只留下主人。

To override a package I use the postinstall hook hook of npm. 要覆盖一个包,我使用npm的postinstall钩子钩子。

I add a script to postinstall in package.json : 我在package.json添加了一个脚本到postinstall

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

Then I use a bash script ( postinstall.sh ) for removing packages and cloning them from github: 然后我使用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

The script clones a package in the custom_modules folder, then it uses npm to install the local package to node_modules . 该脚本克隆custom_modules文件夹中的包,然后使用npm将本地包安装到node_modules The branch name after : is optional. 分支名之后:是可选的。

In the case of OP should be something like this: 在OP的情况下应该是这样的:

override_pkg johndoe jasminewd:jasminewd2 jasminewd2

Then yarn: 然后纱线:

yarn

If I do some local changes on the local git repository in custom_modules\\mypackage I call yarn again for re-override the pacakge. 如果我在custom_modules\\mypackage对本地git存储库进行一些本地更改,我再次调用yarn来重新覆盖pacakge。

If I change machine and I got already a local version of my custom package, then calling yarn will pull from the repository and override the pacakge. 如果我更换机器并且我已经获得了我的自定义包的本地版本,那么调用yarn将从存储库中拉出并覆盖pacakge。

PS. PS。 npm install works too, but yarn is a bit faster. npm install也可以,但yarn更快一点。

Multiple environments for testing purposes 用于测试目的的多个环境

This is a different idea, but sometimes I used it for testing different configurations. 这是一个不同的想法,但有时我用它来测试不同的配置。 Maybe people can find it useful or if anyone knows a tool or something for doing this, please tell me. 也许人们会发现它很有用,或者如果有人知道这样做的工具或其他东西,请告诉我。

Locally I create two distinct folders for node_modules like this: 在本地我为node_modules创建两个不同的文件夹,如下所示:

First the original modules: 首先是原始模块:

yarn --modules-folder=original-modules

Flags: 标志:

  • --modules-folder <path> rather than installing modules into the node_modules folder relative to the cwd, output them here. --modules-folder <path>而不是将模块安装到相对于cwd的node_modules文件夹中,在这里输出它们。

Then for the custom ones, I can simply copy original-modules for a clone: 然后对于自定义的,我可以简单地复制original-modules的克隆:

cp -r original-modules custom-modules

Or I can use yarn to add more custom modules: 或者我可以使用纱线添加更多自定义模块:

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

Flags: 标志:

  • --no-lockfile don't read or generate a lockfile --no-lockfile不读取或生成锁文件

When I'm happy with the custom-modules folder I can switch between environments like this using NODE_PATH : 当我对custom-modules文件夹感到满意时,我可以使用NODE_PATH在这样的环境之间切换:

For the normal env: 对于正常的环境:

NODE_PATH=original-modules npm start

Custom envrionment: 定制环境:

NODE_PATH=custom-modules npm start

It is important that the node_modules folder does not exist or the override will not work, the local node_modules folder has higher priority than NODE_PATH . node_modules文件夹不存在或覆盖不起作用很重要,本地node_modules文件夹的优先级高于NODE_PATH

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM