You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Node.js代码未等待动态模块导入完成?

问题根源与解决方案:异步IIFE未阻塞后续代码执行

问题本质

你的async立即执行函数(IIFE)是异步非阻塞的:JS引擎执行到这个IIFE时,会启动内部的异步模块导入操作,但不会暂停整个代码的执行流程,而是直接继续往下运行创建Express实例、打印SECOND、启动服务器的逻辑。等异步导入完成后,才会回头执行IIFE里await之后的代码,这就是输出顺序混乱的核心原因。

另外还有两个隐藏问题:

  • IIFE内部的webpack和webpackDevMiddleware是局部变量,后续代码根本访问不到,就算顺序正确也没法使用这些模块。
  • 代码里typeof Webpack用了大写变量名,但实际定义的是小写webpack,会导致打印undefined(你提供的输出结果应该是笔误)。

修复方案

方案1:将所有逻辑封装到async启动函数

把服务器初始化的全部逻辑放进一个async函数里,利用await阻塞后续代码执行,确保模块导入完成后再执行后续逻辑:

import express from 'express';

async function startServer() {
  // 提前声明变量,让后续代码能访问到
  let webpack, webpackDevMiddleware;
  const PORT = 8080;

  if (process.env.NODE_ENV === 'development') {
    try {
      console.log(`About to import`);
      // 动态导入并赋值给外部变量
      const { default: wp } = await import('webpack');
      const { default: wpDevMiddleware } = await import('webpack-dev-middleware');
      webpack = wp;
      webpackDevMiddleware = wpDevMiddleware;
      console.log(`FIRST: typeof webpack ${typeof webpack} | typeof webpackdevmiddleware ${typeof webpackDevMiddleware}`);
    } catch (error) {
      console.error('开发环境依赖导入失败:', error);
      process.exit(1); // 导入失败直接退出服务
    }
  }

  const server = express();

  if (process.env.NODE_ENV === 'development') {
    console.log(`SECOND: I must run after FIRST`);
    // 这里可以正常使用webpack和webpackDevMiddleware
    // 示例:配置webpack-dev-middleware
    // const compiler = webpack(yourWebpackConfig);
    // server.use(webpackDevMiddleware(compiler));
  }

  server.listen(PORT, () => {
    console.log(`Server is listening on port ${PORT}`);
  });
}

// 启动服务器并处理全局错误
startServer().catch(err => console.error('服务器启动失败:', err));

方案2:使用顶层await(Node.js 14.8+支持)

如果你的Node.js版本支持顶层await(v14.8及以上),可以直接在模块顶层使用await,这样会阻塞模块加载,直到异步操作完成:

import express from 'express';

let webpack, webpackDevMiddleware;
const PORT = 8080;

if (process.env.NODE_ENV === 'development') {
  try {
    console.log(`About to import`);
    const { default: wp } = await import('webpack');
    const { default: wpDevMiddleware } = await import('webpack-dev-middleware');
    webpack = wp;
    webpackDevMiddleware = wpDevMiddleware;
    console.log(`FIRST: typeof webpack ${typeof webpack} | typeof webpackdevmiddleware ${typeof webpackDevMiddleware}`);
  } catch (error) {
    console.error('开发环境依赖导入失败:', error);
    process.exit(1);
  }
}

const server = express();

if (process.env.NODE_ENV === 'development') {
  console.log(`SECOND: I must run after FIRST`);
}

server.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

验证效果

修复后运行代码,输出顺序会符合预期:

About to import
FIRST: typeof webpack function | typeof webpackdevmiddleware function
SECOND: I must run after FIRST
Server is listening on port 8080

内容的提问来源于stack exchange,提问作者volume one

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 20:42:17