首页 > 解决方案 > 通过 babel-register 动态导入导致多余的“默认模块”

问题描述

我有使用 webpack 捆绑的(多态)代码,包括动态导入(用于代码拆分),并且希望在 NodeJS 中运行相同的代码,目前使用babel-register来运行 ES6 代码。

当涉及到动态导入时,我遇到了一个问题:已解析/加载的模块似乎被包装在一个额外的(默认)模块中。

以下是一个最小示例,使用NodeJS v10.14.1, @babel/core@7.2.2, @babel/plugin-syntax-dynamic-import@7.2.0, @babel/preset-env@7.3.1, @babel/register@7.0.0:

index.js

require('@babel/register')({
  presets: ['@babel/preset-env'],
  plugins: [
    '@babel/plugin-syntax-dynamic-import'
  ]
})

require('./main').run()

dep.js

export const bar = 3;

main.js

import * as syncMod from './dep'

export function run() {
    console.log(syncMod)

    import('./dep').then(mod => console.log(mod))
}

通过node --experimental-modules index.js收益率运行它:

{ bar: 3 } // the syncMod
[Module] { default: { bar: 3 } } // the dynamically loaded

“正常”导入按预期工作,并直接为对象提供导出。动态导入在捆绑的浏览器版本中也这样做(如我所料),但[Module] { default: .. }在 NodeJS 中返回这个东西。

不使用babel-register代码运行而不是使用babel-node ( @babel/node@7.2.2) ( npx babel-node --experimental-modules --plugins=@babel/plugin-syntax-dynamic-import --presets=@babel/preset-env index) 会产生相同的结果。

我需要使用实验标志运行它,否则动态导入根本不起作用(Not supported抛出错误)。

我可以通过在添加的层下方访问动态加载的模块,而不会出现进一步的问题mod.default.bar,但是对于浏览器和 NodeJS,我的代码会有所不同。

我很感激对此行为的任何解释,也许是获得正常/预期导出对象的解决方案(/我出错的地方)。


我目前正在使用这个助手作为解决方法:

function lazyImport(promise) {
  if (typeof window !== 'undefined') {
    // Browser
    return promise
  }

  // Node
  return promise.then(mod => mod.default)
}

并像这样包装每个import()

lazyImport(import('./path/to/mod')).then(mod => /* use the mod */)

标签: javascriptnode.jsbabeljsnode-modulesdynamic-import

解决方案


推荐阅读