Skip to content

Buffer is not defined 错误解决方案

问题描述

在 Webpack 5 环境中,许多开发者遇到了 Uncaught ReferenceError: Buffer is not defined 错误。这个问题通常出现在使用 Node.js 核心模块(如 Bufferstream 等)的浏览器端应用中,因为 Webpack 5 不再自动包含这些模块的 polyfill。

典型的错误堆栈如下:

rfc6979.js:3 Uncaught ReferenceError: Buffer is not defined
    at Object.4142 (rfc6979.js:3)
    at r (bootstrap:19)
    at Object.5892 (js.js:4)
    at r (bootstrap:19)
    at Object.4090 (bip32.js:5)
    at r (bootstrap:19)
    at Object.7786 (index.js:3)
    at r (bootstrap:19)
    at Object.1649 (MnemonicKey.js:50)
    at r (bootstrap:19)

解决方案

根据不同的构建工具和框架,有多种解决方案可供选择。

方案一:使用 ProvidePlugin(Webpack 通用方案)

这是最常见的解决方案,适用于大多数 Webpack 项目。

bash
npm install --save buffer stream-browserify
npm install --save-dev process
js
const webpack = require('webpack');

module.exports = {
  // ... 其他配置
  
  resolve: {
    extensions: ['.ts', '.js', '.tsx', '.jsx'],
    fallback: {
      "stream": require.resolve("stream-browserify"),
      "buffer": require.resolve("buffer"),
      "process": require.resolve("process/browser")
    }
  },
  
  plugins: [
    new webpack.ProvidePlugin({
      Buffer: ['buffer', 'Buffer'],
      process: 'process/browser'
    })
  ]
};

方案二:React 项目(使用 react-app-rewired)

对于使用 Create React App 创建的项目,需要通过 react-app-rewired 来修改 webpack 配置。

bash
npm install --save buffer stream-browserify
npm install --save-dev process react-app-rewired
json
{
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  }
}
js
const webpack = require('webpack');

module.exports = function override(config, env) {
  config.resolve.fallback = {
    ...config.resolve.fallback,
    stream: require.resolve("stream-browserify"),
    buffer: require.resolve("buffer"),
    process: require.resolve("process/browser")
  };
  
  config.plugins = [
    ...config.plugins,
    new webpack.ProvidePlugin({
      process: "process/browser",
      Buffer: ["buffer", "Buffer"]
    })
  ];
  
  return config;
};

方案三:Vue.js 项目

Vue CLI 项目可以在 vue.config.js 中配置:

bash
npm install --save buffer stream-browserify
js
const { defineConfig } = require('@vue/cli-service')
const webpack = require('webpack');

module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        Buffer: ['buffer', 'Buffer']
      })
    ],
    resolve: {
      fallback: {
        "stream": require.resolve("stream-browserify"),
        "buffer": require.resolve("buffer")
      }
    }
  }
})

方案四:Vite 项目

对于 Vite 项目,可以使用更简单的方法:

bash
npm install --save buffer
html
<script type="module">
  import { Buffer } from 'buffer';
  window.Buffer = Buffer;
</script>

方案五:全局导入(快速修复)

如果不想修改构建配置,可以在应用的入口文件中添加:

js
import { Buffer } from 'buffer';

// @ts-ignore
window.Buffer = Buffer;

方案六:使用 node-polyfill-webpack-plugin

这个插件会自动包含所有 Node.js 核心模块的 polyfill:

bash
npm install node-polyfill-webpack-plugin --save-dev
js
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');

module.exports = {
  // ... 其他配置
  plugins: [
    new NodePolyfillPlugin()
  ]
};

注意事项

WARNING

  1. 如果需要优化打包体积,可以使用 excludeAliases 配置只包含需要的 polyfill
  2. 对于 Node.js 环境,应直接使用原生模块:
    js
    import { Buffer } from 'node:buffer';
  3. 确保 CSS 文件中没有使用 // 注释,这可能在 Webpack 5 中导致问题

总结

Buffer is not defined 错误是由于 Webpack 5 不再自动提供 Node.js 核心模块的 polyfill 导致的。通过安装相应的 polyfill 包并在 Webpack 配置中正确设置,可以解决这个问题。选择哪种方案取决于你的项目类型和构建工具。