69

I'm trying to implement basic functionality of a dynamic import inside a Node v10 environment.

main.js

async function main() {
  try {
    const moduleA = await import('./moduleA');
    console.log('Inside main function...');
    moduleA();
    console.log(moduleA);
  }
  catch(err) {
    console.log(err);
  }
}

main();

moduleA.js

console.log('Inside global scope module A...');

function moduleA() {
  console.log('Running module A function...');
}

export default moduleA;

This is the result I'm getting when I run npx babel-node main.js

PS C:\myProject\test-module-imports> npx babel-node src/main.js
Inside global scope module A...
Inside main function...
TypeError: moduleA is not a function
    at main (C:\myProject\test-module-imports\src/main.js:9:5)
    at process._tickCallback (internal/process/next_tick.js:68:7)
    at Function.Module.runMain (internal/modules/cjs/loader.js:834:11)
    at Object.<anonymous> (C:\myProject\test-module-imports\node_modules\@babel\node\lib\_babel-node.js:174:21)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)

.babelrc

{
  "presets": [
    [
      "@babel/preset-env", {
        "targets": {
          "node": "10"
        }
      }
    ]
  ]
}

I also tried this (the following code). And the result is the same:

main.js

let moduleA = null;
import('./moduleA').then((importedModule) => {
  moduleA = importedModule;
  main();
});

async function main() {
  try {
    // const moduleA = await import('./moduleA');
    console.log('Inside main function...');
    moduleA();
    console.log(moduleA);
  }
  catch(err) {
    console.log(err);
  }
}

// main();

QUESTION

What am I doing wrong?


This is working fine (regular import): Executing also with npx babel-node src/main.js

import moduleA from './moduleA';

async function main() {
  try {
    console.log('Inside main function...');
    moduleA();
    console.log(moduleA);
  }
  catch(err) {
    console.log(err);
  }
}

main();

package.json (extra info)

{
  "name": "test-module-imports",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/cli": "^7.7.0",
    "@babel/core": "^7.7.2",
    "@babel/node": "^7.7.0",
    "@babel/preset-env": "^7.7.1"
  }
}
cbdeveloper
  • 27,898
  • 37
  • 155
  • 336

1 Answers1

145

The dynamic import() loads the module and return a module object that contains all its exports. In order to access the default export use the default property of the module object:

const moduleA = await import('./moduleA');
moduleA.default();

// OR

const { default: moduleA } = await import('./moduleA');
moduleA();
Fraction
  • 11,668
  • 5
  • 28
  • 48
  • 1
    helped w my question https://stackoverflow.com/questions/69915979/react-lazy-load-for-a-function-not-a-component/69916178?noredirect=1#comment123591090_69916178 – sao Nov 10 '21 at 16:18
  • 1
    In the second example. What is the curly braces and the default syntax doing? Is this extracting the default export from the module? – user1002794 Mar 08 '23 at 09:50
  • 1
    @user1002794 Yes, we destructure and rename the `default` key because it's a reserved word – Fraction Mar 09 '23 at 07:17
  • 3
    This solution gives me this error "SyntaxError: await is only valid in async functions and the top level bodies of modules" – Some Guy May 01 '23 at 00:16
  • @SomeGuy see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Bad_await – Fraction May 03 '23 at 09:34
  • @cbdeveloper, did this work for You, as I read some where the dynamic import is supported since Node Version >=13.2 – Vipresh Jun 13 '23 at 06:38