Open karlhorky opened 3 weeks ago
Hi @karlhorky - I'm not certain of all the details for how bundling is set up for Expo server-side routes - but at first glance I'd try assetExts
and not sourceExts
for .node
files. Sources will be run through the transformer, which will choke on binary files.
If that doesn't help I'll give this a closer look later in the week.
(Generalised externals support is planned, but not there yet.)
bcrypt
has a dependency on @mapbox/node-pre-gyp
, which is trying to import the problem module. There are two issues with this package
mock-aws-s3
as a development dependency, but tries to require it in production code require('mock-aws-s3')
is an if ()
statement checking for an env value. From a bundler perspective, it does not know if a random env value is a flag for production or not. Env values can be changed at runtime.Metro does have the means to handle this, but the require()
needs to be wrapped in the try {} catch {}
block.
@marklawlor This issue https://github.com/facebook/metro/issues/1377 is for a slightly different package actually - @node-rs/bcrypt
instead of bcrypt
- which does not have the same issues with @mapbox/node-pre-gyp
.
So the notes about @mapbox/node-pre-gyp
, mock-aws-s3
, etc. actually don't belong in this issue.
But if you think I should open a separate Metro issue for bcrypt
itself, then happy to do that too.
Companion issue (
expo/expo
): https://github.com/expo/expo/issues/32350Do you want to request a feature or report a bug?
Request a feature:
Documentation about Node-API native addons usage in Metro with
platform: 'web'
, which Expo Router API Routes uses.What is the current behavior?
Metro does not allow for importing Node-API native addons in
platform: 'web'
code, meaning that npm package containing native addons (such as@node-rs/bcrypt
) cannot be used in Expo Router API Routes.For example:
app/hash+api.ts
Out of the box, Expo Router API Routes will not be able to bundle this, because the
.node
extension is not supported (as also mentioned by @EvanBacon here):Changing
sourceExts
to also contain.node
(addingsourceExts.push('node')
innode_modules/@expo/metro-config/build/ExpoMetroConfig.js
) yields the following (trying to load the.node
binary file):Unclear how to add "externals" in Metro
Thinking through this, one idea came up to use something similar to "externals" - code that Metro will not touch / bundle, but rather just load at runtime.
I can't see how I can modify the Metro configuration for Expo Router API Routes, to add something similar to webpack
externals
.Maybe this feature doesn't exist in Metro?
If such a feature were to exist, this would also help with usage of the standard
bcrypt
package in Expo Router API Routes:Metro Configuration
I believe this is the Metro configuration for Expo Router API Routes:
https://github.com/expo/expo/blob/48d64e9c285871e513f11238933e4abe7d7d1d9a/packages/%40expo/cli/src/start/server/metro/MetroBundlerDevServer.ts#L554-L577
If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can
yarn install
andyarn test
.I'm not sure this is a bug, but just a gap in the documentation - that Node-API native addons are not intended to be supported in the
platform: 'web'
configuration.What is the expected behavior?
It's documented (and a workaround is provided, if possible)
Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.