TL; DR - Не до ~ октября 2019 года Node.js модули Team не спросил :
Не публикуйте пакеты модулей ES, предназначенные для использования Node.js, до [октября 2019 г.]
Обновление за май 2019 г.
С 2015 года, когда был задан этот вопрос, поддержка модулей JavaScript значительно выросла и, надеюсь, станет официально стабильной в октябре 2019 года. Все остальные ответы теперь устарели или чрезмерно сложны. Вот текущая ситуация и лучшие практики.
Поддержка ES6
99% ES6 (также известный как 2015) поддерживаются Node с версии 6 . Текущая версия Node - 12. Все вечнозеленые браузеры поддерживают подавляющее большинство функций ES6. ECMAScript сейчас находится в версии 2019 , а схема управления версиями теперь поддерживает использование лет.
Модули ES (также известные как модули ECMAScript) в браузерах
Все вечнозеленые браузеры были поддерживать import
-ную модули ES6 поскольку 2017. Динамические импорта будут поддерживаться с помощью Chrome (+ вилы , как Opera и Samsung Интернет) и Safari. Поддержка Firefox намечена на следующую версию, 67.
Вам больше не нужно Webpack / rollup / Parcel и т. Д. Для загрузки модулей. Они могут быть полезны для других целей, но не требуются для загрузки вашего кода. Вы можете напрямую импортировать URL-адреса, указывающие на код модулей ES.
Модули ES в Node
Модули ES ( .mjs
файлы с import
/ export
) поддерживаются с Node v8.5.0 путем вызова node
с --experimental-modules
флагом. Node v12, выпущенный в апреле 2019 года, переписал поддержку экспериментальных модулей. Наиболее заметным изменением является то, что расширение файла необходимо указывать по умолчанию при импорте:
export const hello = 'Hello world!';
import { hello } from './lib.mjs';
console.log(hello);
Обратите внимание на обязательные .mjs
расширения повсюду. Беги как:
node --experimental-modules index.mjs
В выпуске Node 12 команда Modules попросила разработчиков не публиковать пакеты модулей ES, предназначенные для использования Node.js, до тех пор, пока не будет найдено решение для использования пакетов через require('pkg')
и import 'pkg'
. Вы по-прежнему можете публиковать собственные модули ES, предназначенные для браузеров.
Экосистемная поддержка собственных модулей ES
По состоянию на май 2019 года экосистемная поддержка модулей ES еще не развита. Например, такие тестовые среды, как Jest и Ava , не поддерживают --experimental-modules
. Вам нужно использовать транспилятор, а затем выбрать между использованием именованного import { symbol }
синтаксиса import ( ) (который пока не работает с большинством пакетов npm) и синтаксиса импорта по умолчанию ( import Package from 'package'
), который работает, но не тогда, когда Babel его анализирует для пакетов, созданных на TypeScript (graphql-tools, node-influenx, faast и т. д.). Однако существует обходной путь, который работает как с, так --experimental-modules
и если Babel транспилирует ваш код, чтобы вы могли протестировать его с помощью Jest / Ava / Mocha и т. д .:
import * as ApolloServerM from 'apollo-server'; const ApolloServer = ApolloServerM.default || ApolloServerM;
Возможно, некрасиво, но таким образом вы можете написать свой собственный код модулей ES с import
/ export
и запускать его node --experimental-modules
без транспиляторов. Если у вас есть зависимости, которые еще не готовы к ESM, импортируйте их, как указано выше, и вы сможете использовать тестовые среды и другие инструменты через Babel.
Предыдущий ответ на вопрос - помните, не делайте этого, пока Node не решит проблему require / import, надеюсь, примерно в октябре 2019 года.
Публикация модулей ES6 в npm с обратной совместимостью
Для того, чтобы опубликовать модуль ES в npmjs.org так , что он может быть импортирован непосредственно, без Бабеля и других transpilers, просто указать main
поле в package.json
в .mjs
файл, но опустить расширение:
{
"name": "mjs-example",
"main": "index"
}
Это единственное изменение. Если опустить расширение, Node будет сначала искать файл mjs при запуске с --experimental-modules. В противном случае он вернется к файлу .js, поэтому ваш существующий процесс транспиляции для поддержки более старых версий Node будет работать, как и раньше - просто убедитесь, что указали Babel на .mjs
файл (ы).
Вот исходный код для собственного модуля ES с обратной совместимостью для Node <8.5.0, который я опубликовал в NPM. Вы можете использовать его прямо сейчас, без Babel или чего-либо еще.
Установите модуль:
npm install local-iso-dt
# or, yarn add local-iso-dt
Создайте тестовый файл test.mjs :
import { localISOdt } from 'local-iso-dt/index.mjs';
console.log(localISOdt(), 'Starting job...');
Запустите узел (v8.5.0 +) с флагом --experimental-modules:
node --experimental-modules test.mjs
Машинопись
Если вы разрабатываете на TypeScript, вы можете сгенерировать код ES6 и использовать модули ES6:
tsc index.js --target es6 --modules es2015
Затем вам нужно переименовать *.js
вывод в .mjs
известную проблему, которая, надеюсь, скоро будет исправлена, чтобы tsc
можно было .mjs
напрямую выводить файлы.