NodeJS планує підтримувати модулі імпорту / експорту es6 (es2015)


275

Я шукав по всьому Інтернету без чіткої відповіді на це.

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

Наразі я не надто позитивний, щоб використовувати будь-який із цих двох методів, чи підтримують сервіси NodeJS навіть підтримку модулів ES2015 чи ні? Я взагалі не знайшов натяку на це.

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

Чи знаєте ви, чи підтримає NodeJS ці модулі поза коробкою найближчим часом?


2
Гугл для node es2015 modules, показує наступне як один із найкращих результатів: github.com/nodejs/node/wiki/ES6-Module-Detection-in-Node .
Фелікс Клінг

6
Особисто я хотів би проголосувати за закриття цього питання як "занадто локалізованого", але такої тісної причини більше не існує. Скажімо, Node завтра вдається реалізувати модулі ES6. Ви збираєтесь потім видалити своє запитання, оскільки воно вже не актуально? Або ви принаймні оновите його? Я не думаю, що питання підходить для ТА, якщо ви вже знаєте, що воно буде застарілим або потребує оновлення "незабаром". Але це лише моя думка, і, здається, є й інші, хто думає навпаки, що для мене нормально :) (fwiw, саме по собі питання, звичайно, важливе та цікаве)
Фелікс Клінг

2
Мені б хотілося, щоб у Всесвітній стеці було місце для таких питань. Це технічно може не підходити тут, але я не знаю, що я згоден, що це дійсно "засноване на думці". ОП шукає конкретну відповідь на конкретне запитання, але таку, яка буде (в якийсь момент) застарілою.
Wonko the Sane

5
Альтернативне фразування цього питання: "Який стан підтримки node.js для модулів ES6?" Відповідь на багато питань ТА змінюється з часом, коли технологія розвивається. У мене теж були проблеми з пошуком відповіді, поки я не приземлився тут.
Джо Лапп

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 для 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 аналізується як есм
      • не підтримує завантаження 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для встановлення точки входу для модуля
    • розширення файлів, що використовуються в основному, будуть вирішені залежно від типу модуля

17 січня 2019 року

Вузол 11.6.0 досі перераховує модулі ES як експериментальні, за прапором.

13 вересня 2017 року

NodeJS 8.5.0 було випущено з підтримкою файлів mjs за прапором:

node --experimental-modules index.mjs

План цього - зняти прапор для випуску v10.0 LTS.

- Актуалізована інформація. Тут утримувались для історичних цілей--

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 та Virtual Machine, перш ніж 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 може досягти цього:


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 як Foo} з "./foo" - це механізм ідентифікації модуля ES6. var Foo = вимога ("./ foo") - це механізм ідентифікації модуля CJS. У Typescript висновок commonjs виглядає так: var mod1_1 = requ ("./ mod1"); export.mod1 = mod1; Вихід ES6 виглядає приблизно так: імпортувати {mod1} з “./mod1”; export {mod1}
Corey Alix

1
Мені було б дуже цікаво в оновленні Node 10 до цієї відповіді. Чи зробила функція розріз, чи це все ще за прапором?
декор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.