Uploaded image for project: 'Node.js Driver'
  1. Node.js Driver
  2. NODE-5152

Remove RequireRewriter rollup transformer

    • Type: Icon: Bug Bug
    • Resolution: Community Answered
    • Priority: Icon: Unknown Unknown
    • None
    • Affects Version/s: None
    • Component/s: BSON
    • 1
    • 1
    • Not Needed

      Description From js-bson PR#568

      Current ESM packaging with rollup uses an unecessary plugin to wrap nodejsRandomBytes, a function that tries to require `crypto` and then fallback to another function, around an top-level async/await anonymous function. According to the documentation provided in the source:

      "crypto" is the only dependency BSON needs. This presents a problem for creating a bundle of the BSON library in an es module format that can be used both on the browser and in Node.js. In Node.js when BSON is imported as an es module, there will be no global require function defined, making the code below fallback to the much less desireable math.random bytes. In order to make our es module bundle work as expected on Node.js we need to change this require() to a dynamic import, and the dynamic import must be top-level awaited since es modules are async. So we rely on a custom rollup plugin to seek out the following lines of code and replace `require` with `await import` and the IIFE line (nodejsRandomBytes = (() => { ... })()) with nodejsRandomBytes = await (async () => { ... })()` when generating an es module bundle.

      This is in fact untrue as as of March 2023 rollup is capable of handling this function as-it-is and the source transformation actually produces unexpected build-time and runtime behaviors.

      What is changing?

      Rollup transformation to wrap `src/utils/node_byte_utils.ts:nodejsRandomBytes` around an async/await function is being deleted.

      Is there new documentation needed for these changes?

      No.

      What is the motivation for this change?

      This entire transformation is useless as browser and node modules are capable of handling the quoted function without it seamlessly. I'm using bson package in both environments (in an webapp bundled with rollup and in the node backend). Before the change I was unable to bundle my webapp for production without throwing on build (worked around this by converting the package to cjs first within rollup config) and then it threw on runtime also (browser interpreter, Chromium by the way, threw because the code generated by rollup put the await in an invalid context). After the change both my applications (packed with ESM) are running as expected, no exceptions thrown and no need to convert to CJS.

      I can create a vite reproduction repo if needed, just let me know.


      Resolution

      When bundling BSON with vite.
      The resolve.alias settings are forwarded to @rollup/plugin-alias

      https://vitejs.dev/config/shared-options.html#resolve-alias

      import { defineConfig } from 'vite'
      
      export default defineConfig({
        resolve: {
          alias: {
            'bson': require.resolve('bson')
          }
        },
        optimizeDeps: {
          include: [
            'bson'
          ]
        },
      })
      
      NODE_PATH=../../node_modules npx vite build
      

            Assignee:
            neal.beeken@mongodb.com Neal Beeken
            Reporter:
            neal.beeken@mongodb.com Neal Beeken
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: