How to compile web3.js in Laravel Mix
If you’ve ever needed to use web3.js in a Laravel Mix / webpack project, you have probably encountered an error along the lines of:
Error: Module not found:
Error: Can’t resolve ‘stream’ in ‘app/node_modules/cipher-base’
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: — add a fallback ‘resolve.fallback: { “stream”: require.resolve(“stream-browserify”) }’ — install ‘stream-browserify’ If you don’t want to include a polyfill, you can use an empty module like this: resolve.fallback: { “stream”: false }
Luckily there are few ways of fixing this.
The easy way
Simply use the ESM build included with theweb3
NPM package in your javascript.
Wherever you import the web3 library, change your import from
import Web3 from 'web3'
to
import Web3 from 'web3/dist/web3.min.js'
Simple as that! Now the warnings should disappear as and your code compile succesfully.
The hard way
Well, not that hard. We just need to configure the polyfills that Webpack is telling us about in the error message.
Knowing how to do this might be handy in case you ever need to install other web3 packages which doesn’t ship with a ESM build (yes, I’m talking about you, WalletConnect!).
Create a new webpack.config.js
file in the root of our Laravel project if it doesn’t already exist, and copy/paste the following configuration:
module.exports = {
resolve: {
fallback: {
"stream": require.resolve("stream-browserify"),
"crypto": require.resolve("crypto-browserify"),
"http": require.resolve("stream-http"),
"https": require.resolve("https-browserify"),
"os": require.resolve("os-browserify/browser"),
},
},
};
All the polyfills should already be installed as they are (sub)dependencies of web3 as well as Laravel Mix.
Finally we just need to tell Laravel Mix to use our freshly created Webpack config.
In webpack.mix.js
add the last line:
const mix = require('laravel-mix'); mix.js('resources/js/app.js', 'public/js')
.webpackConfig(require('./webpack.config'));
And just like that, the compilation errors should be gone!