- 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.jsCreate 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.jsThen 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.jsCreate 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.jsThen 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.jsCreate 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-polyfillsReplace 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.
Hello Lori,
I followed your steps for react webpack5
and I recieved this error :
Task.ts:58 Uncaught (in promise) TypeError: abort_controller__WEBPACK_IMPORTED_MODULE_0__.AbortController is not a constructor
at Task.forceRun (Task.ts:58:1)
at Task.run (Task.ts:47:1)
at OperationClient.execute (OperationClient.ts:76:1)
at NftClient.findByMint (NftClient.ts:35:1)
at getNftMetaData (dashboard.js:38:1)
at Dashboard (dashboard.js:44:1)
at renderWithHooks (react-dom.development.js:16305:1)
at mountIndeterminateComponent (react-dom.development.js:20145:1)
at beginWork (react-dom.development.js:21587:1)
at beginWork$1 (react-dom.development.js:27426:1)