- 4️⃣ Create React App 4 (using Webpack 4)
- 5️⃣ Create React App 5 (using Webpack 5)
- ⚡️ React with Vite
Steps to install a CRA 4 app from scratch using the SDK:
# Scaffold the app.
npx create-react-app getting-started-react-cra4 --scripts-version 4.0.3
cd getting-started-react-cra4
# Install the SDK and Web3.js
npm install @metaplex-foundation/js-next @solana/web3.js
Create and log a new Metaplex
instance inside src/App.js
.
//..
import { Metaplex } from '@metaplex-foundation/js-next';
import { clusterApiUrl, Connection } from '@solana/web3.js';
function App() {
const connection = new Connection(clusterApiUrl('devnet'));
const mx = Metaplex.make(connection);
console.log(mx);
// ...
}
At this point, npm start
will fail, complaining that it can't resolve .mjs
files provided by Web3.js. To fix this we need to:
# Install react-app-rewired.
npm install react-app-rewired
# Replace "react-scripts" with "react-app-rewired" in package.json scripts.
sed -i '' 's/react-scripts /react-app-rewired /g' package.json
# Create a new file to override Webpack 4 configs.
touch config-overrides.js
Then inside that config-overrides.js
file, paste the following:
module.exports = function override(webpackConfig) {
webpackConfig.module.rules.push({
test: /\.mjs$/,
include: /node_modules/,
type: "javascript/auto",
});
return webpackConfig;
};
Now, npm start
should work. 🎉
Even after doing this though you might have the following error when building your app for production (i.e. npm run build
and serve -g build
).
Uncaught TypeError: Cannot convert a BigInt value to a number
This is because Webpack will try to change the code of the deprecated nested dependency noble-ed25519
to make sure it will work on browsers that don't support BigInt
. However, all modern browsers support BigInt
so we can fix this by updating the browserslist
object in our package.json
.
"browserslist": {
"production": [
- ">0.2%",
- "not dead",
- "not op_mini all"
+ "chrome >= 67",
+ "edge >= 79",
+ "firefox >= 68",
+ "opera >= 54",
+ "safari >= 14"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
Now, you should be able to build and serve your application for production!
Steps to install a CRA 5 app from scratch using the SDK:
# Scaffold the app.
npx create-react-app getting-started-react-cra5
cd getting-started-react-cra5
# Install the SDK and Web3.js
npm install @metaplex-foundation/js-next @solana/web3.js
Create and log a new Metaplex
instance inside src/App.js
.
//..
import { Metaplex } from '@metaplex-foundation/js-next';
import { clusterApiUrl, Connection } from '@solana/web3.js';
function App() {
const connection = new Connection(clusterApiUrl('devnet'));
const mx = Metaplex.make(connection);
console.log(mx);
// ...
}
At this point, npm start
will fail, complaining that Webpack 5 does not provide polyfills that might be needed. To fix this we need to:
# Install react-app-rewired.
npm install react-app-rewired
# Install some polyfills.
npm install assert util crypto-browserify stream-browserify
# Replace "react-scripts" with "react-app-rewired" in package.json scripts.
sed -i '' 's/react-scripts /react-app-rewired /g' package.json
# Create a new file to override Webpack 4 configs.
touch config-overrides.js
Then inside that config-overrides.js
file, paste the following:
const webpack = require('webpack');
module.exports = function override(webpackConfig) {
// Disable resolving ESM paths as fully specified.
// See: https://github.com/webpack/webpack/issues/11467#issuecomment-691873586
webpackConfig.module.rules.push({
test: /\.m?js/,
resolve: {
fullySpecified: false,
},
});
// Ignore source map warnings from node_modules.
// See: https://github.com/facebook/create-react-app/pull/11752
webpackConfig.ignoreWarnings = [/Failed to parse source map/];
// Polyfill Buffer.
webpackConfig.plugins.push(
new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'] }),
);
// Polyfill other modules.
webpackConfig.resolve.fallback = {
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("stream-browserify"),
util: require.resolve("util"),
assert: require.resolve("assert"),
fs: false,
process: false,
path: false,
zlib: false,
};
return webpackConfig;
};
Now, npm start
should work. 🎉
Even after doing this though you might have the following error when building your app for production (i.e. npm run build
and serve -g build
).
Uncaught TypeError: Cannot convert a BigInt value to a number
This is because Webpack will try to change the code of the deprecated nested dependency noble-ed25519
to make sure it will work on browsers that don't support BigInt
. However, all modern browsers support BigInt
so we can fix this by updating the browserslist
object in our package.json
.
"browserslist": {
"production": [
- ">0.2%",
- "not dead",
- "not op_mini all"
+ "chrome >= 67",
+ "edge >= 79",
+ "firefox >= 68",
+ "opera >= 54",
+ "safari >= 14"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
Steps to install a React app with Vite from scratch using the SDK:
# Scaffold the app.
npm create vite@latest getting-started-vite -- --template react
cd getting-started-vite
npm install
# Install the SDK and Web3.js
npm install @metaplex-foundation/js-next @solana/web3.js
Create and log a new Metaplex
instance inside src/App.jsx
.
//..
import { Metaplex } from '@metaplex-foundation/js-next';
import { clusterApiUrl, Connection } from '@solana/web3.js';
function App() {
const connection = new Connection(clusterApiUrl('devnet'));
const mx = Metaplex.make(connection);
console.log(mx);
// ...
}
Add the following script in your index.html
file.
<body>
<div id="root"></div>
+ <script>
+ // Global node polyfill.
+ window.global = window;
+ </script>
<script type="module" src="/src/main.jsx"></script>
</body>
Install the following polyfills and plugins.
npm install -D assert util crypto-browserify @esbuild-plugins/node-globals-polyfill rollup-plugin-node-polyfills
Replace the content of your vite.config.js
file with the following to provide polyfills for both development and production.
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
import nodePolyfills from 'rollup-plugin-node-polyfills';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
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 }),
],
}
},
});
And that's it! Now you can run npm run dev
when developing and npm run build
for production.
Hey @MNaguib2611 👋 Yeah that was a bug on version
0.11.0
sorry about that. Try version0.11.1
, it should work. 🙂