How to polyfill Buffer with Webpack 5
The "buffer is not defined" error is a common error that can occur when trying to use the Buffer Node.js API in an environment where it is not natively supported. This article will cover how to fix this error by providing a polyfill with Webpack 5.
Why do we need to polyfill Buffer?
When working in the context of a browser environment, Node.js APIs, such as Buffer, aren't available. There are sometimes comparable APIs available in the browser environment. However, the author of 3rd party libraries and code you may be using would have had to either replace the Node.js specific APIs they are using with the browser versions or provide another mechanism to provide your API to satisfy the libraries' need.
Unfortunately, library authors often do not consider browser environments, or their library may not have been intended to be used in a browser environment. In these cases, it is popular to use a build tool such as Webpack to replace the Node.js specific APIs used by the library with a version that provides a browser environment compatible API, known as polyfilling.
Webpack v5
Before Webpack v5, the polyfilling of many Node.js APIs would be performed automatically. With v5, Webpack will no longer polyfill Node.js APIs automatically.
Solving the Problem
Install a polyfill
First, we will need to install or otherwise provide a browser-compatible Buffer implementation. For my needs, I have found the feross/buffer package to be suitable.
The below command will install buffer
as a dev
dependency.
npm install -D buffer
Configure Webpack Fallback
The Webpack resolve.fallback
configuration option allows us to configure Webpack to leverage the provided package as a "fallback" for APIs which are not natively available in the target environments that Webpack is building for (ie, a Browser).
const webpackConfig = {
...
resolve: {
...
fallback: {
buffer: require.resolve('buffer/'),
},
},
};
The /
at the end of buffer/
may appear strange to you, as it did to me. However, it is recommended by the buffer
documentation because of how the Node.js module lookup algorithm works.
To require this module explicitly, use require('buffer/') which tells the node.js module lookup algorithm (also used by browserify) to use the npm module named buffer instead of the node.js core module named buffer!
Configure Webpack ProvidePlugin
The Webpack ProvidePlugin
provides a mechanism for injecting a module/value as a replacement/API for global variables that would otherwise be undefined. For instance, in Node.js you can leverage the Buffer
class from the global namespace without any import
or require
statements. The' Buffer' class would be' undefined in a browser environment and without the ProvidePlugin.
new Buffer();
Uncaught ReferenceError: Buffer is not defined
at <anonymous>:1:1
We can provide a compatible implementation of the Buffer
class via the Webpack configuration plugins
array to overcome this.
const webpackConfig = {
...
plugins: [
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
]
};
The provided array (['buffer', 'Buffer']
) informs the webpack.ProvidePlugin
to set the global value of Buffer
to the Buffer
export from the buffer
package.
For example:
const Buffer = require('buffer/').Buffer;
All together
Below is an example of the combined relevant parts of your Webpack configuration to polyfill the Buffer
class using Webpack v5.
const webpackConfig = {
resolve: {
fallback: {
buffer: require.resolve('buffer/'),
},
},
plugins: [
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
],
};
Conclusion
Now that you've configured Webpack to polyfill the Buffer
class globally, you should be able to reference and create an instance of the Buffer
class without the pesky Uncaught ReferenceError: Buffer is not defined
error. Additionally, any reference to Buffer
in libraries included in your "bundle" should now also reference the provided polyfill.
Please feel free to leave any questions/comments below, and if you enjoyed this article, checkout my other social media accounts where I share content!