After upgrading webpack to v5 in a project, attempting to build the project with webpack generates a swarm of errors, all with the format:
ERROR in ./node_modules/[dependency_name]/[file_name].js 28:13-30
Module not found: Error: Can't resolve '[polyfill_name]' in '.../node_modules/[dependency_name]'
I've found countless stackoverflow answers and guides (one even the official webpack guide) suggesting the solution is to use fallbacks in the webpack configuration file (because webpack v5 no longer includes the polyfills itself). In webpack.config.json, that is supposed to look something like:
module.exports = {
...configuration stuff...
resolve: {
fallback: {
util: require.resolve("util"),
assert: require.resolve("assert"),
buffer: require.resolve("buffer"),
crypto: require.resolve("crypto-browserify"),
http: require.resolve("stream-http"),
https: require.resolve('https-browserify'),
os: require.resolve("os-browserify/browser"),
path: require.resolve("path-browserify"),
stream: require.resolve("stream-browserify"),
zlib: require.resolve("browserify-zlib")
}
}
}
The missing polyfil plugins (https-browserify, os-browserify/browser, etc) must be installed as well, for example:
npm install path-browserify stream-browserify browserify-zlib etc etc
I have done both of these things, but the errors persist. I have also tried an alternative suggestion to use aliases rather than fallbacks; I have even gone so far as to install the polyfill plugins in the dependencies themselves in my project's node_modules folder:
cd node_modules/module_name && npm install https browserify
...All to no avail. I see countless other people who had these errors confirm that they resolved the errors with these strategies (except the last - installing the polyfills directly in the dependencies was a despearate last-ditch effort to see if I could make it work somehow).
Clearly I must be doing something wrong, because, as I mentioned, nobody else seems to be having issues once they implement the given solution. Here is my webpack configuration:
const path = require("path");
const CopyPlugin = require('copy-webpack-plugin');
var webpack = require('webpack');
const HtmlWebPackPlugin = require("html-webpack-plugin");
const htmlPlugin = new HtmlWebPackPlugin({
inject: false,
template: "./src/main/index.html",
filename: "./index.html"
});
module.exports = {
name: "Stress Tester",
entry: "./src/main/index.js",
output: {
path: path.resolve(__dirname, "browser_build"),
filename: "stress_tester.dist.js"
},
resolve: {
fallback: {
util: require.resolve("util"),
assert: require.resolve("assert"),
buffer: require.resolve("buffer"),
crypto: require.resolve("crypto-browserify"),
http: require.resolve("stream-http"),
https: require.resolve('https-browserify'),
os: require.resolve("os-browserify/browser"),
path: require.resolve("path-browserify"),
stream: require.resolve("stream-browserify"),
zlib: require.resolve("browserify-zlib")
}
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
type: "javascript/auto",
use: {
loader: "babel-loader",
options: {
cacheDirectory: false,
presets: [
[
'@babel/preset-env',
{
targets: {
esmodules: true,
},
},
],
],
}
}
},
{
// Preprocess your css files
// you can add additional loaders here (e.g. sass/less etc.)
test: /\.css$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(jpe?g|png|gif)$/,
use: [{
loader: 'file-loader',
/*
options: {
name: '[name].[ext]',
outputPath: 'img/',
publicPath:'img/'
}
*/
}]
}
]
},
devtool: 'source-map',
externals: ['worker_threads','ws','perf_hooks', 'child_process'], // exclude nodejs
resolve: {
symlinks: false,
alias: {
"fs": "html5-fs"
},
extensions: ['.js', '.jsx', '.css', '.json', 'otf', 'ttf', 'eot', 'svg'],
modules: [
'node_modules'
]
},
cache: true,
context: __dirname,
devServer: {
devMiddleware: {
publicPath: './browser_build',
writeToDisk: true,
}
},
plugins: [
htmlPlugin,
new CopyPlugin({
patterns: [
{ from: path.resolve("node_modules/monero-javascript/dist"), to: path.resolve("browser_build") },
],
}),
],
};
What am I missing?