how to use dynamic names for webpack 2 import() statements?

I'm trying to create a library that exposes a function that dynamically imports other libraries based on parameters it gets passed. Something like:

export function foo(deps){
  deps.forEach(dep => import(dep).then(doSomething))
}
//usage:
foo(['bar', 'baz']);

the library should not know about the deps in advance, but the app using it definitely will and will import foo and any deps.

When i try to create something like this, I get an error saying "module bar not found". I know that webpack uses static analysis to bundle dynamic imports, but I know it can have variables in imports.

If there is a way to list the dependencies ahead of time, that would be fine. I tried something like this (from the app where I use foo)

function doNotRun(){
   import('bar');
   import('baz');
}
foo(['bar', 'baz'])

in the hopes that webpack would figure out at runtime that it had already bundled this module, but it doesn't seem to match up the module ids. I see bar and baz bundled into chunks, but the actual import uses a different module id.

I also tried making foo aware of all possible deps (by name, but not importing them), and it failed because it needed to know about them at build time. like this:

function getImportPromise(subapp){
  switch(subapp){
    case 'baz':
      return import('baz');
    case 'bar':
      return import('bar');
    default:
      return Promise.reject(dep + ' is not known');
  }
}

export function foo(deps){
  deps.forEach(dep => getImportPromise(dep).then(doSomething))
}

Is it possible to do what I'm asking?

edit: I just realized that something like my last idea could work, it just feels odd. And more generally, I thought import() could take variables.

export function foo(deps, getImportPromise){
  deps.forEach(dep => getImportPromise(dep).then(doSomething))
}

//usage
function getImportPromise(subapp){
  switch(subapp){
    case 'baz':
      return import('baz');
    case 'bar':
      return import('bar');
    default:
      return Promise.reject(dep + ' is not known');
  }
}
foo(['bar', 'baz'], getImportPromise);

if this is the recommended solution though, it's not so bad. I was just hoping there was a way to have foo do the import itself.

Answers:

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.