unenv icon indicating copy to clipboard operation
unenv copied to clipboard

Polyfilling Node APIs

Open wobsoriano opened this issue 3 years ago β€’ 4 comments

I am trying to polyfill a certain module that uses process, buffer, utils, etc.

I'm not sure how to use unenv since it's lacking an example or I've not seen a usage somewhere yet. So far, this is what I've accomplished with vite:

import { defineConfig } from 'vite'
import { env, nodeless } from 'unenv'

const { alias } = env(nodeless)

// https://vitejs.dev/config/
export default defineConfig({
  define: {
    global: 'globalThis',
  },
  resolve: {
    alias
  }
})

It throws this error when running the app:

✘ [ERROR] Could not resolve "./_buffer"

    node_modules/unenv/runtime/node/buffer/index.cjs:34:22:
      34 β”‚ var _buffer = require("./_buffer");
         β•΅                       ~~~~~~~~~~~

✘ [ERROR] Could not resolve "../../_internal/utils"

    node_modules/unenv/runtime/node/buffer/index.cjs:36:21:
      36 β”‚ var _utils = require("../../_internal/utils");
         β•΅                      ~~~~~~~~~~~~~~~~~~~~~~~

Am I missing something here? Thank you!

wobsoriano avatar May 29 '22 04:05 wobsoriano

Okay. I'm not sure if this is a proper way of using unenv but it works

// vite.config.ts
import { env, nodeless } from 'unenv'

const { alias } = env(nodeless)

// remove buffer to fix the issue "could not resolve "./_buffer"
const { buffer: _, ...rest } = alias

// https://vitejs.dev/config/
export default defineConfig({
  define: {
    global: 'globalThis',
  },
  resolve: {
    alias: {
      ...rest,
    },
  },
})
<!DOCTYPE html>
<html lang="en">
  <head>
    <script type="module">
      import process from 'node:process'
      import { Buffer } from 'node:buffer'
      import EventEmitter from 'node:events'
      window.process = process
      window.Buffer = Buffer
      window.EventEmitter = EventEmitter
    </script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

wobsoriano avatar May 29 '22 08:05 wobsoriano

Hi @wobsoriano. I believe unenv would return defines as well but yeah overall this is a good integration! Would you like to help on adding documentation for Rollup and Vite usage?

pi0 avatar May 31 '22 20:05 pi0

Hello @pi0 . So the module I was trying to polyfill is ethers. It needs different built-in modules and access to global/globalThis in client.

Normally you would do npm install buffer events process util but since unenv already offers a polyfill of it you won't have to install them all!

This is how I do it before:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  define: {
    global: 'globalThis',
  },
  resolve: {
    alias: {
      process: 'process/browser',
      util: 'util',
    },
  },
})
<!DOCTYPE html>
<html lang="en">
  <head>
    <script>window.global = window;</script>
    <script type="module">
      import process from "process";
      import { Buffer } from "buffer";
      import EventEmitter from "events";
      
      window.process = process;
      window.Buffer = Buffer;
      window.EventEmitter = EventEmitter;
    </script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

and now, using unenv

import { env, nodeless } from 'unenv'

const { alias } = env(nodeless)

export default defineConfig({
  define: {
    global: 'globalThis',
  },
  resolve: {
    alias,
  },
})
<!DOCTYPE html>
<html lang="en">
  <head>
    <script type="module">
      import process from 'node:process'
      import { Buffer } from 'node:buffer'
      import EventEmitter from 'node:events'
      window.process = process
      window.Buffer = Buffer
      window.EventEmitter = EventEmitter
    </script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

wobsoriano avatar Jun 01 '22 17:06 wobsoriano

Might work similar as it does in the PR ☺️

TheAlexLichter avatar May 05 '24 19:05 TheAlexLichter