NodeJS планирует поддерживать импорт / экспорт модулей es6 (es2015)

275

Я искал по всему интернету без четкого ответа на это.

В настоящее время NodeJS использует только синтаксис CommonJS для загрузки модулей, и если вы действительно хотите использовать стандартный синтаксис модулей ES2015, вы должны либо перенести его заранее, либо использовать внешний загрузчик модулей во время выполнения.

В настоящее время я не слишком уверен, чтобы использовать любой из этих двух методов, планируют ли сопровождающие NodeJS даже поддерживать модули ES2015 или нет? Я вообще не нашел подсказки по этому поводу.

На данный момент NodeJS 6.x утверждает, что поддерживает 96% функций ES2015, но нет никаких ссылок на модули ( ссылка на поддержку NodeJS ES2105 ).

Знаете ли вы, будет ли NodeJS поддерживать эти модули "из коробки" в ближайшем будущем?

Zorgatone
источник
2
Поиск в Google node es2015 modulesв качестве одного из лучших результатов показывает следующее: github.com/nodejs/node/wiki/ES6-Module-Detection-in-Node .
Феликс Клинг
6
Лично я бы проголосовал за то, чтобы закрыть этот вопрос как «слишком локализованный», но такой тесной причины больше не существует. Допустим, Node сможет внедрить модули ES6 завтра. Вы собираетесь удалить свой вопрос, потому что он больше не актуален? Или вы хотя бы обновите его? Я не думаю, что вопрос подходит для SO, если вы уже знаете, что он устарел или нуждается в обновлении "в ближайшее время". Но это только мое мнение, и, похоже, есть другие, которые думают об обратном, что для меня нормально :) (кстати, сам по себе вопрос, конечно, важен и интересен)
Феликс Клинг
2
Хотелось бы, чтобы во вселенной Stack было место для подобных вопросов. Это может технически не соответствовать здесь, но я не знаю, согласен ли я, что это действительно "основано на мнении" также. ОП ищет конкретный ответ на конкретный вопрос, но тот, который будет (в какой-то момент) устаревшим.
Вонко здравомыслящий
5
Альтернативная формулировка этого вопроса: «Каково состояние поддержки node.js для модулей ES6?» Ответ на многие вопросы SO со временем меняется по мере развития технологий. У меня тоже были проблемы с поиском ответа, пока я не приземлился здесь.
Джо Лапп,
4
@FelixKling Я думаю, что вы хотели бы закрыть этот вопрос, было бы очень неправильным решением, так как это проблема, которую 211 человек пока считают достаточно проблемной, чтобы проголосовать.
Мухаммед Умер

Ответы:

302

Узел 13.2.0 и выше

NodeJS 13.2.0 теперь поддерживает модули ES без флага 🎉 Однако реализация по-прежнему помечена как экспериментальная, поэтому используйте ее с осторожностью.

Чтобы включить поддержку ESM в 13.2.0, добавьте следующее package.json:

{
  "type": "module"
}

Все .js, .mjs(или файлы без расширения) будет рассматриваться как ESM.

Существует целый ряд различных опций, кроме полного подписки,package.json которые подробно описаны в Документации для 13.2.0 .

Узел 13.1.0 и ниже

Те , кто до сих пор использует старые версии Node может понадобиться попробовать ESM модуль загрузчик, который является производством готовой реализацией ES Модули Spec для NodeJS:

node -r esm main.js

Подробные обновления ...

23 апреля 2019 г.

Недавно появился PR, чтобы изменить способ обнаружения ES-модулей: https://github.com/nodejs/node/pull/26745

Это все еще за --experimental-modulesфлагом, но есть значительные изменения в способе загрузки модулей:

  • package.typeкоторый может быть moduleилиcommonjs
    • type: "commonjs":
      • .js анализируется как commonjs
      • по умолчанию для точки входа без расширения является commonjs
    • type: "module":
      • .js анализируется как ESM
      • не поддерживает загрузку JSON или Native Module по умолчанию
      • по умолчанию для точки входа без расширения является esm
  • --type=[mode]чтобы вы могли установить тип в точке входа. Переопределит package.typeдля точки входа.
  • Новое расширение файла .cjs.
    • это специально для поддержки импорта commonjs в moduleрежиме.
    • это только в загрузчике esm, загрузчик commonjs остается без изменений, но расширение будет работать в старом загрузчике, если вы используете полный путь к файлу.
  • --es-module-specifier-resolution=[type]
    • варианты explicit(по умолчанию) иnode
    • по умолчанию наш загрузчик не допускает дополнительных расширений при импорте, путь к модулю должен включать расширение, если оно есть
    • по умолчанию наш загрузчик не позволяет импортировать каталоги с индексным файлом
    • разработчики могут использовать, --es-module-specifier-resolution=nodeчтобы включить алгоритм разрешения спецификатора commonjs
    • Это не «особенность», а реализация для экспериментов. Ожидается, что он будет изменен до удаления флага
  • --experimental-json-loader
    • единственный способ импортировать JSON, когда "type": "module"
    • при включении все import 'thing.json'пройдет через экспериментальный загрузчик независимо от режима
    • основанный на whatwg / html # 4315
  • Вы можете использовать, package.mainчтобы установить точку входа для модуля
    • расширения файлов, используемые в main, будут решаться в зависимости от типа модуля

17 января 2019 г.

Узел 11.6.0 по- прежнему перечисляет модули ES как экспериментальные, за флагом.

13 сентября 2017

NodeJS 8.5.0 был выпущен с поддержкой файлов mjs за флагом:

node --experimental-modules index.mjs

План для этого состоит в том, чтобы удалить флаг для выпуска LTS v10.0.

- Обновленная информация. Хранится здесь в исторических целях

8 сентября 2017

Основная ветка NodeJS была обновлена ​​с начальной поддержкой модулей ESM:
https://github.com/nodejs/node/commit/c8a389e19f172edbada83f59944cad7cc802d9d5

Это должно быть доступно в последнюю ночь (это может быть установлено через nvm для запуска вместе с существующей установкой):
https://nodejs.org/download/nightly/

И включен за --experimental-modulesфлагом:

package.json

{
  "name": "testing-mjs",
  "version": "1.0.0",
  "description": "",
  "main": "index.mjs" <-- Set this to be an mjs file
}

Затем запустите:

node --experimental-modules .

Февраль 2017:

https://medium.com/@jasnell/an-update-on-es6-modules-in-node-js-42c958b890c#.6ye7mtn37

Ребята из NodeJS решили, что наименее плохим решением является использование .mjsрасширения файла. Вывод из этого:

Другими словами, данные два файла foo.jsи bar.mjsиспользование import * from 'foo'будут рассматриваться foo.jsкак CommonJS, а import * from 'bar' будут рассматриваться bar.mjsкак модуль ES6.

А что касается сроков ...

В настоящий момент все еще существует ряд проблем со спецификацией и реализацией, которые должны произойти на стороне ES6 и виртуальной машины, прежде чем Node.js сможет даже приступить к разработке поддерживаемой реализации модулей ES6. Работа продолжается, но это займет некоторое время - в настоящее время мы рассматриваем как минимум год .

Октябрь 2016:

Один из разработчиков на Node.JS недавно присутствовал на собрании TC-39 и написал превосходную статью о блокировщиках для реализации для Node.JS:

https://hackernoon.com/node-js-tc-39-and-modules-a1118aecf95e

Основной вывод из этого:

  • Модули ES подвергаются статическому анализу, оцениваются CommonJS
  • Модули CommonJS позволяют экспортировать исправления обезьян, в настоящее время модули ES не поддерживают
  • Трудно определить, что такое ES-модуль и что такое CommonJS без какой-либо формы пользовательского ввода, но они пытаются.
  • *.mjs кажется наиболее вероятным решением, если они не могут точно обнаружить модуль ES без ввода пользователя

- Оригинальный ответ -

Это была горячая картошка уже довольно давно. Суть в том, что да, Node в конечном итоге будет поддерживать синтаксис ES2015 для импорта / экспорта модулей - скорее всего, когда спецификация для загрузки модулей будет завершена и согласована.

Вот хороший обзор того, что держит NodeJS. По сути, они должны убедиться, что новая спецификация работает для Node, который в основном состоит из условной синхронной загрузки, а также для HTML, который в основном асинхронный.

Никто не знает наверняка прямо сейчас, но я предполагаю, что Node будет поддерживать import/exportстатическую загрузку, в дополнение к новой System.importдля динамической загрузки - при этом сохраняя requireустаревший код.

Вот несколько предложений о том, как Node может достичь этого:

CodingIntrigue
источник
38
О .mjsрасширении: We have affectionately called these “Michael Jackson Script” files in the past. На всякий случай, когда вы слышите, как кто-то говорит о поп-артистах во время выступления в JS
Jeewes
1
Я не понимаю, почему недостаточно изменить синтаксис импорта. Один синтаксис для импорта es («правильный») и один для импорта cjs? Другими словами, с учетом двух файлов foo.js и bar.js, foo.js import * from 'foo'будет обрабатываться как CommonJS import * as bar from 'bar', а bar.js - как модуль ES6. Может кто-нибудь объяснить?
Кори Аликс
1
@CoreyAlix Синтаксис, как правило, не будет изменен для поддержки среды. Это действительно влияет только на узел. Кроме того, синтаксис немного не интуитивно понятен. Как мне получить доступ к экспорту в предложенном вами синтаксисе?
CodingIntrigue
Чтобы было ясно, это не «мое» предложение, я копирую то, что машинопись уже делает. Чтобы ответить на ваш вопрос, вы получаете доступ к экспорту с помощью «bar»: bar.foobar () import {foo as Foo} из «./foo» - это механизм идентификации модуля ES6. var Foo = require («./ foo») - это механизм идентификации модуля CJS. В Typescript вывод commonjs выглядит следующим образом: var mod1_1 = require ("./ mod1"); exports.mod1 = mod1; Вывод ES6 выглядит следующим образом: import {mod1} из «./mod1»; export {mod1}
Кори Аликс,
1
Я был бы действительно интересен в обновлении Node 10 к этому ответу. Была ли функция вырезана или она все еще за флагом?
dcorking