在Node.js上使用动态import()函数

71

我正在尝试在 Node v10 环境中实现 动态导入 的基本功能。

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;

当我运行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"
        }
      }
    ]
  ]
}

我也尝试了以下代码,结果一样:

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();

问题

我做错了什么?


这是正常工作的(普通导入): 还可以使用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(额外信息)

{
  "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"
  }
}
1个回答

149
动态导入()加载模块并返回一个包含所有导出内容的模块对象。要访问默认导出,请使用模块对象的default属性:
async function main() {
  try {
    const moduleA = await import('./moduleA');
    moduleA.default();

    // OR

    const { default: moduleA } = await import('./moduleA');
    moduleA();
  }
  catch(err) {
    console.log(err);
  }
}


1
帮助了我的问题 https://dev59.com/RsLra4cB1Zd3GeqPPbTr#69916178?noredirect=1#comment123591090_69916178 - sao
1
在第二个例子中,花括号和默认语法是做什么的?这是从模块中提取默认导出吗? - user1002794
1
@user1002794 是的,我们对 default 关键字进行解构和重命名,因为它是一个保留字。 - Fraction
3
这个解决方案给我返回了这个错误信息:“SyntaxError: await 只能在异步函数和模块的顶层体中使用”。 - Some Guy
@SomeGuy 请查看https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Errors/Bad_await。 - Fraction
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接