aurelia / bundler

A library for bundling JavaScript, HTML and CSS for use with SystemJS.
MIT License
37 stars 25 forks source link

"aurelia_framework_1.singleton is not a function" after bundeling #93

Closed EisenbergEffect closed 8 years ago

EisenbergEffect commented 8 years ago

@MaartenThomassen commented on Fri Mar 04 2016

Hello,

In my Aurelia app, I am using a Typescript development environment which transpiles to ES5 and in my code i use the @autoinject attribute and Aurelia's dependency injection framework.

When I build my app and run it locally, everything works fine. When I bundle my app (i made 2 bundles, one with all Aurelia deps i use and 1 with all my own code), i get the following error:

system.js:41 Uncaught (in promise) Error: aurelia_framework_1.singleton is not a function

This error in turn causes:

Error: key/value cannot be null or undefined. Are you trying to inject/register something that doesn't exist with DI?

I did some debugging, and when running without bundles, the aurelia_framework_1 module contains both the .singleton() function definition and the .FrameworkConfiguration.singleton() . When I run with bundles, the aurelia_framework_1 module does NOT contain the .singleton() function definition but DOES contain the .FrameworkConfiguration.singleton().

I can't figure out what the difference between the unbundled and bundled versions are. I also can't figure out how, at runtime, the framework "copies" the .singleton() function directly in the aurelia_framework_1 module, since when i dove into the Aurelia code and Typescript definitions, the .singleton() function is only present in the FrameworkConfiguration whitin the aurelia-framework module.

The error happens when i try to do a custom registration into the DI container:

aurelia.container.registerSingleton(UserManager_1.UserManager);

Where UserManager is a class in my own UserManager module.

NOTE: I use the latest version of Aurelia Beta "aurelia-framework": "npm:aurelia-framework@^1.0.0-beta.1.1.4",

NOTE 2:

The error happens exactly at this line: UserManager = __decorate([aurelia_framework_1.singleton(), aurelia_framework_1.autoinject, __metadata('design:paramtypes', [IAuthentication_1.IAuthentication, ToCRUDConverter_1.ToCRUDValueConverter])], UserManager);

At the bottom of 'System.register("src/libraries/UserManager.js",...' int he bundled file. there, both the aurelia_framework_1.singleton() and aurelia_framework_1.autoinject are undefined, causing the UserManager to not get defined, breaking the DI function call mentioned above.

EisenbergEffect commented 8 years ago

@ahmedshuhel Please take a look at this.

ghost commented 8 years ago

Any updates on this? It's a pretty crucial issue for my team right now.

EisenbergEffect commented 8 years ago

This is a bug in the Babel compiler or SystemJS where it isn't treating re-exported values correctly. To get around it, import from the original module that the export comes from. For example singleton is re-exported from 'aurelia-frameworkfor convenience, but it is originally exported fromaurelia-dependency-injection` so import it from there instead. If that doesn't work, then there may be an issue with your bundle configuration. Let us know.

ghost commented 8 years ago

@EisenbergEffect Thank you for the workaround. I'm going to implement this today and report back to you.

For the record, i am not using Babel (im directly compiling typescript with the typescript version included with gulp-typescript to ES5), so its possibly a bug in SystemJS in combination with the Aurela Bundler.

ghost commented 8 years ago

@EisenbergEffect

I replaced the (auto)inject and singleton imports as you suggested, also replaced my binding imports to import directly from aurelia-templating.

This "seems" to fix the problem, however, I am now getting a different issue, which is also probably a SystemJS issue but since its still in combination with the Aurelia loader, I'll post it here, perhaps you can suggest a better place for me to post it:

When using the text plugin, the aurelia bundler compiles the bundled files with references to text files inside the bundle like this:

(function() {
var define = System.amdDefine;
define("github:necolas/normalize.css@3.0.3/normalize.css!github:systemjs/plugin-text@0.0.7.js", [], function() {
  return <TEXT HERE>;
});

However, as soon as SystemJS configures itself (at line 1804 of system.js), it decanonicalizes the bundle dependencies (at line 1902: var normalizedBundleDep = loader.decanonicalize(cfg.bundles[p][i]);)

However, this cuases SystemJS to register the above dependency in its loader bundle as:

http://localhost:9000/jspm_packages/github/necolas/normalize.css@3.0.3/normalize.css!http://localhost:9000/jspm_packages/github/systemjs/plugin-text@0.0.7.js

Adding the entire "http://localhost....." bit to the text plugin bit which is not present in the actual bundle .js file, causing the lookup of the file to fail.

Any idea how to fix this?

EisenbergEffect commented 8 years ago

@ahmedshuhel Can you take a look at this please?

EisenbergEffect commented 8 years ago

Actually @MaartenThomassen I'm going to close this issue. Can you open a new issue on the bundler repo?