pouchdb: Module build for browser breaks when built with vite

Issue

When including PouchDB in vite projects, vite removes all Node modules when building for the browser. During the bundling phase, vite outputs externalized node built-in "events" to empty module and in the browser I get the error Module "events" has been externalized for browser compatibility and cannot be accessed in client code.

The workaround explained in #8130 does not work any more.

My suggestion for a solution would be to add the node-polyfills rollup plugin when building the browser es6 module. This will replace the “events” builtin with functionally identical code. I could try to provide a patch.

Info

  • Environment: browser
  • Build System: Vite/Rollup

Reproduce

Create a new vite app and add the line import PouchDB from 'pouchdb-browser' to the file main.js

npm init vite-app testApp
cd testApp
npm i && npm i pouchdb-browser
npm run dev

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 7
  • Comments: 19

Commits related to this issue

Most upvoted comments

I got this working with two steps:

  1. Alias global to window in vite.config.js:
export default {
  define: {
    global: "window",
  },
};

2: npm install events

No other config necessary.

I haven’t worked with electron for quite a while, but for my most recent (small) project I used vite-plugin-html to work around the problem along with adding two lines in index.html

In vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import injectHtml from 'vite-plugin-html';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    injectHtml({
      inject: {
        data: {
          injectEnv: '<script type="module">window.process = window.process || { env: { NODE_ENV: import.meta.env.DEV } }</script>'
        }
      }
    })
  ],
  build: {
    outDir: './dist',
    emptyOutDir: true
  }
})

In index.html’s <head> tag

<!DOCTYPE html>
<html lang="en">
<head>
	<%- injectEnv %>
	<script>window.process = window.process || { env: { NODE_ENV: 'production' } }</script>
</head>
</html>

The reason why there’s two definitions of window.process is because of a difference in how it’s built/bundled depending on if you’re running dev or build. Hope this works for your case @hcker2000

Here is my setup that I got working with vite@2.0.0-beta.52 (the current version is .53, but is totally broken). My apologies if it’s not relevant for this issue.

// package.json (left out irrelevant packages)
"dependencies": {
    "events": "^3.2.0",
    "pouchdb-browser": "^7.2.2",
    "process": "^0.11.10",
    "vue": "^3.0.5",
    "vue-router": "^4.0.3"
  },
  "devDependencies": {
    "@rollup/plugin-node-resolve": "^9.0.0",
    "@vitejs/plugin-vue": "^1.1.2",
    "@vue/compiler-sfc": "^3.0.5",
    "eslint-plugin-vue": "^6.2.2",
    "vite": "^2.0.0-beta.52"
  }
// vite.config.js
import pluginVue from '@vitejs/plugin-vue';

export default {
	hostname: '127.0.0.1',
	optimizeDeps: {
		allowNodeBuiltins: ['pouchdb-browser', 'pouchdb-utils', 'base64id', 'mime-types'],
		include: ['pouchdb-live-find/dist/index.es.js']
	}
	plugins: [pluginVue()],
}
// main.js as the first line
import process from 'process/browser';
window.process = process;

window.global = window;

I didn’t run into the issue with events being undefined, but that was solved for me in #8130.

Edit: Added window.global = window; to main.js

I got this working with two steps:

  1. Alias global to window in vite.config.js:
export default {
  define: {
    global: "window",
  },
};

2: npm install events

No other config necessary.

I have the same problem, your answer works, thx.

Great @jbjorge please let me know if you need any assistance. I love Couchdb - Cloudant, Pouchdb and Vue. They are my main tools.

As you stated, hope the author of the issue could find the information you have shared useful.