iron-meteor / iron-router

A client and server side router designed specifically for Meteor.
MIT License
1.98k stars 413 forks source link

Dynamic Imports with Iron Router #1602

Open heberallred opened 6 years ago

heberallred commented 6 years ago

We have a reasonably large application, so we are converting much of our code to use Dynamic Imports in Meteor. We're getting a warning from Iron Router on our routes: Route dispatch never rendered. Did you forget to call this.next() in an onBeforeAction?

Here's the code for the route:

Router.route('support', {
  path: '/support',
  controller: 'BaseController',
  action: function () {
    import('./pricing.html').then(() => {
      this.render();
    });
  }
});

Is this the correct way to dynamically import a template and render it? The page seems to load fine (so far), but I just want to make sure it doesn't trigger other problems.

I also tried using "async" and "await" which gives the same warning.

ghost commented 5 years ago

+1

ddaydd commented 5 years ago

why async, promise?

Router.route('support', {
  path: '/support',
  controller: 'BaseController',
  action: function () {
    import './pricing.html';
    this.render();
  }
});
heberallred commented 5 years ago

@ddaydd If we do it that way, does it import dynamically, or would pricing.html still be in the client bundle?

The purpose of dynamically importing using promises would be to ensure the bundle is smaller for faster page loading. We have a lot of pages on the site, and don't want pages loading until they are needed.

ddaydd commented 5 years ago

all the files in the client folder will be in the client bundle, you must put your files in the import folder and define the route relative to your route.js file.

  action: function () {
    import '../import/client/ui/pricing.js';
    this.render();
  }

and in your pricing.js file

import './pricing.html'

heberallred commented 5 years ago

@ddaydd The files in my example are all in the "imports" folder. If I understand correctly, even files in the import folder will be included in the client bundle unless they are imported dynamically using promises (like in my first example).

rtcwp07 commented 5 years ago

@heberallred I am very interested to know if you were able to make this work, and how. Did you stick with the promise-based solution?

heberallred commented 5 years ago

@rtcwp07 Yes, we are still using promises. To get rid of the warning, we just modified the Iron Router code. It's mostly just a warning for us developers, and just clutters the console for any customers if we need to do any debugging. Looks like the core Iron Router code just needs re-worked a bit to work better with this new method of using dynamic imports.

micktaiwan commented 5 years ago

I have the same Iron Router warning using dynamic imports

@rtcwp07 Looks like the core Iron Router code just needs re-worked a bit to work better with this new method of using dynamic imports.

I think that too.

dpatte commented 3 years ago

i am wondering whether iron router is inside some function when the "Did you forget to call this.next() in an onBeforeAction?" message comes up and whether we should be doing something on the line after the import statement to tell iron router that it can ignore the routing request for now, and it will be handled later. I have nearly Identical code to @haberallred and it seems to work, but i'm suspicious about what iron router is actually doing IMMEDIATELY after the import statement, and what the consequences might be if the server is slow in responding. Do multiple router calls build a stack of requests that iron router is expecting to complete?

dpatte commented 3 years ago

my dynamic import is working fine using irn.router & promises, but I am noticing screen freeze-ups occasionally with the current chrome browser. I'm concerned they may be related to this issue.