Uploaded image for project: 'Realm JavaScript SDK'
  1. Realm JavaScript SDK
  2. RJS-1461

Electron Issue: Bundling Realm with Vite and Rollup

      How frequently does the bug occur?

      All the time

      Description

      While developing an ElectronJS/Realm app using Vite as our runtime tooling, we discovered an issue with how RealmJS imports some files. Vite uses esbuild to bundle dependencies. ESBuild requires specifically formatted imports in order to properly analyze dependencies to be included in the bundle. (See esbuild.github.io/api/#bundle)

      In RealmJS lib/index.js line 72 sets the variable nodeRequire = require, this makes all imports that use nodeRequire such as ./submit-analytics non-analyzable and therefore is not included when esbuild packages RealmJS.

      It appears that this was done deliberately based on the comment on line 21 of index.js:

      // Prevent React Native packager from seeing modules required with this
      

      The reason that this works with Webpack is that Webpack tries to support this by including all potentially reachable-files when they bundle Realm, so Webpack includes all of the files in the package in their bundle.

      The solution here is pretty straightforward, and I think we can just replace the two usages of nodeRequire with require. I believe the only impact here should be that these files are now included in the React Native package of RealmJS, which should be fine, as they would never be used because they would be behind the node.js and electron switch statement.

      Index: lib/index.js
      IDEA additional info:
      Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
      <+>UTF-8
      ===================================================================
      diff --git a/lib/index.js b/lib/index.js
      --- a/lib/index.js	(revision a3e34819a2bbaeb24b7051de0cb67066904bce8a)
      +++ b/lib/index.js	(date 1640542501619)
      @@ -20,21 +20,18 @@
       
       const utils = require("./utils");
       
      -// Prevent React Native packager from seeing modules required with this
      -const nodeRequire = require;
      -
       function getRealmConstructor(environment) {
           switch(environment) {
               case "node.js":
               case "electron":
      -            var analytics = nodeRequire("./submit-analytics");
      +            var analytics = require("./submit-analytics");
                   analytics.submitProductionAnalytics("Run")
                   .catch(() => {
                       // fail silently -- the caller is not responsible for handling
                       // errors in analytics submission
                   });
       
      -            return nodeRequire("bindings")("realm.node").Realm;
      +            return require("bindings")("realm.node").Realm;
               case "reactnative":
                   //switch how babel transpiled code creates children objects.
                   //Inheriting from Realm.Object with class syntax does not support using Reflect.construct the way babel transpiles it.
      

      Stacktrace & log output

      Unable to find source-code formatter for language: shell. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      Uncaught Error: Cannot find module './submit-analytics'
      Require stack:
      - electron/js2c/renderer_init
          at Module._resolveFilename (node:internal/modules/cjs/loader:940)
          at Function.o._resolveFilename (node:electron/js2c/renderer_init:33)
          at Module._load (node:internal/modules/cjs/loader:785)
          at Function.c._load (node:electron/js2c/asar_bundle:5)
          at Function.o._load (node:electron/js2c/renderer_init:33)
          at Module.require (node:internal/modules/cjs/loader:1012)
          at require (node:internal/modules/cjs/helpers:94)
          at getRealmConstructor (index.js:28)
          at node_modules/realm/lib/index.js (index.js:59)
          at __require2 (chunk-A7KXWXJP.js?v=bbcedeba:48)
      

      Can you reproduce the bug?

      Yes, always

      Reproduction Steps

      An easy way to reproduce is to add RealmJS to Alex's Vite/Electron boilerplate. In order to use Realm, you will need to enable nodeIntegration from packages/main/src/index.ts:

      const createWindow = async () => {
        mainWindow = new BrowserWindow({
          show: false, // Use 'ready-to-show' event to show window
          webPreferences: {
            nativeWindowOpen: true,
            webviewTag: false, // The webview tag is not recommended. Consider alternatives like iframe or Electron's BrowserView. https://www.electronjs.org/docs/latest/api/webview-tag#warning
            nodeIntegration: true,
            contextIsolation: false,
            preload: join(__dirname, '../../preload/dist/index.cjs'),
          },
        });
      

      From there, you can go ahead and try adding Realm to the renderer process and you should observe the same error as described above.

      Version

      10.11.0

      What SDK flavour are you using?

      MongoDB Realm (i.e. Sync, auth, functions)

      Are you using encryption?

      No, not using encryption

      Platform OS and version(s)

      macOS & Windows

      Build environment

      No response

            Assignee:
            Unassigned Unassigned
            Reporter:
            unitosyncbot Unito Sync Bot
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: