用自己的实现替换 npm 包
Substitute an npm package with own implementation
在我的 package.json 我有一个依赖关系 "protractor": "2.1.0"
。该包又取决于 "jasminewd2": "0.0.5"
.
那个 jasminewd2
包有一些我想修改的行为。我下载了它的源代码并进行了我需要的更改。 Yarn's documentation 讲述了使用本地资源包的可能性:
yarn add file:/path/to/local/folder
installs a package that is on your local file system. This is useful to test out other packages of yours that haven’t been published to the registry.
当我执行那个命令时
"jasminewd2": "file:\CustomNodeModules\jasminewd2"
被添加到我的 package.json.
这是我的 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 安装我的版本?
我认为您的解决方案不起作用,因为 jasminewd2
是(protractor
的)传递依赖,而不是直接依赖。所以当你直接添加它时,传递的不受影响。
您可以使用 3 种方法解决此问题:
- 如果您的更改是临时的(用于开发或故障排除),您应该
yarn link
如 documentation 中所述。
- 否则,您可以分叉
protractor
和 jasminewd2
包并在各自的 package.json
中引用它们。 package.json
s syntax for that 是 "protractor": "<githubUser>/<githubRepo>"
.
- 使用
yarn
的 resolutions
field:"resolutions": { "jasminewd2": "desired-version-or-url-or-path" }
。我知道 PNPM 也有类似的功能(但我自己没用过)。
根据我的经验,选项 2 和 3 以包管理器缓存的形式存在警告:您的 git 存储库的 HEAD
仅在该依赖项首先 时被拉出安装。之后,它每次都会被缓存并重新安装 - 即使您的回购协议 HEAD
已更改。
解决方法是引用一个提交散列作为依赖的一部分,如下所示:"dependency": "user/repo.git#aef38fb2adc73304ae1ea87b0d607ad7fadc4d0g"
.
使用 postinstall 和 git
覆盖子模块
“npm 方式”需要特定的提交(或 version/tag)才能从 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=
REPO=
DEST=
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
将从存储库中提取并覆盖包。
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
.
在我的 package.json 我有一个依赖关系 "protractor": "2.1.0"
。该包又取决于 "jasminewd2": "0.0.5"
.
那个 jasminewd2
包有一些我想修改的行为。我下载了它的源代码并进行了我需要的更改。 Yarn's documentation 讲述了使用本地资源包的可能性:
yarn add file:/path/to/local/folder
installs a package that is on your local file system. This is useful to test out other packages of yours that haven’t been published to the registry.
当我执行那个命令时
"jasminewd2": "file:\CustomNodeModules\jasminewd2"
被添加到我的 package.json.这是我的 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 安装我的版本?
我认为您的解决方案不起作用,因为 jasminewd2
是(protractor
的)传递依赖,而不是直接依赖。所以当你直接添加它时,传递的不受影响。
您可以使用 3 种方法解决此问题:
- 如果您的更改是临时的(用于开发或故障排除),您应该
yarn link
如 documentation 中所述。 - 否则,您可以分叉
protractor
和jasminewd2
包并在各自的package.json
中引用它们。package.json
s syntax for that 是"protractor": "<githubUser>/<githubRepo>"
. - 使用
yarn
的resolutions
field:"resolutions": { "jasminewd2": "desired-version-or-url-or-path" }
。我知道 PNPM 也有类似的功能(但我自己没用过)。
根据我的经验,选项 2 和 3 以包管理器缓存的形式存在警告:您的 git 存储库的 HEAD
仅在该依赖项首先 时被拉出安装。之后,它每次都会被缓存并重新安装 - 即使您的回购协议 HEAD
已更改。
解决方法是引用一个提交散列作为依赖的一部分,如下所示:"dependency": "user/repo.git#aef38fb2adc73304ae1ea87b0d607ad7fadc4d0g"
.
使用 postinstall 和 git
覆盖子模块“npm 方式”需要特定的提交(或 version/tag)才能从 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=
REPO=
DEST=
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
将从存储库中提取并覆盖包。
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
.