Open patrickhousley opened 7 years ago
Hey @patrickhousley, I'd need some more details to help. Anything you can provide is helpful--including but not limited to: how are you using webpack-rxjs-externals? What is the stack trace including filename/lines?
In addition, if possible, can you make a simple jsbin, codepen, etc to demo? It's not necessarily required, but without it might be really hard for me to understand how you're running into this.
Please use repository/branch: https://github.com/patrickhousley/angular2-aot-webpack/tree/test/webpack-rxjs-externals/issues/3
@patrickhousley how do I reproduce with that repo?
Clone the repository. Checkout the test/webpack-rxjs-externals/issues/3
branch. Run npm start
. Open locahost:9000
in the browser and see the error in the console.
I forgot to update that repo with a script tag to rxjs. Let me update the branch.
Added the script tag to the index.html file. The repository should be good for testing now.
hmmm this seems like an application build using webpack--which isn't what webpack-rxjs-externals is intended for. Webpack externals is for dynamically linking external libraries which are not bundled with your webpack code--usually that means including files from a CDN or for libraries which want to share peer dependencies in their UMD builds.
If you provide externals it's my understanding that webpack will not bundle anything that matches those externals directly with your code. Instead, you're basically saying "dynamically link this external library at runtime, this is how to find them". If you remove the addition of the webpack externals, everything works as expected for me.
Since you mentioned the script tag to rxjs, this suggests you are indeed trying to dynamically link RxJS via CDN. Is that correct? That's why you're using webpack-rxjs-externals?
If that is indeed the case, I don't believe I can help much further without diving super deep into your specific build chain. something is telling webpack to try and statically link the externals. (total guess) maybe one of your typescript loaders. I really don't know, though.
The output from webpack is simply undefined. This is rxjs/Subject
, for instance
It's definitely possible a problem with webpack-rxjs-externals, but I would bet against it--I'm clearly biased though hehe :clown_face: I really didn't intend for it to be used by application builds, though, so I don't have cycles to dig super deep in a complex build setup. Sorry man! 😢
We use this primarily for redux-observable. Here's an example of the expected output of the RxJS externals depended on for redux-observable builds:
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("rxjs/Observable"), require("rxjs/Subject"), require("rxjs/operator/filter"), require("rxjs/operator/map"), require("rxjs/operator/switchMap"), require("rxjs/observable/from"), require("rxjs/observable/merge"), require("rxjs/observable/of"));
else if(typeof define === 'function' && define.amd)
define(["rxjs/Observable", "rxjs/Subject", "rxjs/operator/filter", "rxjs/operator/map", "rxjs/operator/switchMap", "rxjs/observable/from", "rxjs/observable/merge", "rxjs/observable/of"], factory);
else if(typeof exports === 'object')
exports["ReduxObservable"] = factory(require("rxjs/Observable"), require("rxjs/Subject"), require("rxjs/operator/filter"), require("rxjs/operator/map"), require("rxjs/operator/switchMap"), require("rxjs/observable/from"), require("rxjs/observable/merge"), require("rxjs/observable/of"));
else
root["ReduxObservable"] = factory(root["Rx"], root["Rx"], root["Rx"]["Observable"]["prototype"], root["Rx"]["Observable"]["prototype"], root["Rx"]["Observable"]["prototype"], root["Rx"]["Observable"], root["Rx"]["Observable"], root["Rx"]["Observable"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_4__, __WEBPACK_EXTERNAL_MODULE_5__, __WEBPACK_EXTERNAL_MODULE_6__, __WEBPACK_EXTERNAL_MODULE_7__, __WEBPACK_EXTERNAL_MODULE_8__, __WEBPACK_EXTERNAL_MODULE_9__, __WEBPACK_EXTERNAL_MODULE_10__, __WEBPACK_EXTERNAL_MODULE_11__) {
/// etc
Notice how it correctly handles all the situations, commonjs
commonjs2
, amd
or global
I just did some digging on this and it seems like while externals is primarily for library developers one use case it should enable is to allow libs to be loaded via a cdn. Modifying this lib to be
if (request.startsWith('rxjs/')) {
let root = rootForRequest(request);
if (Array.isArray(root)) {
root = root.join('.');
}
return callback(null, root);
}
Fixes that project. There's a couple API options I can see off the top of my head to enable this use case:
Either bake this feature into the library as an option:
rxjsExternalsFactory({scriptTagExternals: true}); // there's probably a better name
or a more flexible solution, but probably a bit OTT:
rxjsExternalsFactory({
modifyExternals(external) {
/* external is the value of
{
root: rootForRequest(request),
commonjs: request,
commonjs2: request,
amd: request
}
*/
let root = external.root;
if (Array.isArray(root)) {
root = root.join('.');
}
return root;
}
})
@jayphelps what do you think?
From the webpack docs:
The bundle with external dependencies can be used in various module contexts, such as CommonJS, AMD, global and ES2015 modules. The external library may be available in any of these forms:
global - An external library can be available as a global variable. The consumer can achieve this by including the external library in a script tag. This is the default setting for externals.
commonjs - The consumer application may be using a CommonJS module system and hence the external library should be available as a CommonJS module.
commonjs2 - Similar to the above line but where the export is module.exports.default.
amd - Similar to the above line but using AMD module system.
Maybe this project could use the same distinction built into it.
@mattlewis92 To your point, externals is primarily for library developers. However, it also works extremely nicely in a Typescript environment where the deployment environment already contains some of the vendor modules on the window (like rxjs).
One thing you might also add to the readme is a warning that this also does not work when importing from rxjs
. Example, import { Observable } from 'rxjs';
Ran into similar issues too. fixed by setting libraryTarget
to umd
.
PR here for more details: https://github.com/Travix-International/frint/pull/332
Getting error
Cannot read property 'Subject' of undefined
when using this webpack module.RxJS: 5.3.0 Webpack 2.4.1 Angular: 4.0.2