本机反应: npm 链接本地依赖,无法解析模块

我正在开发一个反应本机按钮 UI 包。我尝试构建一个示例项目来测试这个按钮。目录结构如下:

my-button/
package.json
index.js
example/
package.json
index.js

我尝试使用 npm link:

cd my-button
npm link


cd example
npm link my-button

example/node_modules/中我可以看到我的按钮符号链接,VSCode 也可以在我的按钮包中自动完成功能。

但是执行示例应用程序会显示错误:

Unable to resolve module my-button ...
Module does not exist in the module map or in these directories: ...

但是错误消息中的路径是正确的。

不知道我哪里错了,或者在 React-Native 有什么特别的方法来处理链接本地依赖?

我也试了 npm install file:../.。它以这种方式工作得很好,但是在编辑 my-Button 之后在 example/中更新依赖关系并不容易。

37673 次浏览

换包裹吧 Json

//...
"dependencies": {
//...
"my-button" : "file:../"
},
//...

遇到了同样的问题。虽然我不能使 npm link按照它应该的方式工作,但是我通过在项目文件夹中安装本地包来解决这个问题

npm install ../<package-folder> --save

这将安装包像一个普通的包,但从本地文件夹。 缺点是您对包所做的更改不会被反映出来。每次改变之后你必须做 npm install

npm link命令不起作用,因为 React Nativepackager 不支持符号链接

经过一些研究,我发现有两种方法可以做到这一点。

  1. 在例子 app 中使用 运输包装机运输包装机。 Haul 支持符号链接,所以你可以像往常一样使用 npm link
  2. 通过 file:../使用本地依赖项,然后在 node_modules文件夹中编辑文件,或者每次更改时重新安装。

我发现 非常适合这个用例,甚至可以设置一个包含 故事书刚开始的小项目,如果您有许多组件可以切换的话,这非常有帮助。

试着逃跑

npm run watch

在纽扣包里。目前,我正在使用它将库中的更改应用到我的主项目中。如果有用请告诉我!

试试 Wml(https://github.com/wix/wml)

它是 npm link的一种替代方法,实际上可以将更改过的文件从源文件夹复制到目标文件夹

# add the link to wml using `wml add <src> <dest>`
wml add ~/my-package ~/main-project/node_modules/my-package


# start watching all links added
wml start

我在围绕现有的本机 SDK 开发本机模块包装器时遇到了同样的问题。起初,我按照@aayush-shrestha 的建议在本地安装软件包。像这样:

npm install ../<package-folder> --save

只要我通过 NativeModules引用这个模块,它就可以工作。导入它:

import { NativeModules } from 'react-native';

然后访问一个名为 ActualModuleName的模块,如下所示:

NativeModules.ActualModuleName

但是,当我试图按名称导入模块时,它失败了:

import { ActualModuleName } from 'react-native-actualmodulename'

为了实现这个功能,我必须首先打包这个包,在这个包的根目录下运行它:

npm pack

这将生成一个 gzip 压缩的 tarball:

react-native-actualmodulename-1.0.0.tgz

现在把它安装到你的应用程序中:

npm install <path/to>/react-native-actualmodulename-1.0.0.tgz

这样做的一个巨大缺点是,每次更改模块时都必须重新打包包。我所知道的唯一解决方法是直接在 node_modules中修改包的文件,然后在修改完成后将这些修改复制回您的回购。

但是好的一面是,你的应用程序的源代码可以导入 ActualModuleName,就像你通过 npm发布后导入它一样; 不需要特定于环境的代码。

我不能总是让它与纱线链接工作。我发现额外的有用的是 Yalc:

首先在全球范围内永远安装一次:

npm install -g yalc

在本地库/包中(我称之为 my-local-package) ,然后运行:

yalc publish

然后,在使用 my-local-package 作为依赖项的项目中,运行: (如果您已经添加了任何其他方式,首先卸载它(npm uninstall -S my-lockal-package)

yalc add my-local-package
npm install

如果 my-local-package 是一个本机模块,那么运行 react-native run-android来链接依赖项

如果你对我的“本地包裹”做了任何改动,那么:

cd path/of/my-local-package
yalc push //updates the local package
cd path/to/my-project
npm install
react-native run-android (or run-ios)

如果没有应用更新,请尝试执行 cd android && ./gradlew clean && cd ..,然后重新运行: react-native run-android

对于那些仍然在寻找一个没有其他依赖性的简单解决方案的人,试试这个:

yarn --version
1.21.1


npm --version
6.13.4
  1. 在项目根目录中安装
cd my-button
yarn install or npm install
  1. 在我的-按钮中的寄存器链接
yarn link or npm link
  1. 安装示例项目
cd example
yarn add ../ or npm add ../
  1. 链接到我的按钮
yarn link my-button or npm link my-button
  1. 完整的吊舱安装(如有必要)
cd ios
pod install

我也遇到了同样的问题。

我尝试使用 npm安装一个本地模块,但一直遇到无法解析该模块的问题,尽管我可以看到 node _ module 中的文件夹以及类和方法名的自动完成工作。

在看到这个在 github 上打开的 问题之后,我可以通过使用 yarn而不是 npm安装本地库来绕过它。发行于2020年9月,目前 Facebook 尚未发表任何评论。

您可以使用 Metro 使用 npm 链接。只需将链接包的源文件夹添加到 metro.config.js中的 watchFolders即可。

这对我有用:

第一步:

npm link packageNameHere

这将把这个包链接到全局 node _ module

步骤2转到您想要使用这个包的目录并运行这些

npm link pathToPackageDirectory
npm install pathToPackageDirectory

例如: npm link ~/myDemoPackage

这将把全局 node _ moudle 链接到这个项目

如果要将包导入到文件中,请使用文件路径代替包名!

例如:

我的包名是 stripe-api-helper,我的代码在 src/index.ts 中 那么我需要像这样解决:

import { postStripe, Item } from '@aliciaForDemo/stripe-api-helper/src'

如果使用“@aliciaForDemo/stripe-api-helper”,它将失败。

我也遇到了这个问题。在访问了下面的链接之后,我了解到 response-national 不支持符号链接。[点击这里][1]

但是,我已经通过在 Metro.config.js 文件中添加这些代码行解决了这个问题。

const path = require('path');


const thirdPartyPath = path.resolve(__dirname + '/../your_module_name/');  // Path of your local module


const thirdParty= {
'your_module_name': thirdPartyPath,
};


const watchFolders = [ thirdPartyPath];


module.exports = {
// existing dependencies
resolver: {
thirdParty,
},
watchFolders
};

使用任何其他建议都无法让我自己的环境正常工作,但是我发现了一个可以很好地工作(尽管不是很理想)的技巧,它可以很容易地在几行代码中建立起来,而且不需要改变 RN 项目的配置。

使用 fs.watch来递归地更改您正在处理库的目录,并在发生更改时复制更新:

import fs from 'fs'


const srcDir = `./your-library-directory`
const destDir = `../your-destination-directory`


fs.watch("./src/", {recursive: true}, () => {
console.log('copying...')
fs.cp(srcDir, destDir, { overwrite: true, recursive: true }, function() {
console.log('copied')
})
})