Ionic-framework: PouchDB not working with RC0 due to Rollup+CommonJS

Created on 30 Sep 2016  Â·  48Comments  Â·  Source: ionic-team/ionic-framework

See:

I took a stab at solving this, but ultimately failed due to another module besides PouchDB that Rollup can't handle:

[06:21:04]  Error: Module /Users/nolan/workspace/cutePuppyPics/node_modules/rxjs/Subject.js does not export Subject (imported by /Users/nolan/workspace/cutePuppyPics/node_modules/@angular/core/src/facade/async.js)
    at Module.trace (/Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:7677:29)
    at ModuleScope.findDeclaration (/Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:7300:22)
    at Identifier.bind (/Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:6489:29)
    at /Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:5151:50
    at CallExpression.eachChild (/Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:5165:19)
    at CallExpression.bind (/Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:5151:7)
    at CallExpression.bind (/Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:5842:23)
    at /Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:5151:50
    at ParenthesizedExpression.eachChild (/Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:5168:5)
    at ParenthesizedExpression.bind (/Users/nolan/workspace/cutePuppyPics/node_modules/rollup/dist/rollup.js:5151:7)

There probably exists some combination of Rollup plugins that can work for all npm packages that contain a mix of CommonJS and ES6 modules, but I'm not sure what it is; keep in mind that a lot of what Browserify/Webpack do by default, you have to do with plugins in Rollup-land. (E.g. I'm fairly sure you would need -json, -commonjs, -node-resolve, and -globals at the very least. FWIW this is why, for PouchDB's own build, we opted to _only_ use Rollup to take ES6 source and configure it to highly-optimized CommonJS, and we only used ES6 source for packages that we ourselves controlled. At that point, we assume our consumers are using Browserify or Webpack.)

On the other hand, maybe I'm just dense and @rich-harris can point us in the right direction. Or maybe PouchDB is misusing jsnext:main, and we shouldn't have it point to a module that includes _any_ CommonJS dependencies. I have no idea, honestly. I just know that I tried to solve this problem using only Rollup plugins and was unable.

My sample project in case anyone wants to play with this: I just did ionic create cutePuppyPics --v2 as in the guide and then added pouchdb-browser: https://github.com/nolanlawson/cutePuppyPics-with-pouchdb-browser

Most helpful comment

Hello all! We have made some great progress and now have a working example of PouchDB with Ionic 2 RC.0. We are still throwing around ideas and reviewing this, but it looks like the key is to use namedImports in our rollup.config. I will share more once we have gone over all this. Thanks!

All 48 comments

Whoops, just realized I should have opened this issue on https://github.com/driftyco/ionic-app-scripts

Hm, it's really odd, I've tried every combo of include and exclude for rollup-plugin-commonjs and rollup-plugin-node-resolve and I just can't get it to ignore rxjs/Subject.js. Also I don't understand why Subject is failing in the first place; it looks like a TypeScript dependency? Maybe @robwormald would know?

Fixed by changing "app-scripts/config/rollup.config.js" like this.

Libraries:

  • npm install rollup-plugin-node-builtins
  • npm install rollup-plugin-node-globals

Gist: rollup.config.js

Hm, I tried using rollup-plugin-node-resolve-auto instead of rollup-plugin-node-resolve, and now PouchDB builds correctly, but I get a completely different error about ReferenceError: rxjs_Subject is not defined. :confused:

_(thanks @matheusgarcez for moving to a gist :D)_

Now with the plugin 'pouchdb-find'.

Uncaught TypeError: Cannot read property 'utils' of undefined.

_/node_modules/des.js/lib/des/des.js_

var des = require('../des'); // undefined
var utils = des.utils; // here... reason: circular dependency.
var Cipher = des.Cipher;

Related to:
https://github.com/rollup/rollup-plugin-commonjs/issues/119
https://github.com/rollup/rollup/issues/552

The circular dependency issue, and the fact that @calvinmetcalf was not able to find a solution via Rollup's plugin system, leads me to believe that this is best solved by either 1) using Webpack/Browserify instead of Rollup, or 2) using Rollup in a very limited way (to produce a small CJS bundle), and then following up with Webpack/Browserify. I would recommend making the change to ionic-app-scripts' bundle.ts.

Another possibility would be for the ionic-app-scripts to include a small whitelist of modules that are known to play nice with Rollup, and then use Browserify/Webpack for the rest.

Crypto is a really big dep and it's the one I havn't ported to rollup, it's pretty well modularized so if you only need part of it it should be easy to grab that

@matheusgarcez That pouchdb-find error with crypto should not be happening assuming that the "browser" field is being respected. It's only used in the browser version.

The better so far then would be Ionic get back to gulp/browserify?

@matheusgarcez that just gives it to you if you require it, I think the issue is that you either aren't using the rollup-plugin-node-resolve or it isn't respecting the browser field

If i remove the "rollup-plugin-node-builtins" plugin:

[15:33:56] rollup: No name was provided for external module 'events' in options.globals – guessing 'events'

Uncaught ReferenceError: events is not defined


Commenting the line 34 of https://github.com/calvinmetcalf/rollup-plugin-node-builtins/blob/master/src/index.js#L34:

Uncaught ReferenceError: txt is not defined
g   @   md5.min.js:30
k   @   md5.min.js:57
(anonymous function)    @   md5.min.js:70
g   @   md5.min.js:2
(anonymous function)    @   md5.min.js:3
createCommonjsModule    @   component_factory_resolver.js:61
(anonymous function)    @   index.js:5
(anonymous function)    @   main.dev.js:3

And then changing the file "_node_modules/md5-jkmyers/md5.min.js_":
function g(b){txt="";var c,d=b.length // ... minified file

To:
function g(b){var txt="";var c,d=b.length // ... minified file

Fixes everything.

import PouchDB from "pouchdb-browser";
import PouchDB_Plugin_Find from "pouchdb-find";
import PouchDB_Plugin_QuickSearch from "pouchdb-quick-search";

rollup.config.js:
https://github.com/matheusgarcez/ionic-2rc-pouchdb/blob/master/config/rollup.config.js

Example repository:
https://github.com/matheusgarcez/ionic-2rc-pouchdb

Related issues:
https://github.com/AndreasPizsa/md5-jkmyers/issues/4

now that crypto is the only one i havn't ported I should add an option to
turn that one off

On Fri, Sep 30, 2016 at 2:46 PM Matheus Garcez [email protected]
wrote:

If i remove the "rollup-plugin-node-builtins" plugin:

[15:33:56] rollup: No name was provided for external module 'events' in
options.globals – guessing 'events'

Uncaught ReferenceError: events is not defined

Commenting the line 34 of
https://github.com/calvinmetcalf/rollup-plugin-node-builtins/blob/master/src/index.js#L34:

Uncaught ReferenceError: txt is not defined
g @ md5.min.js:30
k @ md5.min.js:57
(anonymous function) @ md5.min.js:70
g @ md5.min.js:2
(anonymous function) @ md5.min.js:3
createCommonjsModule @ component_factory_resolver.js:61
(anonymous function) @ index.js:5
(anonymous function) @ main.dev.js:3

Changing "_node_modules/md5-jkmyers/md5.min.js_":
function g(b){txt="";var c,d=b.length // ... minified file

To:
function g(b){var txt="";var c,d=b.length // ... minified file

Fixes everything:

import PouchDB_Plugin_Find from "pouchdb-find";
import PouchDB_Plugin_QuickSearch from "pouchdb-quick-search";

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/driftyco/ionic/issues/8356#issuecomment-250822284,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABE4n3yjI1LU-kemk72vWR234pdKmzcqks5qvVkKgaJpZM4KLFxU
.

@matheusgarcez Looks like a bug in md5-jkmyers.

Hello all! We have made some great progress and now have a working example of PouchDB with Ionic 2 RC.0. We are still throwing around ideas and reviewing this, but it looks like the key is to use namedImports in our rollup.config. I will share more once we have gone over all this. Thanks!

@nolanlawson so, how do i can fix it?

There is an open pull request about it:
https://github.com/AndreasPizsa/md5-jkmyers/pull/5

calvinmetcalf/rollup-plugin-node-builtins#18 should help fix with this as well

To fix the Uncaught ReferenceError: txt is not defined error, just set useStrict to false in the rollup.config.js file.

Example:
config/rollup.config.js

@jgw96 Any news on this?

I just tried using:

import * as PouchDB from 'pouchdb-browser';

this.db = new PouchDB('test');

I'm getting this error: TypeError: PouchDB$2 is not a constructor

Use it like this:

@audan2009

import PouchDB from 'pouchdb-browser';

this.db = new PouchDB('test');

I have had endless roll up issues.

Thanks @matheusgarcez ! That worked!

It tried the following the config from @matheusgarcez example repo and I get:

Error: Could not resolve entry (./.tmp/app/main.dev.js)

When I look in the .tmp directory the main.dev.ts file has been copied over but the .js file is missing.

Interesting if I make the edits directly in the @ionic/app-scripts/config/rollup.config.js and remove my custom config everything builds fine.

Anyone encountered this issue?

@matheusgarcez's approach didn't work for me 😞

@nolanlawson I hope you and the Ionic team can find a solution quickly because the has stalled my migration to RC0. Could you ensure [email protected] is also supported as I haven't been able to migrate to 6.x due to another issue.

@glaucocustodio @Bouzmine

Try with the latest repository version:
https://github.com/matheusgarcez/ionic-2rc-pouchdb

Environment:

Ionic App Lib Version: 2.1.0-beta.1
Ionic Framework Version: 2.0.0-rc.0
Ionic CLI Version: 2.1.0
Node Version: v6.7.0

Here's what worked for me:

npm install --save pouchdb
npm install --save pouchdb-quick-search
npm install --save-dev rollup-plugin-node-builtins
npm install --save-dev rollup-plugin-node-globals
npm install --save-dev rollup-plugin-json
npm install js-extend
npm install @types/pouchdb

I use pouchdb-quick-search but there are no typings for it, so I manually created:

node_modules/@types/pouchdb-quick-search/index.d.ts:

declare module 'pouchdb-quick-search' {
  var PouchQuickSearch: any;
  export = PouchQuickSearch;
}

I edited node_modules/@ionic/app-scripts/config/rollup.config.js with this: https://gist.github.com/shaggy8871/7cd2d8222ae67b2bf6d8d141f1d9c07c

I edited node_modules/rollup-plugin-node-builtins/dist/rollup-plugin-node-builtins.es6.js and node_modules/rollup-plugin-node-builtins/dist/rollup-plugin-node-builtins.cjs.js (didn't know which is being used) by commenting out this line:

//libs.set('crypto', require.resolve('crypto-browserify'));

I also changed my require('pouchdb') and require('pouchdb-quick-search') calls to:

import PouchDB from 'pouchdb';
import PouchDB_Plugin_QuickSearch from 'pouchdb-quick-search';
PouchDB.plugin(PouchDB_Plugin_QuickSearch);

Some of these steps may not be necessary, but they worked for me :) Hope it helps someone.

fyi published version 2.0.0 of builtins which only includes crypto if you explicitly include an option to do so

What is the point of moving to rollup.js if its going to break something as wildly used as pouchDB? Can someone please explain? Because my transition from ionic 2.0 beta 11 to ionic2.0.0-RC.0 has been very painful so far.

Just create a declarations.d.ts file and add
'''declare module 'pouchdb'; '''

@realappie it seems somewhat premature to be honest, rollup works pretty well for es6 code but it is in no way (and doesn't claim or pretend to be) a drop in replacement for browserify or webpack and it has much less compatibility

Sorry for belatedly joining this thread – @nolanlawson it looks like the solution to the error in your initial comment...

Module /Users/nolan/workspace/cutePuppyPics/node_modules/rxjs/Subject.js does not export Subject...

...is to use the namedExports option with rollup-plugin-commonjs:

plugins: [
  commonjs({
    ...,
    namedExports: {
      'node_modules/rxjs/Subject.js': ['Subject']
    }
  })
]

CommonJS modules are a little, shall we say, _forgiving_ about how you can structure them in ways that completely defeat static analysis, meaning it's rather hard to determine what module exports what. We do need a more informative error message – I've created an issue (https://github.com/rollup/rollup/issues/1033) – and I had one idea about how to make things work out of the box a bit better, though I don't know how realistic it is: https://github.com/rollup/rollup-plugin-commonjs/issues/125

I've tried following the various discussions about RC0, external deps, modifying rollup config, etc., but still get "extend.js does not export extend" errors on build.

Where has the dust settled on this? Do we have a direction on how to install and import pouch? If this commit fixes it, do we just need a PouchDB v6.0.7 cut to achieve ultimate happiness?

@dendrochronology If you only followed creating the config, that was incomplete. There are additional changes that are listed above that are not on the docs page yet.

Look for rollup-plugin-node-builtins and rollup-plugin-node-globals and the associated rollup.config.js

@sovanyio so I need to manually export extend in the builtins() and globals() as well? I don't suppose you have an example, do you? :-)

@dendrochronology the config is linked here. The two additions address followup problems after you explicitly tell rollup about extend.

The build cli output actually spits out the error after echoing that it failed to find the overridden config file (due to errors in it).

Yeah, I thought I was doing all that (created custom rollup.config.js in cutePuppyPics/scripts, npm installed stuff, still get:

Module /Users/foo/Projects/cutePuppyPics/node_modules/js-extend/extend.js does not export extend

Can you post more from the log?

@dendrochronology see the Bundle section on https://ionicframework.com/docs/v2/resources/app-scripts/.

Has anyone been able to successfully get ionic emulate iOS to work with any of the workarounds?

I recently tried @matheusgarcez repo and that worked for ionic serve.

I can't get ionic emulate iOS to work. It might be unrelated. Posted in the forum here:

https://forum.ionicframework.com/t/ionic-emulate-ios-error-error-could-not-resolve-entry-tmp-app-main-dev-js/66508/1

@audan2009 It worked for me. You have to update to @ionic/app-scripts because v0.0.27 doesn't set up the process.env.IONIC_ENV correctly. With the latest version you have to remove ngTemplate from your config.

@Bouzmine thank you thank you!

are there any workarounds?

I just released PouchDB 6.0.7. Our solution was to drop the js-extend dependency because Rollup can't seem to handle it.

It's not an ideal solution, but PouchDB now works out-of-the-box with Ionic 2. You can get the fix by merely doing npm update.

I'll close this issue because the title itself is no longer applicable. The core problem still exists (e.g. if any Ionic users actually legitimately do want to use js-extend or similar modules with tricky export patterns) but I'll leave it up to Ionic/Rollup if they'd like to fix the root problem.

Much appreciated thanks @nolanlawson

Was this page helpful?
0 / 5 - 0 ratings

Related issues

manucorporat picture manucorporat  Â·  3Comments

masimplo picture masimplo  Â·  3Comments

gio82 picture gio82  Â·  3Comments

MrBokeh picture MrBokeh  Â·  3Comments

vswarte picture vswarte  Â·  3Comments