RC0 - library dependency export (jwt-angular2, js-base64)

We are migrating/upgrading from beta11 to rc0 and use the jwt-angular2 lib.
This lib has a dependency on js-base64.

But when running the app the jwt-angular2 call to js-base64 throws following Exception:

list-page.ts:57 TypeError: Cannot read property ‘decode’ of undefined
at JwtHelper.urlBase64Decode (http://localhost:8100/build/main.js:85725:34)
at JwtHelper.decodeToken (http://localhost:8100/build/main.js:85732:28)
at JwtHelper.getTokenExpirationDate (http://localhost:8100/build/main.js:85740:24)
at JwtHelper.isTokenExpired (http://localhost:8100/build/main.js:85749:25)
at tokenNotExpired (http://localhost:8100/build/main.js:85768:40)
at AuthHttp.requestWithToken (http://localhost:8100/build/main.js:85632:14)
at MergeMapSubscriber.project (http://localhost:8100/build/main.js:85666:109)
at MergeMapSubscriber._tryNext (http://localhost:8100/build/main.js:85472:27)
at MergeMapSubscriber._next (http://localhost:8100/build/main.js:85462:18)
at MergeMapSubscriber.Subscriber.next (http://localhost:8100/build/main.js:6652:18)

Caused by the following call (angular2-jwt.ts, version: 0.1.24, line 192):

return Base64.decode(output);

which i assume is or was translated to (angular2-jwt.js, version: 0.1.24, line 189):

return js_base64_1.Base64.decode(output);

The referenced js_base64_1 variable is set at (angular2-jwt.js, version: 0.1.24, line 16):

var js_base64_1 = require(‘js-base64’);

The require call gets replaced in the main.js with:

var js_base64_1 = base64;

I tracked the library export down in the main.js and also inserted console logs:

var base64 = createCommonjsModule(function (module) {

(function(global) {

// export Base64
global.Base64 = {

};

})(commonjsGlobal);
});
console.log(“base64.Base64”);
console.log(base64.Base64);

The line console.log(base64.Base64) returns “undefined”.

Everything should be in place:

npm install angular2-jwt.js --save

results in following folders:

node_modules\angular2-jwt (contains ts, js and d.ts)
node_modules\js-base64 (contains only js)

We also tested it with typings for js-base64 to no avail.

I assume the problem lies in the way the js-base64 lib is exported but do not know how to fix it.

With a lot of tinkering i managed to get angular2-jwt working. But its not a permanent solution/fix.

If I manually add following line to the main.js inside the createCommonjsModule block:


// export Base64
global.Base64 = {

};
module.exports.Base64=global.Base64;

the base64.Base64 variable finally contains the exported object from js-base64.

This further indicates that the js-base64 needs fixing. Can someone confirm this?

I have the same issues. Anyone have any idea?

It very well could have to do with Rollup injecting crypto from Node land. Try removing globals and builtins from the Rollup config for now.

We are considering supporting Webpack as well since some 3rd party libraries are not working well with Rollup.

Thanks,
Dan

If my problem is similar, globals are fine. It’s builtins that causes trouble with crypto.

That would be great, I found rollup one problem after another with third party libs. I am almost at the stage of trying to port over the old ionic beta gulp build process.

Thank you for the suggestion.

Unfortunately disabling anything in the rollup.config.js does not produce better results. Either buffer is missing or globals and cause the app to break completely.

For now I roll with my wonky fix:

  • Include following line in a custom base64.js file (line 170):
    module.exports.Base64=global.Base64;
  • A pre-build task copies this file over /node_modules/js-base64/base64.js
1 Like

Is that a big change if we back to webpack? And why we just using gulp as before?

Allow me to elaborate here for clarity.

TL;DR

We know there’s issues. The entire Angular community is dealing with them, not just Ionic. We’re working hard to fix them - both our code and working with library producers to make things better. We know some members of the community are struggling right now with libraries. We’re doing everything we can as fast as we can to get this situation squared away.

Gulp

If we were using gulp, we’d still be seeing the same issues we’re seeing today. gulp is just a task runner, so you give it a task, and it runs it. It works well - but hasn’t had a lot of updates recently and we were seeing a lot of deprecation warnings. npm scripts enable basically the same thing without the added overhead of gulp. This allows us to reduce dependencies, speed up install time, and take one moving part out of the equation.

Where we’ve seeing issues right now really boils down to two things:

Taking the compiled JS files and bundling them into one large bundle.

When Ionic 2 first went into Beta, we used Webpack. This drew the ire of the community because it was hard to use and configure. We made the decision to switch to Browserify. Browserify is simpler to use than Webpack, and works decently for the most part.

We decided to try a new tool called Rollup for bundling with the RC release because it is proven to produce a script that the browser can process and execute faster. See this great read from Nolan Lawson on the subject. When we tested it out internally, we did not see any issues at all. Everything was working great! In our tests, Rollup apps did start up in about 1/3 of the time that a Webpack or Browserify app did. So that was great and very validating. This is important since we are not just web apps, we compete with and are compared to native apps on devices that boot up instantly.

However, when we released to the masses, we’ve found that this tool does not work great with many libraries Ionic developers are using. Sometimes it requires configuration to get it to work, and sometimes it just doesn’t work at all.

In the meantime, since the Ionic beta release, Webpack has grown tremendously in popularity.

So, there’s where we’re at now. We think Rollup is the future, but we recognize that the community isn’t there yet. With that said, we are investigating in exposing Webpack as an option to bundle apps when Rollup simply won’t work.

Hopefully this will provide a good balance to the community to build the apps they want with the tools they want. If an app uses a library that Rollup can’t handle, they can accept the tradeoff and use the slightly slower webpack.

Stay tuned. I hope we’ll have more to share on this topic soon. Please let me know what you all think about this.

Many popular Angular libraries are not set-up for ngc.

ngc, or the Angular ahead-of-time compiler is very strict. It takes Typescript as an input, processes it, and outputs better Typescript essentially (for component/directive/etc files). Because it is working off of Typescript, public/private must be correct on variables/properties, variables must be declared correctly ahead of time, things must be typed correctly, etc for it to work. This is a bit of a change from Angular 1 and even earlier Angular 2 development. It is way more strict - and it can be challenging. We’re confident that the Angular team will continue to iterate on this to make it easier to use and more forgiving.

We’re also finding that a lot of libraries out there are not being compiled ahead-of-time correctly, and this is breaking compatibility with apps that are compiled with ngc. Whenever an Ionic app is run on a device, it is compiled with ngc. Basically, they may contain the NgModule in the lib, but they often times lack the proper AoT metadata needed.

Basically, the community is in a transition period right now. Bear with us - developers would be seeing the same challenges with vanilla Angular 2 apps that they are with Ionic apps right now. The community will get these issues resolved. We are dedicated to helping the community get to where it needs to go to be successful. I am working on producing documentation for library authors right now on how to get their library squared away. I have seen this metadata issue with ~10 different popular Angular libraries or so in the past couple weeks since we released RC.0.

Anyway, sorry for the novel. I just wanted to give some insight into where we’re at and what we’re thinking. Of course, these are just my opinions and may not be reflective of the entire team.

Happy to discuss further, but probably later. We have a lot of work to do to get everything in great shape for the community.

Thanks,
Dan

4 Likes

Thank you so much for the explain! :slight_smile:!

For right now! Our project for rollup is working pretty well.

  1. chart.js
  2. moment
  3. underscore.

Only problem is the angular-jwt. but it’s NOT the rollup issues.

And Rollup as you said its fast and easy to config, once you know the magic. :slight_smile:

Thanks again.

Hello @biller_anton
Thanks for the tips! And I think this fix my issues.

@danbucholtz, seems now! I think I get use to the new build process which is using the rollup. You are right, it make more sense!

Keep up the great works.

Thanks guys

We have a very huge package.json and I can’t bisect it all to find out why we are getting a white screen on devices with RC1 and no error message.

So is would be really helpful if somebody could compile a list of libraries that are currently know to break with rollup.


Here we go!

1 Like

Hi, for me the issue is with the Base64 decode, the workaround was to use a custom rollup.config.js to export Base64 from js-base64:

commonjs({
            namedExports: {
             ..
                // js-base64
                'node_modules/js-base64/base64.js': ['Base64']

..
            }
        }),

and to modify node-modules/angular2-jwt/angular2-jwt.js to use the global Base64 (in JwtHelper.prototype.urlBase64Decode()) :
return global.Base64.decode(output);

I think angular2-jwt needs to modify it’s reference to Base64 to be specific to the scope and js-base64 needs to explicitly export Base64!

1 Like

Thanks a lot for this. We should grow that Google spreadsheet as more info comes in. @webprofusion So in the case of angular-jwt the installation of types as described here was not enough? Ionic2 RC1 builds giving white screen of death

Yeah turned out it would build OK but when you tried to access anything that decoded the jwt token it would error in the console.

1 Like

Care to share your ionic.config.json as well and where do I need to put the custom roll up file?

For a general guide to build config check out http://ionicframework.com/docs/v2/resources/app-scripts/

If you look at the section titled Providing Custom Build Configuration, you’ll see you can add a section to your package.json to tell it where to look for config files, so if you put your custom config file in /config of your app root it might look like:

“config”: {
“ionic_rollup”: “./config/rollup.config.js”
}

I copy the contents of node_modules/@ionic/app-scripts/config/rollup.config.js then add whichever modifications are required, usually the commonjs({…}) bit.

1 Like

Thanks for this. Thought about what happens when Ionic Team updates their rollup config? (Maybe we should configure package.json to read in both files, default and custom?.. but 2 exports dunno if that works well)

I think angular2-jwt needs to modify it’s reference to Base64 to be specific to the scope and js-base64 needs to explicitly export Base64!

Could you raise this issue with angular-jwt team?