使用web3一些前端库报webpack5问题的解决办法

424 阅读2分钟

fork: github.com/yuanjunlian…

其他库集成文档: docs.cloud.coinbase.com/wallet-sdk/…

While setting up a new web3 project from scratch, you might face multiple issues with webpack 5. This issue is caused due to the fact that the web3.js and ethers.js packages have certain dependencies, which are not present within the browser environment by webpack 5. Hence, you require certain node polyfills to be added to your project, while overriding the configurations to enable their usage. When that is done, your project should be able to utilise the web3.js and ethers.js packages easily without any issues.

In this guide, we have added instructions of adding the polyfills of some of the commonly used web frameworks:

React


create-react-app

If you are using create-react-app version >= 5 you may run into issues building. The issue can be resolved following the instructions below:

Solution

  • Install react-app-rewired and the missing modules into your application

<Tabs defaultValue="npm" values={[ { label: "npm", value: "npm" }, { label: "yarn", value: "yarn" }, ]}

npm install --save-dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process
yarn add --dev react-app-rewired process crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer
  • Create config-overrides.js in the root of your project folder with the content:
const webpack = require("webpack");

module.exports = function override(config) {
  const fallback = config.resolve.fallback || {};
  Object.assign(fallback, {
    crypto: require.resolve("crypto-browserify"),
    stream: require.resolve("stream-browserify"),
    assert: require.resolve("assert"),
    http: require.resolve("stream-http"),
    https: require.resolve("https-browserify"),
    os: require.resolve("os-browserify"),
    url: require.resolve("url"),
  });
  config.resolve.fallback = fallback;
  config.plugins = (config.plugins || []).concat([
    new webpack.ProvidePlugin({
      process: "process/browser",
      Buffer: ["buffer", "Buffer"],
    }),
  ]);
  return config;
};
  • Within package.json change the scripts field for start, build and test. Instead of react-scripts replace it with react-app-rewired

<Tabs defaultValue="after" values={[ { label: "before", value: "before" }, { label: "after", value: "after" }, ]}

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
},
"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
},

The missing Nodejs polyfills should be included now and your app should be functional with web3.

  • If you want to hide the warnings created by the console:

In config-overrides.js within the override function, add:

config.ignoreWarnings = [/Failed to parse source map/];

这里可以通过在env中添加GENERATE_SOURCEMAP=false来屏蔽WARNING

"start": "GENERATE_SOURCEMAP=false react-app-rewired start"

或者在.env中添加

GENERATE_SOURCEMAP=false
If you're using craco, similar changes need to be made to craco.config.js

Angular


If you are using Angular version >11, you may run into issues building. The issue can be resolved following the instructions below:

Solution

  • Install the required dependencies within your angular project:

<Tabs defaultValue="npm" values={[ { label: "npm", value: "npm" }, { label: "yarn", value: "yarn" }, ]}

npm install --save-dev crypto-browserify stream-browserify assert stream-http https-browserify os-browserify process buffer url
yarn add --save-dev crypto-browserify stream-browserify assert stream-http https-browserify os-browserify process buffer url
  • Within tsconfig.json add the following paths in compilerOptions so Webpack can get the correct dependencies
{
    "compilerOptions": {
        "paths" : {
            "crypto": ["./node_modules/crypto-browserify"],
            "stream": ["./node_modules/stream-browserify"],
            "assert": ["./node_modules/assert"],
            "http": ["./node_modules/stream-http"],
            "https": ["./node_modules/https-browserify"],
            "os": ["./node_modules/os-browserify"],
            "process": ["./node_modules/process"],
        }
    }
}
  • Add the following lines to polyfills.ts file:
import { Buffer } from "buffer";

(window as any).global = window;
global.Buffer = Buffer;
global.process = {
  env: { DEBUG: undefined },
  version: "",
  nextTick: require("next-tick"),
} as any;

Vue.js


If you are using vue.js you may run into issues building. The issue can be resolved following the instructions below:

Solution

  • Install the missing modules

<Tabs defaultValue="npm" values={[ { label: "npm", value: "npm" }, { label: "yarn", value: "yarn" }, ]}

npm install --save node-polyfill-webpack-plugin
yarn add node-polyfill-webpack-plugin

Add the following lines to vue.config.js

const { defineConfig } = require("@vue/cli-service");
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
  configureWebpack: {
    plugins: [new NodePolyfillPlugin()],
    optimization: {
      splitChunks: {
        chunks: "all",
      },
    },
  },
});

Vite/Svelte/Rollup

If you are using vite/svelte/rollup you may run into issues building. This is because NodeJS polyfills are not included.

Solution

  • Install the missing modules

<Tabs defaultValue="npm" values={[ { label: "npm", value: "npm" }, { label: "yarn", value: "yarn" }, ]}

npm install --save-dev crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process
yarn add --dev process crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer

Add the following lines to svelte.config.js or rollup.config.js or vite.config.js

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
import { NodeModulesPolyfillPlugin } from "@esbuild-plugins/node-modules-polyfill";
import rollupNodePolyFill from "rollup-plugin-node-polyfills";
import builtins from "rollup-plugin-node-builtins";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  optimizeDeps: {
    esbuildOptions: {
      plugins: [
        NodeGlobalsPolyfillPlugin({
          process: true,
          buffer: true,
        }),
        NodeModulesPolyfillPlugin(),
      ],
    },
  },
  build: {
    rollupOptions: {
      plugins: [
        // Enable rollup polyfills plugin
        // used during production bundling
        builtins(),
        rollupNodePolyFill(),
      ],
    },
  },
});