Extend `requireNodeAddon(path)` to support more use-cases
評估
這個 Issue 還沒有評估資料。
描述
Context
Currently, the requireNodeAddon() function requires only 1 string argument, which was expected to be a relative path to the compiled Node add-on. This worked great for the first few simple PoCs and demos, but it start showing its age and limitations already. In the meantime @kraenhansen in #12 added support for hashing the module paths to solve the issues of name clashes when modules are being packaged, which was later replaced by #32.
Problem statement
- The current solution does not support addons, which are imported by specifying just the package name, whose
package.jsonspecifies themainfield. - Leaking abstraction (exposes implementation details)
Proposed solution
Adding additional parameters to requireNodeAddon() that would enable the platform's add-on loader to resolve the path and try a few of them. My current suggestion is to have requireNodeAddon(requiredPath: string, targetPackageName: string, fromSubpath: string) where:
requiredPathis (in most cases) the original relative path passed to therequire()call. If this path was not relative (starting with.or..) then it should be the package name which will be resolved by looking up themainfield, making this argument a relative subpath again.packageNameshould be the name of the package that this add-on is expected to be in. Please note that such package name might be scoped, therefore - for simplicity - I've decided to keep it separated from the subpath.fromSubpathis the relative path (subpath) of the file that issued the call to therequire()function. This parameter is needed to resolve the package-relative path where the add-on is supposed to be.
Example use case 1
Somebody in ./src/index.js within package @callstack/foo wrote:
const module = require('./build/Release/foo.node');
Our Babel plugin should replace it with following:
const module = requireNodeAddon('./build/Release/foo.node', '@callstack/foo', './src/index.js');
In this case, the native loader would be able to resolve the relative path by combining ./build/Release/foo.node on top of ./src/index.js, resulting in ./src/build/Release/foo.node - which should be added to the search paths.
[!NOTE]
If the path would include the package name (especially when it's scoped), like@callstack/foo/src/build/Release/foo.node, then separating the package name from the subpath would be a little bit more convoluted (we would need to parse it). Passing those as separate arguments gives us those "for free".
Example use-case 2
Somebody in the package @callstack/foo set the main field in their package.json to ./foo.node. A different user in their package (say whatever) writes:
const { foofighter } = require('@callstack/foo');
then our Babel plugin should output:
const { foofighter } = requireNodeAddon('./foo.node', '@callstack/foo', './package.json');
Following the steps from the "algorithm" above, the relative path would be resolved to ./foo.node (it used the path from main and ./package.json gives ./), which will be expected to be in the @callstack/foo package. The exact value of the last argument is not that important here (can be ./ or . as well).
Example use-case 3
Somebody in ./src/wrapper.js that's part of package foo wrote:
const fs = require('node:fs');
Our Babel plugin is expected to output this instead:
const fs = requireNodeAddon('node:fs', 'foo', './src/wrapper.js');
More flexible loader
One of the main goals of this proposal would be to "hide" the resolution algorithm in native code. The JavaScript side should not care whether the names are hashed or changed in any other way. The closer the original Node.js code, the better. Those 3 separate arguments: requiredPath, targetPackageName and fromSubpath gives more flexibility to the native loader. If all the addons are flattened into a single directory (like for iOS), the JS does not care -- the native loader will be able to implement this logic and try different search paths and variants.
Lastly, it shouldn't be hard to adapt this approach to support ES modules that use import and export.
- 主要語言
- TypeScript
- 星號
- 188
- 分支
- 10
- 平均合併
- 2 天 17 小時
- 30 天內合併 PR
- 3
貢獻指南
這個儲存庫沒有索引到貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
callstackincubator/react-native-node-api 的其他 Issue
-
Android 🤖
難度 2/5 1-3 小時 新手友好度 66/100
-
Sanity check of Hermes source directory via environment variable, when building Android projects 未關閉Android 🤖 good first issue
難度 2/5 1-3 小時 新手友好度 78/100
callstackincubator/react-native-node-api#163 · 1 則留言 ·
-
enhancement good first issue gyp-to-cmake
難度 2/5 1-3 小時 新手友好度 72/100
callstackincubator/react-native-node-api#161 · 3 則留言 · 1 個 reaction ·
-
enhancement Host 🏡
難度 5/5 一週以上 新手友好度 25/100
-
Automatable good first issue
難度 3/5 1-2 天 新手友好度 15/100
callstackincubator/react-native-node-api#424 · 1 則留言 ·
查看 callstackincubator/react-native-node-api 的全部 Issue
相似的 Issue
-
VerificationGate: ATTRIBUTION quote guard never matches a normal quotation (\b around the quote) 未關閉
難度 2/5 1-3 小時 新手友好度 75/100
danielmiessler/LifeOS#2234 ·
-
T: Bug
難度 2/5 1-3 小時 新手友好度 75/100
-
難度 2/5 1-3 小時 新手友好度 65/100
-
難度 1/5 1 小時以內 新手友好度 85/100
-
Mend: dependency security vulnerability untriaged
難度 2/5 1-3 小時 新手友好度 70/100