scaffold-eth / scaffold-eth-typescript

Typescript version of Scaffold-Eth 🏗
MIT License
186 stars 83 forks source link

Bundled App breaks with dependency-thrown TypeError: Right-hand side of 'instanceof' is not callable #80

Closed dvinubius closed 2 years ago

dvinubius commented 2 years ago

I'm using Moralis as a backend for a Meta MultiSig Factory App.

One of the dependencies is react-moralis, which in turn uses the moralis, which in production throws an error.

I suspect that this is due to how vite builds the app for production.

I've searched for this particular issue and could not find it related to Moralis specifically, but I did find it related to Vue and Rollup. However, none of the solutions there were applicable.

So I have little hope that the Moralis people will be able to solve this, but @ShravanSunder I know you've given quite a bit of thought to the vite config and the bundling process. So - here it is:

Issue Description

The app works in local development.

But when served as a production bundle it throws the following exception

Screenshot 2022-02-25 at 18 29 47

Here is the stack trace

This is my code in useMultiSigSafes.tsx:

Screenshot 2022-02-25 at 22 25 10

This is in Cloud.jsline 98:

Screenshot 2022-02-25 at 22 21 42

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,
      },
    },
  },
});
dvinubius commented 2 years ago

The only solution I was able to find involves changing code in the react-moralis dependency itself. I found it because of a developer with Vue-Vite having this issues with another dependency.

  1. go to packages/vite-app-ts/node_modules/react-moralis/lib/index.esm.js
  2. change import MoralisImport from 'moralis'; to import MoralisImport from 'moralis/dist/moralis.js';

I suppose we can close the issue, especially since it's not exactly a scaffold eth issue.

But then this may happen to future builders too when using certain 3rd party code...

github-actions[bot] commented 2 years ago

Stale issue message

ShravanSunder commented 2 years ago

@dvinubius there's a nextjs folder and build now in scaffold-eth-typescript. that might solve this issue.

I think its because of how they bundled their package, they probably default to cjs, which is normal

thanks for investigating @dvinubius

dvinubius commented 2 years ago

Thank you @ShravanSunder for the fix!