I've created a brand new project with npm init vite bar -- --template vue
. I've done an npm install web3
and I can see my package-lock.json
includes this package. My node_modules
directory also includes the web3
modules.
So then I added this line to main.js
:
import { createApp } from 'vue'
import App from './App.vue'
import Web3 from 'web3' <-- This line
createApp(App).mount('#app')
And I get the following error:
I don't understand what is going on here. I'm fairly new to using npm
so I'm not super sure what to Google. The errors are coming from node_modules/web3/lib/index.js
, node_modules/web3-core/lib/index.js
, node_modules/web3-core-requestmanager/lib/index.js
, and finally node_modules/util/util.js
. I suspect it has to do with one of these:
<script setup>
tag (but I imported it in main.js
so I don't think it is this one)web3js
is in Typescript and my Vue3 project is not configured for TypescriptBut as I am fairly new to JavaScript and Vue and Web3 I am not sure how to focus my Googling on this error. My background is Python, Go, Terraform. Basically the back end of the back end. Front end JavaScript is new to me.
How do I go about resolving this issue?
Polyfilling the Node globals and modules enables the web3
import to run in the browser:
npm i -D @esbuild-plugins/node-globals-polyfill
npm i -D @esbuild-plugins/node-modules-polyfill
Configure optimizeDeps.esbuildOptions
to use these ESBuild plugins.
Configure define
to replace global
with globalThis
(the browser equivalent).
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',
},
},
},
})
Note: The polyfills add considerable size to the build output.
web3
distributes a bundled script at web3/dist/web3.min.js
, which can run in the browser without any configuration (listed as "pure js"). You could configure a resolve.alias
to pull in that file:
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',
},
],
},
})
Note: This option produces 469.4 KiB smaller output than Option 1.