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

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

  1. импорт модулей с помощью require, и экспорт с помощью module.exports и exports.foo.
  2. импорт модулей с помощью ES6 import, и экспорт с помощью ES6 export

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

7 ответов


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

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

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

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


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

требуется:

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

ЕС6 Импорт:

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

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


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

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

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


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

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

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

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

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

этой документ это то, что нам нужно, и это документ это то, что мы должны подчиняться.

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

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

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

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

что это require?

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

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

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

enter image description here


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

делается это с помощью статического анализа кода путь.

например, через:

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

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

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

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

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


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

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

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

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

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

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

Примечание - при разработке узла.проект JS, то вы должны строго использовать require() как узел выдаст ошибку исключения как invalid token 'import' если вы используете import . Таким образом, узел не поддерживает операторы импорта

обновление - как предложено Дэн Dascalescu: начиная с v8.5.0 (выпущено Sep 2017),node --experimemntal-modules index.mjs можно использовать import без Бабеля. Вы можете (и должны) также опубликуйте свои пакеты npm как собственный ESModule с обратной совместимостью старый require путь.

Посмотреть больше зазор, где использовать async импорта - https://www.youtube.com/watch?v=bb6RCrDaxhw


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

import {foo, bar} from "dep";

имя файла: dep.js

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

заслуга Павла-Шаня. Подробнее.