This example sets up a new React app with Metaplex using Esbuild.
This example has been generated using the following steps:
-
Create a new project using NPM.
Esbuild does not have any standard template for React which can be utilized for initializing the project like CRA or Vite. So, we will be creating an empty npm project and setup everything from scratch.
mkdir getting-started-react-esbuild cd getting-started-react-esbuild npm init -y
Once the empty npm project is ready, we will set up a basic directory structure with mainly
public
andsrc
folders and a config file (build.js
) which will be used for compiling and bundling the react app with esbuild.getting-started-react-esbuild/ ├── public/ │ └── index.html ├── src/ │ ├── app.jsx │ ├── index.css │ └── index.js ├── build.js └── package.json
-
Install React, EsBuild and the Metaplex SDK.
npm install react react-dom esbuild @metaplex-foundation/js @solana/web3.js
-
Install some polyfills.
Why?
Some dependencies of the Metaplex SDK are still relying on NPM packages that are not available in the browser. To make sure that the Metaplex SDK works in the browser, we need to install some polyfills.npm install -D node-stdlib-browser
-
Install Servor for Development
Why?
Esbuild does not include any server that could be used to preview our app in the browser. So we will be using servor for that.npm install -D servor
-
Update your build.js file.
Add the following code to the
build.js
file we created earlier.Why?
The following code will build and bundle your react app with EsBuild. It will also start a dev server when used in development.const esbuild = require('esbuild'); const plugin = require('node-stdlib-browser/helpers/esbuild/plugin'); const stdLibBrowser = require('node-stdlib-browser'); const fs = require('fs'); const path = require('path'); const servor = require('servor'); const outdirectory = 'public'; // Clean previously built assets. fs.readdir(outdirectory, (err, files) => { if (err) throw err; for (const file of files) { if ( file.endsWith('.js') || file.endsWith('.css') || file.endsWith('.js.map') ) { fs.unlink(path.join(outdirectory, file), (err) => { if (err) throw err; }); } } }); async function dev() { console.log('Building development bundle ⏳'); await esbuild.build({ entryPoints: ['src/index.js'], outdir: outdirectory, bundle: true, define: { 'process.env.NODE_ENV': '"development"', global: 'global', process: 'process', Buffer: 'Buffer', }, minify: false, watch: true, inject: [require.resolve('node-stdlib-browser/helpers/esbuild/shim')], plugins: [plugin(stdLibBrowser)], loader: { '.js': 'jsx', }, }); console.log('Development bundle built ✅'); console.log('Running server from: http://localhost:8000'); await servor({ browser: true, root: outdirectory, port: 8000, }); } async function prod() { console.log('Build started ⏳'); await esbuild.build({ entryPoints: ['src/index.js'], outdir: outdirectory, bundle: true, define: { 'process.env.NODE_ENV': '"production"', global: 'global', process: 'process', Buffer: 'Buffer', }, minify: true, inject: [require.resolve('node-stdlib-browser/helpers/esbuild/shim')], plugins: [plugin(stdLibBrowser)], loader: { '.js': 'jsx', }, }); console.log('Build completed ✅'); } //defaults to build let config = '-build'; if (process.argv.length > 2) { config = process.argv[2]; } // Builds the bundle for dvelopment and runs a local web server // with livereload when -watch is set config === '-watch' && dev(); // Builds optimized bundle for production config === '-build' && prod();
-
Update your
package.json
.Add the following scripts to your
package.json
file."scripts": { + "build": "node build.js -build", + "dev": "node build.js -watch" },
-
Update your
index.html
.Add the following code in your
index.html
file.<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="EsBuild + Metaplex" /> <title>EsBuild + Metaplex</title> <script src="index.js" async defer></script> <link rel="stylesheet" href="index.css" /> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>
-
That's it! 🎉
You're now ready to start building your app. You can use the following commands to build and serve your app.
# Build and serve for development. npm run dev # Build for production. npm run build
If you're interested in how this example app is using the Metaplex SDK, check out the
App.jsx
andApp.css
files in thesrc
directory.