Help me understand dynamic imports

Dynamic imports are great, but I’m not 100% clear on how they work exactly.

For example, at least when testing locally it seems like dynamically imported files are still getting bundled and executed. For example if I create a new test.js file containing:

console.log('test')

And then import it normally from somewhere else (import 'test.js) I would expect test to get logged out.

But when it comes to dynamic imports, test is still getting logged out even if I use import('test.js') instead. I would’ve thought this would return a Promise, and that the test.js code would not get executed until I call then() on that Promise?

What’s the expected behavior here? How can I ensure test won’t get logged out until a later time?

Maybe some more context will help. I’m trying to make it very easy to implement dynamic imports in Vulcan routes.

This is how a normal Vulcan route is defined:

import Admin from './Admin.jsx';

addRoute({
  name: 'admin',
  path: '/admin',
  component: Admin
});

And this is how I’m trying to make dynamic imports work:

const Admin = import('./Admin.jsx');

addRoute({
  name: 'admin',
  path: '/admin',
  component: Admin
});

I did think about only passing the path (./Admin.jsx, or its absolute equivalent) to addRoute and then only calling import() later on when I actually need it, but I then end up running into Cannot find module issues, probably due to a wrong path…

My guess is the import is being executed when you define that constant.

The way I am doing it in Meteor Candy is:

run = function () { 
   import(...).then(...)
}

That way, I can keep the import from running until its needed

3 Likes

Thanks! It seems simple now but it took me a while to work out the correct syntax:

addRoute({
  name: 'admin',
  path: '/admin',
  component: () => getDynamicComponent(import('../components/AdminHome.jsx'))
});

With:

import React from 'react';
import loadable from 'react-loadable';

export const dynamicLoader = componentImport => loadable({
  loader: () => componentImport,
  loading: MyLoadingComponent,
});

export const getDynamicComponent = componentImport => React.createElement(dynamicLoader(componentImport));
1 Like