MoralisWeb3 / Moralis-JS-SDK

Moralis Official Javascript SDK
https://docs.moralis.io
Other
368 stars 257 forks source link

production-bundled code in Vite app breaks when calling Moralis.Cloud.run #271

Closed dvinubius closed 1 year ago

dvinubius commented 2 years ago

New Bug Report

This issue seems related to Moralis SDK itself. However, I'm using react-moralis: ^1.3.1.

My react code is inside a Vite App and written in typescript.

I'm opening an issue with the Vite developer, too, but please take a look guys. You may recognize the potential source of the issue, or at least quickly exclude that it's from Moralis, I'll know where to tackle it best.

Issue Description

The cloud function call works in local development.

const safes = await Moralis.Cloud.run('MultiSigSafes', {
    owner,
  });

But in a production bundle it throws the following exception

Screenshot 2022-02-25 at 18 29 47

Here is the stack trace

This is in Cloud.js line 98:

Screenshot 2022-02-25 at 18 41 29

This is also Cloud.js line 171:

Screenshot 2022-02-25 at 18 42 17

This is encode.js line 149:

Screenshot 2022-02-25 at 18 44 35

This is encode.js line 65:

Screenshot 2022-02-25 at 18 47 09

This is my vite.config.ts:

import { resolve } from 'path';

import reactPlugin from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
// import reactRefresh from '@vitejs/plugin-react-refresh';
import macrosPlugin from 'vite-plugin-babel-macros';
import { viteExternalsPlugin } from 'vite-plugin-externals';
import tsconfigPaths from 'vite-tsconfig-paths';

const isDev = process.env.ENVIRONMENT === 'DEVELOPMENT';
console.log('env.dev:', process.env.ENVIRONMENT, ' isDev:', isDev);

/**
 * browserify for web3 components
 */
const externals = {
  http: 'http-browserify',
  https: 'http-browserify',
  timers: 'timers-browserify',
  electron: 'electron',
  'electron-fetch': 'electron-fetch',
};

const nodeShims = {
  util: 'util',
};

/**
 * Externals:
 * - node externals are required because web3 are terribly bundled and some of them use commonjs libraries.  modern libs like ethers help with this.
 * - electron:  added due to ipfs-http-client.  it has very poor esm compatibility and a ton of dependency bugs. see: https://github.com/ipfs/js-ipfs/issues/3452
 */
const externalPlugin = viteExternalsPlugin({
  ...externals,
  ...(isDev ? { ...nodeShims } : {}),
});

/**
 * These libraries should not be egarly bundled by vite.  They have strange dependencies and are not needed for the app.
 */
const excludeDeps = ['@apollo/client', `graphql`];

export default defineConfig({
  plugins: [reactPlugin(), macrosPlugin(), tsconfigPaths(), externalPlugin],
  build: {
    sourcemap: true,
    commonjsOptions: {
      include: /node_modules/,
      transformMixedEsModules: true,
    },
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
      },
    },
  },
  esbuild: {
    jsxFactory: 'jsx',
    jsxInject: `import {jsx, css} from '@emotion/react'`,
  },
  define: {},
  optimizeDeps: {
    exclude: excludeDeps,
  },
  resolve: {
    preserveSymlinks: true,
    mainFields: ['module', 'main', 'browser'],
    alias: {
      '~~': resolve(__dirname, 'src'),
      ...externals,
      ...nodeShims,
      process: 'process',
      stream: 'stream-browserify',
    },
  },
  server: {
    watch: {
      followSymlinks: true,
    },
    fs: {
      // compatability for yarn workspaces
      allow: ['../../'],
    },
  },
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
      },
    },
  },
});

Server

Client

dvinubius commented 2 years ago

I've been able to solve the issue by going into

node_modules/react-moralis/lib/index.esm.js and changing an import to a deep import:

import MoralisImport from 'moralis'; to

import MoralisImport from 'moralis/dist/moralis.js';

Clearly not ideal, but it makes it apparent that the bundler can't handle this dependency properly because of the way it is written in terms of its own imports / bundling process.

To make it more clear - vite uses rollup.js to perform the bundling. When dependencies have mixes es6 and commonJS modules this typically creates issues which can be mitigated by refactoring of the dependencies.

So if any of you guys who have worked on the moralis packaging could take a look, it's much appreciated! And surely helps future devs that get into this situation.

ErnoW commented 2 years ago

Thanks for the clear report. We will change the whole build process in the next major update (see https://github.com/MoralisWeb3/Moralis-JS-SDK/issues/245), where we also consider to use rollup (or other modern building tools), So that would probably resolve the issue.

dvinubius commented 2 years ago

That's great news! Thanks for all the work. Keep it up 👍

ErnoW commented 2 years ago

Maybe related (leaving it as a reference). Since Moralis is bootstrapped from Parse, and saw this issue with Vite on the Parse forums: https://community.parseplatform.org/t/vue-vite-parse-js-error-super-expression-must-either-be-null-or-a-function/2001

ErnoW commented 1 year ago

Closing this issue, as it's not relevant anymore since v2