metaplex-foundation / js-examples

Examples and Starter Kits using the new JS SDK
MIT License
79 stars 92 forks source link

Vite build for production doesn't work #29

Closed devfather closed 1 year ago

devfather commented 1 year ago

I have used both the React and Vue examples and neither will build for production when using npm preview. It only happens when the metaplex object is called. There error for both the vue and react examples is:

uncaught TypeError: Class extends value undefined is not a constructor or null

Any help resolving this would be appreciated.

KartikSoneji commented 1 year ago

Can you please list down the exact steps you followed before you saw the error? Also a screenshot of the error would be very helpful.

devfather commented 1 year ago

Can you please list down the exact steps you followed before you saw the error? Also a screenshot of the error would be very helpful.

npm create vite@latest test3 -- --template

cd test3
npm install

npm install @metaplex-foundation/js @solana/web3.js

npm install -D assert util crypto-browserify @esbuild-plugins/node-globals-polyfill rollup-plugin-node-polyfills

Then navigate to vite config and updated to the following per the docs

import { defineConfig } from "vite";
import vue from '@vitejs/plugin-vue'
// Or for other frameworks:
// import { svelte } from "@sveltejs/vite-plugin-svelte";
// etc.
import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
import nodePolyfills from "rollup-plugin-node-polyfills";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()], // Or svelte(), etc.
  resolve: {
    alias: {
      stream: "rollup-plugin-node-polyfills/polyfills/stream",
      events: "rollup-plugin-node-polyfills/polyfills/events",
      assert: "assert",
      crypto: "crypto-browserify",
      util: "util",
    },
  },
  define: {
    "process.env": process.env ?? {},
  },
  build: {
    target: "esnext",
    rollupOptions: {
      plugins: [nodePolyfills({ crypto: true })],
    },
  },
  optimizeDeps: {
    esbuildOptions: {
      plugins: [NodeGlobalsPolyfillPlugin({ buffer: true })],
    },
  },
});

Then update index.html to include the following:

<script>
  window.global = window;
</script>
npm run build
npm run preview

This WILL build and work

Now to break it...

in the HellowWorld.vue file I've added the following to make a basic call to load an nft

I've added the following:

import { ref } from 'vue'
import { Metaplex } from "@metaplex-foundation/js";
import { Connection, PublicKey } from "@solana/web3.js";

const connection = new Connection("https://api.devnet.solana.com");

//It is this line alone that is breaking everything. You can remove my function and button below. It never makes it past this line.
const metaplex = Metaplex.make(connection)

const getNft = async () => {
  let mintAddress = prompt("Collection Mint Address:");
  if (!mintAddress) return;
  mintAddress = new PublicKey(mintAddress);
  const nft = await metaplex.nfts().findByMint({ mintAddress });  
  console.log(nft);
  return nft;
}

//On top of the existing button from the template i placed the following button to trigger the above function
<button type="button" @click="getNft()">Look Up NFT</button>

then...

npm run build
npm run preview

This will build... however it will NOT display in the browser it shows the following error:

Uncaught TypeError: Class extends value undefined is not a constructor or null at index.a6410298.js:161:30454

This is the same error i get with my more customized version of this. I rebuilt this using barebones to demonstrate that the simplest metaplex functionality breaks it in production mode.

It DOES work in dev mode.

devfather commented 1 year ago

Thanks to @KartikSoneji the solution was to add an additional alias:

near-api-js/dist/near-api-js.js

to the vite.config.js file.