Error: Cannot find module with dynamic import

Do you want to request a feature or report a bug?

bug

What is the current behavior?

When I try to load dynamic module with import('/path/to/my/module.js').then() it work, but when i try to import module with import(rootPath + '/' + myModuleName + '/index.js').then() it doesn’t work.

I got:

 Error: Cannot find module '/Users/hubert_i/Emodyz/launcher-ezgames.eu/modules/test/index.js'.
      at /Users/hubert_i/Emodyz/launcher-ezgames.eu/dist/electron/main.js:10475:9
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:188:7)

If the current behavior is a bug, please provide the steps to reproduce.

What is the expected behavior?

Dynamic import with variable

Please mention other relevant information such as the browser version, Node.js version, webpack version, and Operating System.

webpack => 3.10.0
npm => 5.6.0
yarn => 1.5.1
Node.js => v9.6.1
Operating System => macOs High Sierra

Author: Fantashit

9 thoughts on “Error: Cannot find module with dynamic import

  1. It’s incomprehensible 😢

    If i write this it work

    import( '/Users/hubert_i/Emodyz/launcher-ezgames.eu/modules/test/index.js')
      .then((m) => {
        console.log(m.name)
      })
      .catch(err => {
        console.error('Error during loading module: ' + err)
        callback()
      })

    but when i write this don’t work

    const test = '/Users/hubert_i/Emodyz/launcher-ezgames.eu/modules/test/index.js'
    import(test)
      .then((m) => {
        console.log(m.name)
      })
      .catch(err => {
        console.error('Error during loading module: ' + err)
        callback()
      })
  2. Webpack performs a static analyse at build time. It doesn’t try to infer variables which that import(test) could be anything, hence the failure. It is also the case for import(path+"a.js").

    If you need truly dynamic imports, you have to restrict it to a known path:

    import("./locales/" + locale + ".js")

    In the above example, webpack will create a chunk for each JS file in locale/.

  3. Would this also work for loading a remote module (over http(s)). I currently am trying to load modules located on a remove server (owned by me). When I import them locally it works fine:

    loadJs = ( url, name ) => {
      return new Promise( resolve => {
        import(`/test/${name}`)
        .then((module) => {
          resolve(module.default)
        })
      })
    }
    

    However when I try to import over http it fails (no request reaches the backend at all):

    import(`http://localhost:3001/api/uicomponents/one/${name}`)
    

    Error: Unhandled Rejection (Error): Cannot find module ‘http://localhost:3001/api/uicomponents/one/%5Bname%5D.js‘.

  4. This isn’t dynamic import if we can load dynamically files depending on our variables otherwise why would I even use this I could just import all the files at the top!!

    Seriously @ooflorent ?

  5. @meteorplus you can import files dynamically. You only need a static prefix.

    why would I even use this I could just import all the files at the top!!

    Because it will reduce the main bundle size.

  6. @ooflorent, what if I don’t want to reduce bundle size, but load another webpack packed bundle with all dependencies (even with duplicate dependencies) from absolute path?

  7. Just in case this helps somebody else who finds this issue, I got the behavior I wanted by adding a rule to my Webpack config to load the files I wanted with file-loader:

    {
      test: /\.config\.js$/,
      exclude: /node_modules/,
      loader: "file-loader",
      options: { name: "./conf/[name]-[hash:base36:4].[ext]", },
    }
    

    then getting a reference to the output path and dynamically importing it with native import():

    const path = require("../conf/" + ENVIRONMENT_NAME + ".config.js");
    import(/* webpackIgnore: true */CONFIG_PATH).then(mod => config.init(mod));
    

    This means that all the files matching ../conf/*.config.js get copied to ./conf/ in the build, and a map is established between their original path and the public path. Now, I can use the inline “ignore” comment to cause Webpack to actually emit a native import call, and the argument will be the public path to the file in question. Works great! (…on browsers that support import())

  8. If you develop a node project and use webpack to build your node project, when you meet the Error: Cannot find module with dynamic import , you can use NodeNative module to replace webpack build create __webpack_require__ function,

    webpack.config.js

    {
     target: 'node',
        node: {
          __dirname: false,
          __filename: false,
        }
    }

    eg :

    import module from 'module';
    const test = '/Users/hubert_i/Emodyz/launcher-ezgames.eu/modules/test/index.js'
    module.createRequire(__dirname)(test)
      .then((m) => {
        console.log(m.name)
      })
      .catch(err => {
        console.error('Error during loading module: ' + err)
        callback()
      })
  9. I solved this problem by simply removing the opening slash from the dynamic url. this might work for you.

    const test = 'Users/hubert_i/Emodyz/launcher-ezgames.eu/modules/test/index.js'
    import(`/${test}`)
    

Comments are closed.