Breeze / breeze.js

Breeze for JavaScript clients
MIT License
540 stars 88 forks source link

webpack and angular-cli support #185

Open kferstl opened 7 years ago

kferstl commented 7 years ago

Breeze wraps its definition in a function and sees "this" as its global variables. For my understanding, this does not work in combination with angular-cli. angular-cli uses uses webpack and it looks like "this" is an empty object instead of the global namespace when using webpack. The result is, that breeze is unable to find any depending library like OData (datajs).

My (very) dirty fix: breeze.debug.js ` (function (global, definition) { var def = function(){ return definition(global); };

// CommonJS
if (typeof exports === "object" && typeof module === "object") {
    **global = window;**
    module.exports = def();
    // RequireJS
} else if (typeof define === "function" && define["amd"]) {
    define(def);
    // <script>
} else {
    breeze = def();
}

})(this, function (global) { .... `

I found some other workarrounds in combination with webpack, e.g. this: http://stackoverflow.com/questions/41119357/how-to-configure-webpack-to-support-global-window-for-breeze-clientdatajs

The problem with angular-cli is, that it does not and will not expose the webpack configuration, so this is no solution.

marcelgood commented 7 years ago

Breeze is written with a universal module header, that allows it to be loaded globally as well as via a module loader such as SystemJS or a module bundler such as webpack. You just need to properly import breeze-client and datajs in your Angular app and it should bundle fine with webpack. We use breeze with webpack in several projects ourselves, without having to mess with the webpack configuration.

See our Angular bridge for more info: https://github.com/Breeze/breeze.bridge.angular2

and this post should help with how to import datajs. http://stackoverflow.com/questions/39352922/breezejs-angular-2-and-odata/39356264#39356264

dharapvj commented 7 years ago

Hi Marcel,

Even I have spent many hours over last 4-5 months on same issue. We cannot use the solution suggested by you because of following:

I would be looking at the change @kferstl has mentioned above too. But I would request that if that change is feasible - kindly consider due to above reasons.

dharapvj commented 7 years ago

Just beautifying original fix offered by @kferstl .

(function (global, definition) {
var def = function(){ return definition(global); };

// CommonJS
if (typeof exports === "object" && typeof module === "object") {
    // CHANGE STARTED BY @kferstl
    global = window;
    // CHANGE COMPLETE BY @kferstl
    module.exports = def();
    // RequireJS
} else if (typeof define === "function" && define["amd"]) {
    define(def);
    // <script>
} else {
    breeze = def();
}
})(this, function (global) {
marcelgood commented 7 years ago

I would probably need a small repro sample to see the issue that you are describing. I have a suspicion that the root cause is somewhere else based on your comments. Here's why. breeze.debug.js is already a bundle of breeze and all the adapters. That's why it has the require calls in it. You should use breeze.base.debug.js and then manually import/configure the breeze adapters you need.

I had to do a similar thing for rollup. You can see it in our temphire example.

https://github.com/Breeze/temphire.angular2/tree/master/TempHire

In rollup.js, I use the alias plug-in (webpack has a similar plug-in) and set up an alias for breeze-client like so:

      alias({
          'breeze-client': path.resolve(__dirname, 'node_modules', 'breeze-client/breeze.base.debug.js')
      }),

And then in my app I manually import all the required adapters.

import 'breeze-client/breeze.dataService.webApi';
import 'breeze-client/breeze.modelLibrary.backingStore';
import 'breeze-client/breeze.uriBuilder.json';
import 'breeze-client/breeze.uriBuilder.odata';

and configure them manually

config.initializeAdapterInstances({ dataService: 'webApi', uriBuilder: 'odata' });

breeze.bridge.angular2 takes care of configuring the ajax adapter. datajs may throw a monkey wrench into the mix that I'm not aware of. We do zero projects with OData back-ends ourselves, so if you can send me an example that shows the issue, preferably after you've tried the above, then I can take a look at it. The angular-cli is another story with its insistence to not giving access to the webpack configuration. That's one reason we've so far not used the cli ourselves. It takes away too much control and sooner or later you get into a situation where you need to tweak webpack.

We are working on breeze-vnext and a beta should be available soon. It's rewritten entirely in TypeScript and uses modern module management. I'm reluctant to changing the module header of current breeze. This is a standard universal header that is used in other libraries as well and so far we haven't seen any issues with it in several angular 2 projects, but again, none have an OData back-end, so there could be an issue that we haven't experienced ourselves yet.

dharapvj commented 7 years ago

Tried all these options... But get same errors. May be what you say about datajs throwing in wrench might be true.

I will try to provide an isolated small repo for debugging.

coni2k commented 7 years ago

@marcelgood, I also had the same issue when using Angular CLI with BreezeJS & datajs.

in __requireLibCore function, it's checking the availability of the necessary libraries by using global.window but somehow in Angular CLI project, global is just an empty object at that point and it throws Unable to initialize OData. Needed to support remote OData services error.

I just created a demo project that solves the issue by tweaking breeze.base.debug.js itself, which is of course not the proper way of fixing it: https://github.com/forCrowd/Labs-AngularCLI-BreezeJS

Also I had to modify package.json to refer to breeze.base.debug.js instead of breeze.debug.js.

"Readme" also contains how to see the error but let me know if you encounter any issue.


Update: Created a separate issue and updated the demo app Issue: https://github.com/Breeze/breeze.js/issues/221 Demo app: https://github.com/forCrowd/Labs-AngularCLI-BreezeJS

MikaelLambert commented 5 years ago

@coni2k thanks! This solution worked for me. It's not the best to have to live patch a library like this, but it's better to do this than to modify breeze-client directly.

@marcelgood I believe this rollup PR if completed would fix this problem and you should be able to update to the latest rollup and solve this problem properly.

https://github.com/rollup/rollup/pull/2274

Edit: I had some issues with Q even with this change and had to set it later. If someone runs into the same issue, try adding the following to your initialization:

import * as Q from 'Q';
import { config } from 'breeze-client';
config.setQ(<any>Q);