Использование Node.js требует от импорта/экспорта ES6

В проекте, с которым я сотрудничаю, у нас есть два варианта, по которым мы можем использовать систему модулей:

  • Импорт модулей с помощью require и экспорт с использованием module.exports и exports.foo.
  • Импорт модулей с использованием ES6 import и экспорт с использованием ES6 export

Есть ли преимущества в производительности для использования одного над другим? Есть ли что-то еще, что мы должны знать, если мы будем использовать модули ES6 над Node те?

Ответ 1

Есть ли преимущества в производительности для использования одного над другим?

Имейте в виду, что пока еще нет механизма JavaScript, который на самом деле поддерживает модули ES6. Вы сами сказали, что используете Вавилон. По умолчанию Babel конвертирует объявления import и export в CommonJS (require/module.exports). Поэтому, даже если вы используете синтаксис модуля ES6, вы будете использовать CommonJS под капотом, если вы запустите код в Node.

Существуют технические различия между модулями CommonJS и ES6, например. CommonJS позволяет загружать модули динамически. ES6 не допускает этого, но для этого есть API в разработке.

Поскольку модули ES6 являются частью стандарта, я бы использовал их.

Ответ 2

Существует несколько возможностей использования/возможностей, которые вы можете рассмотреть:

Требуется:

  • У вас может быть динамическая загрузка, где имя загруженного модуля не предопределен/статичен или где вы условно загружаете модуль только в том случае, если он "действительно необходим" (в зависимости от определенного потока кода).
  • Загрузка синхронный. Это означает, что если у вас есть несколько require s, они загружаются и обрабатываются один за другим.

ES6 Импорт:

  • Вы можете использовать именованный импорт для выборочной загрузки только тех частей, которые вам нужны. Это может сохранить память.
  • Импорт может быть асинхронным (и в текущем загрузчике модуля ES6, это на самом деле есть) и может немного улучшиться.

Кроме того, система модулей Требование не является стандартной. Сейчас вряд ли станет стандартным, что существуют модули ES6. В будущем в различных реализациях будет встроена поддержка модулей ES6, что будет выгодно с точки зрения производительности.

Ответ 3

Основные преимущества синтаксические:

  • Более декларативный/компактный синтаксис
  • Модули ES6 в основном упростят устаревание UMD (Universal Module Definition) - существенно удаляет раскол между CommonJS и AMD (сервер против браузера).

Вероятно, вы вряд ли увидите преимущества производительности модулей ES6. Вам все равно потребуется дополнительная библиотека для объединения модулей, даже если в браузере есть полная поддержка функций ES6.

Ответ 4

Есть ли преимущества в производительности для использования одного над другим?

Текущий ответ - нет, потому что ни один из текущих движков браузера не реализует import/export из стандарта ES6.

В некоторых сравнительных диаграммах http://kangax.github.io/compat-table/es6/ не учитывайте это, поэтому, когда вы видите почти все зелень для Chrome, будьте осторожны. import ключевое слово из ES6 не было учтено.

Другими словами, текущие браузерные движки, включая V8, не могут импортировать новый файл JavaScript из основного файла JavaScript через любую директиву JavaScript.

(Мы можем по-прежнему просто отбросить несколько ошибок или на несколько лет до тех пор, пока V8 не выполнит это в соответствии со спецификацией ES6.)

Этот документ - это то, что нам нужно, и этот document это то, что мы должны соблюдать.

И в стандарте ES6 сказано, что зависимости модуля должны быть там до того, как мы прочитаем модуль, как на языке программирования C, где у нас были (заголовки) .h файлы.

Это хорошая и проверенная структура, и я уверен, что эксперты, создавшие стандарт ES6, имели это в виду.

Это то, что позволяет Webpack или другим поставщикам пакетов оптимизировать пакет в некоторых особых случаях и уменьшать некоторые зависимости от пакета, которые не нужны. Но в тех случаях, когда у нас есть идеальные зависимости, этого никогда не будет.

Это займет некоторое время, пока поддержка import/export не будет включена, а ключевое слово require долгое время не будет работать.

Что такое require?

Это node.js способ загрузки модулей. (https://github.com/nodejs/node)

Node использует методы системного уровня для чтения файлов. Вы в основном полагаетесь на это при использовании require. require закончится каким-то системным вызовом типа uv_fs_open (зависит от конечной системы, Linux, Mac, Windows), чтобы загрузить файл/модуль JavaScript.

Чтобы убедиться, что это правда, попробуйте использовать Babel.js, и вы увидите, что ключевое слово import будет преобразовано в require.

введите описание изображения здесь

Ответ 5

Использование модулей ES6 может быть полезно для "дрожания дерева"; то есть включение Webpack 2, Rollup (или других связующих) для идентификации путей кода, которые не используются/импортированы, и поэтому не попадают в полученный пакет. Это может значительно уменьшить размер файла, исключив код, который вам никогда не понадобится, но с CommonJS поставляется по умолчанию, потому что Webpack и др. Не имеют возможности узнать, нужно ли это.

Это делается с использованием статического анализа пути кода.

Например, используя:

import { somePart } 'of/a/package';

... дает связнику подсказку, что package.anotherPart не требуется (если он не импортирован, его нельзя использовать - правильно?), поэтому он не будет связывать его.

Чтобы включить это для Webpack 2, вам необходимо убедиться, что ваш транспилер не выплевывает модули CommonJS. Если вы используете плагин es2015 с babel, вы можете отключить его в своем .babelrc так:

{
  "presets": [
    ["es2015", { modules: false }],
  ]
}

Rollup, а другие могут работать по-другому - просмотрите документы, если вы заинтересованы.

Ответ 6

Когда дело доходит до асинхронной или ленивой загрузки, то import() намного мощнее. Посмотрите, когда нам требуется компонент асинхронным способом, тогда мы используем его import некоторым асинхронным способом, как в переменной const используя await.

const module = await import('./module.js');

Или, если вы хотите использовать require() тогда,

const converter = require('./converter');

Дело в том, что import() на самом деле асинхронный по своей природе. Как упомянуто neehar venugopal в ReactConf, вы можете использовать его для динамической загрузки реагирующих компонентов для архитектуры на стороне клиента.

Также это намного лучше, когда речь идет о маршрутизации. Это единственная особенность, которая заставляет сетевой журнал загружать необходимую часть, когда пользователь подключается к определенному веб-сайту к его конкретному компоненту. Например, страница входа перед панелью управления не будет загружать все компоненты панели мониторинга. Потому что то, что нужно текущему, то есть компоненту входа, которое будет загружено только.

То же самое касается export: ES6 export точно так же, как для CommonJS module.exports.

ПРИМЕЧАНИЕ. - Если вы разрабатываете проект node.js, вы должны строго использовать require() как узел будет выдавать ошибку исключения как invalid token 'import' если вы будете использовать import. Таким образом, узел не поддерживает операторы импорта.

ОБНОВЛЕНИЕ - Как предлагает Дэн Даскалеску: начиная с версии 8.5 (выпущено в сентябре 2017 г.), node --experimental-modules index.mjs позволяет использовать import без Babel. Вы можете (и должны) также публиковать свои пакеты НПХ, require как родную ESModule, с обратной совместимостью для старого require пути.

Посмотрите это, чтобы больше узнать, как использовать асинхронный импорт - https://www.youtube.com/watch?v=bb6RCrDaxhw.

Ответ 7

Я лично использую импорт, потому что мы можем импортировать необходимые методы, члены с помощью импорта.

import {foo, bar} from "dep";

Имя_файла: dep.js

export foo function(){};
export const bar = 22

Кредит идет к Полю Шану. Дополнительная информация.

Ответ 8

Самое важное, что нужно знать, это то, что модули ES6 действительно являются официальным стандартом, а модули CommonJS (Node.js) - нет.

В 2019 году модули ES6 поддерживаются 84% браузеров. В то время как Node.js помещает их за флаг --experimental-modules, есть также удобный пакет узлов, называемый esm, который делает интеграцию гладкой.

Другая проблема, с которой вы можете столкнуться между этими модульными системами, - это местоположение кода. Node.js предполагает, что источник хранится в каталоге node_modules, а большинство модулей ES6 развернуто в виде плоской структуры каталогов. Это нелегко согласовать, но это можно сделать, взломав файл package.json с помощью скриптов до и после установки. Вот пример изоморфного модуля и статья, объясняющая, как он работает.