Web3js 无法在 Vue3 组合 api 项目中导入

Web3js fails to import in Vue3 composition api project

我用 npm init vite bar -- --template vue 创建了一个全新的项目。我已经完成了 npm install web3,我可以看到我的 package-lock.json 包含这个包。我的 node_modules 目录还包括 web3 模块。

然后我将这一行添加到 main.js:

import { createApp } from 'vue'
import App from './App.vue'
import Web3 from 'web3'   <-- This line


createApp(App).mount('#app')

我收到以下错误:

我不明白这是怎么回事。我对使用 npm 还很陌生,所以我不太确定要 Google 做什么。错误来自 node_modules/web3/lib/index.jsnode_modules/web3-core/lib/index.jsnode_modules/web3-core-requestmanager/lib/index.js,最后是 node_modules/util/util.js。我怀疑这与其中之一有关:

  1. 我正在使用 Vue 3
  2. 我正在使用 Vue 3 组合 API
  3. 我正在使用 Vue 3 Composition API SFC <script setup> 标签(但我在 main.js 中导入了它,所以我认为不是这个)
  4. web3js 在 Typescript 中,我的 Vue3 项目没有为 Typescript 配置

但是由于我对 JavaScript、Vue 和 Web3 还很陌生,所以我不确定如何将我的谷歌搜索重点放在这个错误上。我的背景是 Python,Go,Terraform。基本上后端的后端。前端 JavaScript 对我来说是新手。

我该如何解决这个问题?

选项 1:Polyfill 节点 globals/modules

Polyfilling Node 全局变量和模块使 web3 导入到浏览器中的 运行:

  1. 安装 ESBuild plugins 那个 polyfill 节点 globals/modules:
npm i -D @esbuild-plugins/node-globals-polyfill
npm i -D @esbuild-plugins/node-modules-polyfill
  1. 配置 optimizeDeps.esbuildOptions 以使用这些 ESBuild 插件。

  2. 配置 define 以将 global 替换为 globalThis(等效浏览器)。

import { defineConfig } from 'vite'
import GlobalsPolyfills from '@esbuild-plugins/node-globals-polyfill'
import NodeModulesPolyfills from '@esbuild-plugins/node-modules-polyfill'

export default defineConfig({
  ⋮
  optimizeDeps: {
    esbuildOptions: {
      2️⃣
      plugins: [
        NodeModulesPolyfills(),
        GlobalsPolyfills({
          process: true,
          buffer: true,
        }),
      ],
      3️⃣
      define: {
        global: 'globalThis',
      },
    },
  },
})

demo 1

注意:polyfill 会显着增加构建输出的大小。

选项 2:使用预捆绑脚本

web3web3/dist/web3.min.js 分发了一个捆绑脚本,它可以 运行 在浏览器中无需任何配置(列为 "pure js"). You could configure a resolve.alias 以拉入该文件:

import { defineConfig } from 'vite'

export default defineConfig({
  ⋮
  resolve: {
    alias: {
      web3: 'web3/dist/web3.min.js',
    },

    // or
    alias: [
      {
        find: 'web3',
        replacement: 'web3/dist/web3.min.js',
      },
    ],
  },
})

demo 2

注意:此选项产生 469.4 KiB 比选项 1 小的输出。

你可以通过在你的 vite 配置中添加这个来避免 Uncaught ReferenceError: process is not defined 错误

export default defineConfig({
  // ...
  define: {
    'process.env': process.env
  }
})

我找到了最佳解决方案。

问题是因为你丢失了window.process变量,并且进程只存在于节点上,而不存在于浏览器上。

所以你应该在应用加载时将它注入浏览器。

将此行添加到您的应用程序:

window.process = {
  ...window.process,
};