Search code examples
reactjsecmascript-6lazy-loadingreact-suspense

Passing String to Import Function React


I'm trying to create a helper method to lazily import modules with a delay in react.

This first version, when I have the path in the import fixed, it works:

import { lazy } from 'react';

export function lazyLoaderWithDealy() {
  return lazy(async () => {
    const [moduleExports] = await Promise.all([
      import('components/SchemaEditor'),
      new Promise(resolve => setTimeout(resolve, 300))
    ]);
    return moduleExports;
  });
}

But in this second example, when the path to the module comes from a variable, it doesn't work, any idea why?

import { lazy } from 'react';

export function lazyLoaderWithDealy(path) {
  return lazy(async () => {
    const [moduleExports] = await Promise.all([
      import(path),
      new Promise(resolve => setTimeout(resolve, 300))
    ]);
    return moduleExports;
  });
}

Solution

  • Instead of passing the path you should passe the entire import.

    import { lazy } from 'react';
    
    export function lazyLoaderWithDealy(importPromise) {
      return lazy(async () => {
        const [moduleExports] = await Promise.all([
          importPromise,
          new Promise(resolve => setTimeout(resolve, 300))
        ]);
        return moduleExports;
      });
    }
    
    // ...
    
    lazyLoaderWithDealy(import('components/SchemaEditor'))
    

    You should take a look to this answer. You can't do a dynamic import like import(path) because webpack won't be able to know what should be bundle up, if you pass something like that, webpack you need to bundle up your hole application (which you don't want and can't). If you pass something like import('components/' + path), webpack will bundle up everything in components, which works, but is also bad.

    If you can pass the hole string to the import, it will be better for the lazyload, if you can't, you need at least to pass some folder + path.