NodeJS ES6 Модули и экспорт / импорт по умолчанию - PullRequest
2 голосов
/ 15 апреля 2020

Я пытаюсь использовать модули стиля ES6 с NodeJS v13.13, и я сталкиваюсь с противоречивым поведением.

Изначально мой проект переносился с помощью node-babel, но затем я включил поддержку встроенного модуля ES6, добавив "type": "module" в свой пакет. json файл.

На этом этапе импортируйте операторы типа import * as esprima from 'esprima'; перестали работать правильно. При проверке, вместо импорта, создающего функцию esprima.parse, она создала функцию esprima.default.parse.

Конечно, все это можно было исправить, используя что-то вроде:

import * as esprimaLoad from 'esprima';
const esprima = esprimaLoad.default;

Однако Какое поведение является правильным для спецификаций c? Правильно ли babel удалить / свернуть объект по умолчанию, и есть ли ошибка в текущем поведении node.js, которая все еще помечена как экспериментальная? Все эти ES-модули против общего JS модуля вызывают головную боль.

Обновление:

Я до сих пор не дошел до сути, но есть и другие проблемы. esprima. js, одна из библиотек, в которой возникла эта проблема, похоже, была создана с использованием веб-пакета и представляет собой формат UMD (определение универсального модуля). Он начинается со следующего:

(function webpackUniversalModuleDefinition(root, factory) {
/* istanbul ignore next */
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
    else if(typeof define === 'function' && define.amd)
        define([], factory);
/* istanbul ignore next */
    else if(typeof exports === 'object')
        exports["esprima"] = factory();
    else
        root["esprima"] = factory();
})(this, function() { ...

Я думаю, что формат UMD веб-пакета уже предназначен для работы как с инструкциями import в браузере, так и с require операторами в node.js. Однако при использовании экспериментальных модулей / babel в node.js кажется, что следующее не работает вообще:

import esprima from 'esprima'

, и следующее работает с babel, но не с экспериментальными модулями :

import * as esprima from 'esprima'

и следующие работают как с babel, так и с экспериментальными модулями:

import * as esprimaLoad from 'esprima'
const esprima = esprimaLoad.default?esprimaLoad.default:esprimaLoad;

Для модулей, которые не используют эту хитрость UMD веб-пакета, оба Бабель и экспериментальные модули, кажется, работают просто отлично.

1 Ответ

1 голос
/ 15 апреля 2020

Если вы экспортируете default, тогда вам не нужно импортировать его таким окольным способом.

Простейшая версия напрямую импортирует значение по умолчанию:

import myDefault from '/modules/my-module.js';

Можно также использовать синтаксис по умолчанию с рассмотренным выше синтаксисом (импорт пространства имен или именованный импорт). В таких случаях импорт по умолчанию должен быть объявлен первым. Например:

import myDefault, * as myModule from '/modules/my-module.js';
// myModule used as a namespace

Вы можете проверить больше из MDN

Так что в вашем случае

import esprima from 'esprima';

Это должно быть простейший оператор импорта.

...