Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

zones and bluebird in node? #793

Closed
mike-kaufman opened this issue May 22, 2017 · 15 comments · Fixed by #794
Closed

zones and bluebird in node? #793

mike-kaufman opened this issue May 22, 2017 · 15 comments · Fixed by #794

Comments

@mike-kaufman
Copy link

What's the recommendation for getting Zones to work w/ bluebird in node? There are some instructions here, but they're out of date, or I'm missing something. :)

Thanks much!

Mike

@JiaLiPassion
Copy link
Collaborator

@mike-kaufman, you can still use the instructions described in https://github.com/angular/zone.js/blob/master/NON-STANDARD-APIS.md#user-content-currently-supported-non-standard-common-apis.

I have did some basic test about the promise API which exposed by bluebird, can you try the steps in the document above?

@mike-kaufman
Copy link
Author

Thanks @JiaLiPassion - I'm not clear on where 'zone-node.js' and 'zone-bluebird.js' are supposed to come from? I looked around on npm but didn't see anything.

@JiaLiPassion
Copy link
Collaborator

@mike-kaufman, the zone-node.js and zone-bluebird.js are under node_modules\zone.js\dist, so you just need to npm install zone.js and you can load those js.

@mike-kaufman
Copy link
Author

mike-kaufman commented May 22, 2017

just need to npm install zone.js and you can load those js.

@JiaLiPassion - Thanks for the quick responses. A couple of issues here:

  1. I tried above (both require('zone-node.js') and require('node_modules/zone.js/dist/zone-node.js')) and I get errors that the module can't be found. It seems (from here that zone-node.js is the main module, so these instructions should just be require('zone.js');?

  2. I'm not sure how to correctly require('zone-bluebird.js'); per instructions. Again, reaching into the node_modules doesn't work, and also is not idomiatic AFAIU. i.e., I have not seen cases where a client of some module explicitly requires things outside of the module's root "export ". Perhaps I'm missing something? As a consumer, my expectation is that either:

    a) zone-bluebird.js is available via module's require (e.g., require('zone.js').zoneBluebird);
    b) or, there's a method available to do the bluebird patching (e.g., require('zone.js').patchBluebird();)

Please let me know if I'm missing something. I'm happy to submit a patch so that the "magic docs" becomes a "magic method", but would need guidance on where to best expose.

@JiaLiPassion
Copy link
Collaborator

@mike-kaufman , I will update document later.
the sample is

require('zone.js');
const Bluebird = require('bluebird');
require('./node_modules/zone.js/dist/zone-bluebird');
Zone[Zone['__symbol__']('bluebird')](Bluebird);
Zone.current.fork({
  name: 'bluebird'
}).run(() => {
  Bluebird.resolve(1).then(r => {
    console.log('result ', r, 'Zone', Zone.current.name);
  });
});

@mike-kaufman
Copy link
Author

So, to be precise, this:

require('zone.js');
const Bluebird = require('bluebird');
require('./node_modules/zone.js/dist/zone-bluebird');
Zone[Zone['__symbol__']('bluebird')](Bluebird);

Doesn't work for me. It fails to find 'zone-bluebird'. (Possibly because I have multiple modules in play in here? Irrespective, above is not idiomatic, and I don't think it will work given that npm can de-dupe packages such that zone.js is not necessarily in my modules' node_modules directory.

What I want is something like this:

const zones = require('zone.js')
zones.enableBluebird();

Where enableBluebird() is something like this:

    export function enableBluebird() {
        const Bluebird = require('bluebird');
        require('./zone-bluebird');
        Zone[Zone['__symbol__']('bluebird')](Bluebird);
    }

I'm happy to submit a PR, but I don't know your build pipeline and would need some guidance as to where this code should live.

@JiaLiPassion
Copy link
Collaborator

@mike-kaufman , you can check the node_modules\zone.js\dist folder to find out the zone-bluebird.js exist or not, if not, maybe you can update your zone.js version.

const zones = require('zone.js')
zones.enableBluebird();

I am not sure that Zone will provide an API like this, because currently Zone only expose APIs to
for Zone itself, if Zone expose API like enableBluebird, somehow it will have dependencies with bluebird library, currently zone have not such kind of dependencies.

so the current idea is , if you want to patch bluebird with zone.js, Zone provide some non-public-api help method if you load zone-bluebird.js yourself.

@mike-kaufman
Copy link
Author

Thanks @JiaLiPassion.

you can check the node_modules\zone.js\dist folder to find out the zone-bluebird.js exist or not, if not, maybe you can update your zone.js version.

The issue isn't that zone-bluebird doesn't exist. The issue is "where do I find it?". require(...) has a bunch of logic to look around for modules; I shouldn't have to replicate this logic on my own. npm has logic that de-dupes redundantly installed modules, so zone.js isn't necessarily in my module's node_modules directory.

if Zone expose API like enableBluebird, somehow it will have dependencies with bluebird

Not really... I don't think the dependencies change at all over what you're currently providing. Of course, if someone calls zones.enableBluebrid(), then it's safe to assume they have a dep on bluebird, and it's OK to assume that it is installed. If not, you fail. That's OK.

@JiaLiPassion
Copy link
Collaborator

@mike-kaufman , I understand your point.

The issue isn't that zone-bluebird doesn't exist. The issue is "where do I find it?".

Basically, in my understanding, the API for bluebird in zone has 3 concerns.

  1. user can control to load it or not, by default , it will not be loaded by default for performance concern.

  2. currently the API (Zone as any)[Zone.__symbol__('bluebird')] is not a good one, it is confusing and just like you said, it basically the same with enableBluebird, but I also don't think so there should be a enableBluebird() method. for other non standard API, if you load the js file such as webapis-media-query.js to patch MediaQuery, after you load, you will have patched the bluebird already. So the API is not needed.

currently the reason we have such API is bluebird is not a global object, maybe remove this API and change the usage to

require('zone.js');
const Bluebird = require('bluebird');
Zone[Zone['__symbol__']('bluebird')] = Bluebird;
require('./node_modules/zone.js/dist/zone-bluebird');

is better.

  1. we should let user to be able to control the load order and patch target.
    if we require ('bluebird') in zone-bluebird.js, just like you wrote below.
    export function enableBluebird() {
        const Bluebird = require('bluebird');
        require('./zone-bluebird');
        Zone[Zone['__symbol__']('bluebird')](Bluebird);
    }

how application code access the patched Bluebird?

And Bluebird support getNewLibraryCopy to get a stand-alone copy, so maybe we should let
user decide which and when to patch.

@mike-kaufman
Copy link
Author

how application code access the patched Bluebird?... And Bluebird support getNewLibraryCopy...

I think this addresses your concerns:

    export function patchBluebird(bluebird) {
        require('./zone-bluebird');
        Zone[Zone['__symbol__']('bluebird')](bluebird);
        return bluebird;
    }

Then caller can do this:

  const zones = require('zone.js');
  const bluebird = zones.patchBluebird(require('bluebird'));

The salient thing here is that reaching into the zone.js installed location is problematic & not idiomatic, so there really should be a work-around

@JiaLiPassion
Copy link
Collaborator

@mike-kaufman , yeah, pass Bluebird as parameter is ok, but it still require that zone load Bluebird patch function definition by default.

for example, when you use rxjs, you will only load the modules you used.

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';

And in zone.js case, you can do like this after nodejs support import

import `zone.js`; 
const Bluebird = require('bluebird');
import 'zone.js/dist/zone-bluebird';
Zone[Zone['__symbol__']('bluebird')] (Bluebird);

JiaLiPassion added a commit to JiaLiPassion/zone.js that referenced this issue May 25, 2017
@mike-kaufman
Copy link
Author

So, for this,

import 'zone.js/dist/zone-bluebird';

How does this work exactly? Don't I need to to know the full path to where zone.js is installed?

@JiaLiPassion
Copy link
Collaborator

@mike-kaufman , no, you don't need to know where zone.js installed, it is will load zone-bluebird from <fullpath of zone.js installed path>/dist/zone-bluebird

@mike-kaufman
Copy link
Author

it will load zone-bluebird from /dist/zone-bluebird

How does this work on down-level runtimes that don't support es6?

@JiaLiPassion
Copy link
Collaborator

@mike-kaufman , I think you may need to use babel polyfill to do that. Or you can use typescript.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants