-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The loading algorithm doesn't work for Webpack-bundled applications when dependencies are bundled into them. #22
Comments
My easiest available workaround is just not bundling in libraries, but that adds in my case 500MB of production dependencies - of which I only need 12MB - and makes my build a whole lot slower. Either that or I'm stuck figuring out which exact libraries I need to keep unbundled by hand and package them separately. (Which is potentially laborious, since Webpack cannot load bundled libraries from unbundled ones, so I have to include the entire dependency tree.) |
A flat structure like that is ill-advised in any case, because some native modules have multiple |
That may be the case, but assuming I want to bundle dependencies, I don't have the option of having the files loading the bindings be in different containing folders, and I will grant that this might be an issue that's not completely solvable on the side of Even something like an additional optional parameter that explicitly specifies an additional path relative to __dirname to search would probably help; e.g. leveldown would call:
and node-gyp-build would search both: ("Just don't bundle dependencies" is my current path forward but it's not trivial to undo it on an established codebase - not all my libraries behave well as externals for reasons I have yet to diagnose. And it's impossible to just have native modules as external, because webpack doesn't automatically handle their dependencies, so I'd have to specify all of those myself - since webpack can't load bundled modules from external ones.) |
Could this be solved with a webpack plugin, perhaps? That rewrites |
It might be possible, and it would be orthogonal to Now that I'm rubberducking this, what could work while remaining relatively simple is adding a shim module like |
This is not specific to Webpack. Could you change the title? It happens with any bundler which copies the files to some other folder. |
@vweevers Close this as per #35 (comment). Add your comment to the Readme. |
@aminya This issue is slightly different from the one you had, so keeping it open. |
That's the exact issue. All the bundlers change the path of the files. That results in "__dirname" being incorrect. |
@aminya The two issues are both related to This issue on the other hand, is about consuming a native addon with a bundler, especially multiple native addons, and especially with bundlers that do not preserve |
I'm not a fan of breaking the static analysis chain of our bundlers, finding the native module at runtime or packaging all the native modules into the npm package itself. I wrote a Yarn v2 that we've been using internally for a while that takes a different approach. https://github.com/electricui/yarn-prebuilds It intercepts dependencies on the I figured doing it at the package management level made more sense than at a Webpack / Babel level. I'm not sure if this solution is useful to any of you, but I thought I'd drop it in here. |
I'm getting hit with this as well on a project at work. I'd be happy to contribute to a fix, with some guidance. |
We have a tag system already for picking a build with certain features, ie If someone wants to add support for that I'd be happy to help review. It just has be to backwards compat, ie, if no name tag fits pick the one without a name tag etc. |
If I can get time, I can take a look this evening. Are you looking for something like what was proposed in #22 (comment)? Updating the call to accept an optional name like
and then search for the proper binary? |
While I do not have anything to contribute, we have also encountered this issue recently and have found it extremely hard to debug, especially in conjunction with larger toolchains (in our case tsc -> webpack -> nodegui packer -> linuxdeployqt). |
Simple workaround for bundling of a project with multiple native dependant packages is to include the most heavy package to the bundle and do not bundle others. In this case we have this native module in /build/prebuilds/linux-x64/node.abi72.node (for Linux), and mark other native dependant packages in node_modules. This can be done with webpack-node-externals plugin with allowlist setting. |
Another short-term fix could be to externalise the native packages and allow the commonjs system to pick them up from node_modules at runtime. https://webpack.js.org/configuration/externals/#root e.g.:
|
When using Webpack to bundle a Node application into a single .js file, node-gyp-build cannot unambiguously load the correct
.node
file.In a bundled application, Webpack can provide as
__dirname
either"/"
which is the default, the input file's path relative to the build context, or Node's regular behaviourTo support
bindings
based native modules, you can copy the built.node
files intobuild/Release
relative to the bundle file, because bindings is passed the name of the .node file. Whennode-gyp-build
tries to load build files from that folder, if it contains multiple.node
files from multiple modules, it will grab the first one in it for every module that usesnode-gyp-build
.E.g. if my project uses
argon2
andleveldown
and builds them from source, I will have the bundled output structure:but either library trying to load its bindings file will just end up loading
argon2.node
.For similar reasons prebuilds are completely impossible to use, because all flavours of prebuild for a given runtime and ABI will have the same filename (such as
node-napi.node
), and since there's only one bundle file its containing directory won't disambiguate between them.The text was updated successfully, but these errors were encountered: