Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First tx... + an issue... lazy loading...EXCEPTION: TypeError: AMD module #1504

Closed
born2net opened this issue Feb 8, 2016 · 19 comments
Closed

Comments

@born2net
Copy link

born2net commented Feb 8, 2016

First let me say thank you... I am LOVING jspm. I moved to this from Webpack and will soon release my popular project on: http://ng2.javascriptninja.io/ to jspm, well as soon as I resolve this one issue...

I am trying to load a bundle dynamically.
I have my main bundle, and for the lazy loaded bundle I do:

jspm bundle-sfx src/comps/app1/App1.js out.js --skip-source-maps
and in the angular2 code I run

if (condition){
   return System.import('/dist/public/out.js').then(c => c[name]);
}

the problem is that I am getting an error of:

EXCEPTION: TypeError: AMD module http://localhost:8003/dist/public/out.js did not define

Is there something special I need to do to be able to load App1 dynamically (lazy load)?

(if I don't bundle lazy loading is working great by the way)...

my config.js is:

    ...
    packages: {
        "src": {
            "main": "App",
            "defaultExtension": "ts",
            "meta": {
                "*.js": {
                    "loader": "ts"
                },
                "*.ts": {
                    "loader": "ts"
                },
                "*.css": {
                    "loader": "css"
                }
            }
       ...

so as you can see I didn't put any special package entry for App1 (don't think I need to?!?!?!)

tx again for an AMAZING project,
I will make sure I push lots of new devs to jspm and plan on making a video tutorial on jspm workflow which kicks ass... I love working close to the metal which is what jspm allows + TS complication in the broswer, + versioning... WOW!!!! Webpack bye bye...!

regards

Sean.

@born2net born2net changed the title First tx... + an issue... First tx... + an issue... lazy loading...EXCEPTION: TypeError: AMD module Feb 8, 2016
@born2net
Copy link
Author

born2net commented Feb 8, 2016

if I run:
jspm bundle src/comps/app1/App1.js ./dist/public/out.js --skip-source-maps
I don't get the amd error, when loading out.js, but I can't seem to import the App1.js from inside the out.js

any help is appreciated

@born2net
Copy link
Author

anyone?

@guybedford
Copy link
Member

Can you share your contents of /dist/public/out.js here that wasn't working?

@born2net
Copy link
Author

Hi Guy,
let me update, once I ran

jspm bundle-sfx src/comps/app1/App1.js out.js --skip-source-maps --inject

I no longer got the AMD error, which is good!
but, when I try to lazy load App1 (which embedded inside out.js) I simply don't get any object back (just an empty object literal)

I am using Angular2 so my lazy load is:

 return System.import('/dist/public/out.js')
           .catch(function (e) {
               alert('prob loading out.js ' + e);
          }).then(function (e) {
               alert(e);
               alert(e[name]);
               alert(JSON.stringify(e));
               return System.import('App1').then(c => c[name]);
           });

but on the alert I just get {}

I think the issue is that maybe the 2nd statement of:

return System.import('App1').then(c => c[name]);

as it just returns an empty object...
I am sure there is a way to get it working, prob just my syntax,

by the way I moved my project to jspm and love it... it kicks ass compare to Webpack.

and if you want to see the code I use to load, it's here (commented out now :( )

loadComponent async:
https://github.com/born2net/ng2Boilerplate/blob/master/src/Lib.ts

which is being called from AsyncRoute:
https://github.com/born2net/ng2Boilerplate/blob/master/src/App.ts

tx again

Sean

@born2net
Copy link
Author

let me know if any ideas...
FYI posted this on ng2 cli project: angular/angular-cli#187

good stuff...

@guybedford
Copy link
Member

@born2net note that is the correct behaviour - bundle files are empty modules, which define other modules into the registry. You need to load the bundle itself and then load the module you wanted from the bundle.

@born2net
Copy link
Author

I understand, I wish it actaully loaded my module :)
if you ever find time and can get it to work with ng2 it would be amazing.
I have no doubt that ng2 is going to be THE framework that consolidates the JS world and I can see already that jspm will be the blunder of choice (I love jspm).

if we could just get ng2 to lazy load separate bundles we would be golden!!!

PS

I believe you would need to add a feature to support it as what I am seeing is that the ng2 Injector does not know how to instantiate the imported component from the lazy loaded bundle.
tx again

Sean.

@guybedford
Copy link
Member

@born2net did you try using the bundles config or inject option in jspm? That is designed exactly for this.

@born2net
Copy link
Author

I do use the

jspm bundle src/comps/app1/App1.js out.js --skip-source-maps --inject

which helped as I don't get the amd error anymore.

however I am still not able to get an instance of my module.

I am going to give the bundles config a try again...

@born2net
Copy link
Author

I must be getting close, the issue I am having is that after creating the bundle config I get an error of:

http://localhost:8003/dist/public/App1 404 (Not Found)

basically System.js is trying to load the module from the drive instead of from the bundle

I added bundle config as:

  bundles: {
    "main-bundle": [
      "app/App1.ts",
      "app/App1.js",
      "app/App1.ts",
      "App1.ts",
      "App1.js",
      "src/comps/app1/App1",
      "src/comps/app1/App1.ts",
      "/dist/comps/app1/App1",
      "/dist/comps/app1/App1",
      "/dist/comps/app1/App1.ts",
      "/dist/comps/app1/App1.js",
      "comps/app1/App1.js",
      "app1/App1.js",
      "App1",
      "comps/app1/App1.ts",
      "app1/App1.ts",
      "App1",
      "/dist/comps/app1/App1",
      "src/comps/app1/App1.js",
      "src/comps/app1/app1",
      "src/comps/app1/App1"
    ],

figured it will catch App1 with one of the entries but still no luck (but feel like getting close)

@born2net
Copy link
Author

and here is my import in ng2:

 return System.import('main-bundle')
            .catch(function (e) {
                alert('prob loading out.js ' + e);
            }).then(function (e) {
                alert(e);
                alert(e[name]);
                alert(JSON.stringify(e));
                return System.import('App1').then(c => c[name]);
            });

and use

jspm bundle src/comps/app1/App1.js ./dist/public/main-bundle.js --skip-source-maps --inject

any tips?

@guybedford
Copy link
Member

Make sure you are including your configuration file after including SystemJS in production and before loading the bundle.

@born2net
Copy link
Author

well my config.js is injected into my bundles... :/

@guybedford
Copy link
Member

@born2net does it come at the top, before any of the System.register statements? The point is that the config needs to be already called, before running System.register or System.import.

@born2net
Copy link
Author

maybe I am wrong, but all I do is include my index.html file via:

<script src="index.min.js"></script>

which is the bundle created by

jspm bundle-sfx src/App.js " + paths.dist + "/" + paths.targetJS + ' --skip-source-maps

and so since I am using -sfx the config and System.js will already be inside no?
I assume I am right since everything is working (thus a config exists internally) but just the lazy load doesn't work

and later in my build process I also run for the App1 bundle:

jspm bundle src/comps/app1/App1.js out.js --skip-source-maps --inject

Sean.

@guybedford
Copy link
Member

SFX bundles do not include SystemJS or the configuration. It's a completely different loaderless workflow to bundles.

@born2net
Copy link
Author

I know that SystemJS, the config and all my modules can be bundled into a single self executing file, which means replacing the setup within my HTML file with a script tag loading the compiled file.
jspm bundle-sfx main, so that's how I load it... (I know it works that way cause it works LOL... putting lazy loading aside) ... so I must have not explained my self well...

I run 2 separate commands:

jspm bundle-sfx src/App.js " + paths.dist + "/" + paths.targetJS + ' --skip-source-maps
jspm bundle src/comps/app1/App1.js out.js --skip-source-maps --inject

first is for the main bundle (95% of the app)
and second is for a small chunk which is just the App1

the problem is that when I try and lazy load App1, it tries to load it from disk, even though the config was bundled in the first step ...

@born2net
Copy link
Author

I tried to load the config.js inside the html file and still get same old:

GET http://localhost:8003/App1.js 404 (Not Found)

@guybedford
Copy link
Member

Well it has the extension now at least! The point is to get the name imported to line up with the name defined by the bundle. If you need to double-check what that should be you can also look at System.defined to see the names the bundle has registered, and how they differ from http://localhost:8003/App1.js.

if you've done a bundle inject like that then System.import('src/comps/app1/App1.js') is what you're after. Names need to be consistent between client and server. But you really shouldn't be loading a bundle on top of an SFX bundle as that is code duplication. Ideally you want a bundle on top of a bundle. I'd suggest following some existing workflows carefully.

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

No branches or pull requests

2 participants