pouchdb: PouchDB not working with Angular 6.0.0

Issue

PouchDB and PouchDBFind do not work with Angular 6.0.0, throwing an error as soon as a new PouchDB instance is created, or as soon as an index is created.

Info

  • Environment: Angular 6.0.0 (Angular CLI 6.0.0 and Node.js v8.9.4)
  • Platform: Chrome 66.0.3359.139 (64 bits)
  • Adapter: IndexedDB
  • Server: No server needed to reproduce the error

Reproduce

This simple example should be enough to reproduce the issue: https://stackblitz.com/edit/angular-rgm8ga. It does not crash on stackblitz but it does if the project is built with the Angular CLI 6.0.0 (simply run ng serve)

I believe the problem is related with the fact that the Angular CLI 6.0.0 stopped providing shims for global and process. See this comment: https://github.com/angular/angular-cli/issues/9827#issuecomment-369578814

The project compiles fine with the CLI but after opening the browser the error thrown is screenshot_1 when the PouchDB instance is created:

After some research, I added (window as any).global = window; to polyfills.ts, and the error thrown is now screenshot_2 when trying to create an index.

Any idea how to solve this issue? I have a project that relies heavily on PouchDB, but there are some other Angular-related libraries I’m using whose newest features are only avaliable for Angular 6, so I’d really like to update to Angular 6 while keeping PouchDB.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 12
  • Comments: 25 (3 by maintainers)

Most upvoted comments

The following in polyfills.ts will fix PouchDB with PouchDBFind plugin:

(window as any).global = window;
(window as any).process = {};
(window as any).process.nextTick = setTimeout;

with

import PouchDB from 'pouchdb';
import PouchFind from 'pouchdb-find';
PouchDB.plugin(PouchFind);

As suggested,

import * as PouchDB from 'pouchdb/dist/pouchdb';
import * as PouchDBUpsert from 'pouchdb-upsert/dist/pouchdb.upsert';
[..]

does solve the issue in Angular 6. It’s not ideal but it works 😉

The memory adapter also seems to have an issue with indirectly depending on stream via readable-stream:

├─┬ pouchdb-adapter-memory@6.4.3 │ └─┬ pouchdb-adapter-leveldb-core@6.4.3 │ ├─┬ levelup@2.0.1 │ │ └─┬ level-iterator-stream@2.0.0 │ │ └── readable-stream@2.3.6 deduped │ ├─┬ sublevel-pouchdb@6.4.3 │ │ └── readable-stream@1.0.33 │ └─┬ through2@2.0.3 │ └── readable-stream@2.3.6 deduped

ERROR in ./node_modules/sublevel-pouchdb/node_modules/readable-stream/readable.js
Module not found: Error: Can't resolve 'stream' in '/tmp/ng6/node_modules/sublevel-pouchdb/node_modules/readable-stream'
ERROR in ./node_modules/sublevel-pouchdb/node_modules/readable-stream/lib/_stream_readable.js
Module not found: Error: Can't resolve 'stream' in '/tmp/ng6/node_modules/sublevel-pouchdb/node_modules/readable-stream/lib'
ERROR in ./node_modules/sublevel-pouchdb/node_modules/readable-stream/lib/_stream_writable.js
Module not found: Error: Can't resolve 'stream' in '/tmp/ng6/node_modules/sublevel-pouchdb/node_modules/readable-stream/lib'

@daleharvey The Angular CLI uses webpack to build javascript code. I don’t actually know how webpack works, but from what I understood, what happened is that the Angular CLI 6 removed the code that tells webpack to turn node.js built-ins like global and process into code that the browser understands. (link to the commit) Their reasoning is that libraries should not assume the environment they’re running on, and if they’re intended to run both on node and the browser, then they should provide a separate web version. (I tried using pouchdb-browser btw, but I still got the same errors)

I managed to fix the first error I posted above by adding

(window as any).global = window;

to src/polyfills.ts.

The second error comes from PouchDB Find code, which calls process.nextTick() at some point when creating an index. (I saw that you closed an issue related to this, but the current release still uses process.nextTick() instead of setTimeout)

Anyway, for the time being I managed to fix the second error by manually importing the code that webpack uses to polyfill process in the browser. I downloaded this file and saved it as src/node-polyfills/process/polyfill.js (I removed lines 16-24) and then inside src/polyfills.ts added the following code:

import * as pr from './node-polyfills/process/polyfill';
(window as any).process = pr;

I understand this is a workaround, but until the Angular CLI provides a way to override the node webpack config it’ll have to do.

this works for me var PouchDB = require(‘pouchdb-browser’);

let pouchdb = PouchDB.default.defaults(); let db = new pouchdb(‘mydb’); db.info().then(info => console.log(info));

dist/pouchdb.find does seem to expect a global PouchDB object to be available.

You may have better luck with going back to

import PouchDB from 'pouchdb';

and then adding

(window as any).global = window;

to your polyfills.ts file as suggested here

@daleharvey this is worth reopening as it’s still a problem. a one line shim will fix this

import * as PouchDB from ‘pouchdb/dist/pouchdb’;

these code work for me when i code in polymer3. thanks.