У меня есть (полиморфный) код, связанный с помощью веб-пакета, включая динамический импорт (для разделения кода), и я хочу запустить тот же код в 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 */)