ngneat / falso

All the Fake Data for All Your Real Needs 🙂

Home Page:https://ngneat.github.io/falso/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Falso attempts to import the built-in Node.js `crypto` module in the browser

srmagura opened this issue · comments

Is this a regression?

No

Description

If you import any function from Falso in the browser, you'll get a warning similar to the following from your bundler:

Module "crypto" has been externalized for browser compatibility. Cannot access "crypto.randomBytes" in client code. See http://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.

It happens because Falso or one of its dependencies is attempting to import the crypto module. This module is part of Node.js and is not available in the browser.

You can work around the issue by aliasing crypto to a polyfill like crypto-browserify. But this is not recommended because that polyfill is very large.

Please provide a link to a minimal reproduction of the bug

https://github.com/srmagura/falso-crypto-repro

Please provide the exception or error you saw

Module "crypto" has been externalized for browser compatibility. Cannot access "crypto.randomBytes" in client code. See http://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.

Please provide the environment you discovered this bug in

Node 18, Vite 4.3.8, @ngneat/falso 6.4.0

Anything else?

I did a quick search in the Falso codebase, and it seems that Falso itself is not importing crypto. So it must be one of Falso's dependencies that is importing it.

Do you want to create a pull request?

Yes

Root Cause

The line of code that is causing the problem is in the seedrandom package here: https://github.com/davidbau/seedrandom/blob/4460ad325a0a15273a211e509f03ae0beb99511a/seedrandom.js#L236

Since the require is wrapped in a try-catch, it should be harmless. But bundlers don't know that. I think silencing the warning emitted by the bundler is a fine temporary solution in this case.

How to Silence the Warning

Webpack

If using Webpack, put this in your webpack.config.js:

    resolve: {
      /* ... */
      fallback: {
        // For falso. This tells Webpack to not include a polyfill (since their
        // bundle sizes are massive)
        crypto: false,
        stream: false,
      },
    },

Vite

If using Vite, create a file called src/emptyModule.ts:

// See `vite.config.ts` for why this exists
export {};

Then, add this to your vite.config.ts:

  resolve: {
    alias: {
      crypto: 'src/emptyModule.ts',
    },
  },