简体   繁体   中英

Bundling pouchdb-adapter-memory with Rollup

I am attempting to use the memory adapter for PouchDB . I want to bundle my application (along with dependencies like Pouch and this adapter) using Rollup . In order to reduce this to a minimally reproducible issue imagine this is my application I want to bundle:

import PouchDB from 'pouchdb-browser'
import MemoryAdapterPlugin from 'pouchdb-adapter-memory'

PouchDB.plugin(MemoryAdapterPlugin)

Since I am using a node module I'm obviously going to need the rollup-node-resolve Rollup plugin . Also many of PouchDB's dependent modules are in CJS format so I'm going to also need therollup-node-commonjs Rollup plugin . Finally PouchDB makes use of some built-in Node modules (such as events ) and the memory adapter even more ( buffer , etc). I'm not sure these are used at runtime (it may be just in PouchDB's code because it can work in Node or the browser) but to prevent a bundling error I'm going to also include the rollup-plugin-polyfill-node plugin but direct the resolve plugin to prefer built-ins to the browser target if they are needed and available.

With all that in place here is my rollup config:

import commonjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import polyfillNode from 'rollup-plugin-polyfill-node'

export default {
  input: 'index.js',
  output: {
    format: 'iife',
    name: 'app',
    file: 'bundle.js'
  },
  plugins: [
    commonjs({
      requireReturnsDefault: "auto",
    }),

    polyfillNode(),

    resolve({
      preferBuiltins: true,
      browser: true
    }),
  ]
}

This will bundle. But when I load up the bundle in a browser I get an error about the inherits polyfill not working at this line:

https://github.com/FredKSchott/rollup-plugin-polyfill-node/blob/main/polyfills/inherits.js#L7

It says superCtor is undefined. If I step back a level on the backtrace it comes from this line:

https://github.com/nodejs/readable-stream/blob/main/lib/_stream_duplex.js#L46

The Readable is undefined. When I bundle I get warnings about circular references. I think it fundementally revolves around the fact that some of the PouchDB dependencies use NPM packages as polyfills explicitly (like inherits and readable-stream) while the polyfillNode plugin is also providing some of those same polyfills and they are doing so in an incompatible way. But I don't know how to untangle it.

Finally was able to resolve this so going to provide the answer in case someone else needs to bundle PouchDB memory adapter in Rollup.

The readable streams polyfill is a mess of circular dependencies. This is fine under a CJS format but since Rollup converts CJS to ES format it becomes problematic as Rollup can't figure out the proper order to put things in. This leads to the use of inherits where the superclass is not yet defined. The readable streams polyfill has an open ticket regarding this. The general solution is to fix it upstream in Node and then cut a new copy of the polyfill based on that upstream fix. The upstream fix was made but the polyfill hasn't yet been updated. Once it is this should naturally resolve itself.

In the meantime we can use someone else's fork of the polyfill that has the circular dependencies resolved. This fork is mentioned in that issue but the punchline is to add this to the package.json :

"readable-stream": "npm:vite-compatible-readable-stream@^3.6.0",

This will force readable-stream to resolve to that fork. But that's not the whole story. There are some dependencies of the memory adapter that are locked to a different version of readable-stream. To resolve that we want to add the following to our rollup's resolve plugin:

dedupe: ['readable-stream']

This will force the readable-stream substitute that we have explicitly added to our project to be used anytime a readable stream is needed.

The final issue is that PouchDB is using an ancient version of memdown that also has circular dependency issues. The latest version does not and seems to work with the memory adapter just fine. There is an open ticket at PouchDB to update memdown and this will naturally resolve when that happens.

In the meantime to resolve that we are going follow a similar pattern as above. We will explicitly require memdown into our project although no need for a fork. Just a newer version. Then to force the memory adapter to use this version we add memdown to that dedup option as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM