различия в синтаксисе между модулями CJS и ES6

В модулях CJS я бы использовал export и var plugin = require('plugin'); для экспорта/импорта
В модулях ES6 я бы использовал export и import * as plugin from 'plugin'; для экспорта/импорта.

Есть ли еще различия в синтаксисе? эти ^ различия верны?

Что значит export default и export *?


person Rikard    schedule 30.06.2015    source источник
comment
В CJS exportmodule.export) — это просто переменная. В ES6 export является ключевым словом и имеет собственную грамматику языка!   -  person Bergi    schedule 30.06.2015
comment
@ Берги, спасибо, интересно. Дайте также интересный ответ, который займет несколько минут.   -  person Rikard    schedule 30.06.2015


Ответы (1)


Модули CommonJS и модули ES6 очень похожи, но у них есть некоторые очень важные отличия, о которых следует знать. Чтобы сначала ответить на ваш вопрос напрямую:

var plugin = require('plugin');

в ES6 будет эквивалентно обоим

// Import all named exports of 'plugin'.
import * as plugin from 'plugin';

и/или

// Import default export of 'plugin'.
import plugin from 'plugin';

// an alias of
import {default as plugin} from 'plugin';

но это зависит от того, как был написан «плагин» и был ли он написан с помощью ES6 export или CommonJS module.exports.

Модули CommonJS

Импорт CommonJS имеет только один экспортируемый объект. Этот объект может быть функцией, объектом или чем-то еще. Обычно модули CommonJS делают

exports.foo = ...;
exports.bar = ...;

для экспорта именованных свойств. Они также могут экспортировать объект «по умолчанию» как

module.exports = function(){};

Суть здесь в том, что если вам нужен как экспорт по умолчанию, так и именованный экспорт, ваш единственный вариант — фактически поместить свойства непосредственно в экспорт по умолчанию.

Модули ES6

Для модулей ES6 понятия именованного экспорта и экспорта по умолчанию разделены на 100 %. например

export var foo = ...;
export var bar = ...;
export default function fn(){};

Основное отличие в том, что

fn.foo !== foo;

В этом примере есть два случая

Используемый плагин ES6 export

import * as plugin from 'plugin';

plugin.foo === ...;
plugin.bar === ...;
typeof plugin === 'object';

import plugin from 'plugin';

plugin.foo === undefined;
plugin.bar === undefined;
typeof plugin === 'function';

Используемый плагин CommonJS module.exports

import * as plugin from 'plugin';

plugin.foo === ...;
plugin.bar === ...;
typeof plugin === 'object';

import plugin from 'plugin';

plugin.foo === ...;
plugin.bar === ...;
typeof plugin === 'function';

Импорт/экспорт Live Binding

Другое основное отличие в вашем примере заключается в том, что plugin является живой привязкой. Это означает, что если он будет обновлен внутри модуля позже, он будет обновляться в вашем импорте, например.

// plugin.js

export var foo = 'foo';

export function update(){
    foo = 'bar';
}

// other.js

import {foo, update} from 'plugin';

foo === 'foo';

update();

foo === 'bar'

и это было бы не так, если бы вы сделали

var foo = require('plugin').foo;
var update = require('plugin').update;
person loganfsmyth    schedule 30.06.2015
comment
Это был очень хороший ответ! +1. Могу ли я использовать синтаксис commonjs и ES6 в одном проекте в Node.js или io.js (я так полагаю, но интересно, есть ли проблемы с ним, о которых я не знаю)? Исчезнут ли модули commonsjs со временем (может быть, субъективный вопрос...)? - person Rikard; 30.06.2015
comment
Также нашел интересную суть/статью об этом: gist.github.com/domenic/4748675 - person Rikard; 01.07.2015
comment
Вы определенно можете использовать модули ES5 в ES6. Я не могу сказать о Traceur, но Babel включает стандартный уровень взаимодействия, когда вы используете синтаксис import, который проверяет, импортируете ли вы модуль ES6 или ES5. - person loganfsmyth; 01.07.2015