Русский

Изучите различия между CommonJS и ES Modules, двумя доминирующими системами модулей в JavaScript, с практическими примерами и рекомендациями для современной веб-разработки.

Системы модулей: CommonJS против ES Modules - Подробное руководство

В постоянно развивающемся мире разработки JavaScript модульность является краеугольным камнем создания масштабируемых и поддерживаемых приложений. Две системы модулей исторически доминировали в этой области: CommonJS и ES Modules (ESM). Понимание их различий, преимуществ и недостатков имеет решающее значение для любого разработчика JavaScript, независимо от того, работает ли он во front-end с такими фреймворками, как React, Vue или Angular, или в back-end с Node.js.

Что такое системы модулей?

Система модулей предоставляет способ организации кода в многократно используемые единицы, называемые модулями. Каждый модуль инкапсулирует определенную часть функциональности и предоставляет только те части, которые необходимы другим модулям для использования. Этот подход способствует повторному использованию кода, снижает сложность и улучшает удобство обслуживания. Думайте о модулях как о строительных блоках; каждый блок имеет определенную цель, и вы можете объединить их для создания более крупных и сложных структур.

Преимущества использования систем модулей:

CommonJS: Стандарт Node.js

CommonJS появился как стандартная система модулей для Node.js, популярной среды выполнения JavaScript для серверной разработки. Он был разработан для решения проблемы отсутствия встроенной системы модулей в JavaScript, когда Node.js был впервые создан. Node.js принял CommonJS в качестве способа организации кода. Этот выбор оказал огромное влияние на то, как создавались JavaScript-приложения на стороне сервера.

Ключевые особенности CommonJS:

Синтаксис CommonJS:

Вот пример того, как используется CommonJS:

Модуль (math.js):

// math.js
function add(a, b) {
 return a + b;
}

function subtract(a, b) {
 return a - b;
}

module.exports = {
 add: add,
 subtract: subtract
};

Использование (app.js):

// app.js
const math = require('./math');

console.log(math.add(5, 3)); // Вывод: 8
console.log(math.subtract(10, 4)); // Вывод: 6

Преимущества CommonJS:

Недостатки CommonJS:

ES Modules (ESM): Стандартизированная система модулей JavaScript

ES Modules (ESM) - это официальная стандартизированная система модулей для JavaScript, представленная в ECMAScript 2015 (ES6). Они призваны обеспечить последовательный и эффективный способ организации кода как в Node.js, так и в браузере. ESM обеспечивают встроенную поддержку модулей в самом языке JavaScript, устраняя необходимость во внешних библиотеках или инструментах сборки для обработки модульности.

Ключевые особенности ES Modules:

Синтаксис ES Modules:

Вот пример того, как используются ES Modules:

Модуль (math.js):

// math.js
export function add(a, b) {
 return a + b;
}

export function subtract(a, b) {
 return a - b;
}

// Или, в качестве альтернативы:
// function add(a, b) {
//  return a + b;
// }
// function subtract(a, b) {
//  return a - b;
// }
// export { add, subtract };

Использование (app.js):

// app.js
import { add, subtract } from './math.js';

console.log(add(5, 3)); // Вывод: 8
console.log(subtract(10, 4)); // Вывод: 6

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

ES Modules поддерживают как именованные, так и экспорты по умолчанию. Именованные экспорты позволяют экспортировать несколько значений из модуля с определенными именами. Экспорты по умолчанию позволяют экспортировать одно значение в качестве экспорта по умолчанию модуля.

Пример именованного экспорта (utils.js):

// utils.js
export function formatCurrency(amount, currencyCode) {
 // Форматировать сумму в соответствии с кодом валюты
 // Пример: formatCurrency(1234.56, 'USD') может вернуть '$1,234.56'
 // Реализация зависит от желаемого форматирования и доступных библиотек
 return new Intl.NumberFormat('en-US', { style: 'currency', currency: currencyCode }).format(amount);
}

export function formatDate(date, locale) {
 // Форматировать дату в соответствии с локалью
 // Пример: formatDate(new Date(), 'fr-CA') может вернуть '2024-01-01'
 return new Intl.DateTimeFormat(locale).format(date);
}
// app.js
import { formatCurrency, formatDate } from './utils.js';

const price = formatCurrency(19.99, 'EUR'); // Европа
const today = formatDate(new Date(), 'ja-JP'); // Япония

console.log(price); // Вывод: €19.99
console.log(today); // Вывод: (зависит от даты)

Пример экспорта по умолчанию (api.js):

// api.js
const api = {
 fetchData: async (url) => {
 const response = await fetch(url);
 return response.json();
 }
};

export default api;
// app.js
import api from './api.js';

api.fetchData('https://example.com/data')
 .then(data => console.log(data));

Преимущества ES Modules:

Недостатки ES Modules:

CommonJS против ES Modules: Подробное сравнение

Вот таблица, в которой суммированы основные различия между CommonJS и ES Modules:

Функция CommonJS ES Modules
Синтаксис импорта require() import
Синтаксис экспорта module.exports export
Загрузка Синхронная Асинхронная (в браузерах), Синхронная/Асинхронная в Node.js
Статический анализ Нет Да
Встроенная поддержка браузера Нет Да
Основной вариант использования Node.js (исторически) Браузеры и Node.js (современный)

Практические примеры и варианты использования

Пример 1: Создание многократно используемого модуля утилит (интернационализация)

Предположим, вы создаете веб-приложение, которое должно поддерживать несколько языков. Вы можете создать многократно используемый модуль утилит для обработки интернационализации (i18n).

ES Modules (i18n.js):

// i18n.js
const translations = {
 'en': {
 'greeting': 'Hello, world!'
 },
 'fr': {
 'greeting': 'Bonjour, le monde !'
 },
 'es': {
 'greeting': '¡Hola, mundo!'
 }
};

export function getTranslation(key, language) {
 return translations[language][key] || key;
}
// app.js
import { getTranslation } from './i18n.js';

const language = 'fr'; // Пример: Пользователь выбрал французский язык
const greeting = getTranslation('greeting', language);
console.log(greeting); // Вывод: Bonjour, le monde !

Пример 2: Создание модульного API-клиента (REST API)

При взаимодействии с REST API вы можете создать модульный API-клиент для инкапсуляции логики API.

ES Modules (apiClient.js):

// apiClient.js
const API_BASE_URL = 'https://api.example.com';

async function get(endpoint) {
 const response = await fetch(`${API_BASE_URL}${endpoint}`);
 if (!response.ok) {
 throw new Error(`HTTP error! status: ${response.status}`);
 }
 return response.json();
}

async function post(endpoint, data) {
 const response = await fetch(`${API_BASE_URL}${endpoint}`, {
 method: 'POST',
 headers: {
 'Content-Type': 'application/json'
 },
 body: JSON.stringify(data)
 });
 if (!response.ok) {
 throw new Error(`HTTP error! status: ${response.status}`);
 }
 return response.json();
}

export { get, post };
// app.js
import { get, post } from './apiClient.js';

get('/users')
 .then(users => console.log(users))
 .catch(error => console.error('Error fetching users:', error));

post('/users', { name: 'John Doe', email: 'john.doe@example.com' })
 .then(newUser => console.log('New user created:', newUser))
 .catch(error => console.error('Error creating user:', error));

Переход с CommonJS на ES Modules

Переход с CommonJS на ES Modules может быть сложным процессом, особенно в больших кодовых базах. Вот несколько стратегий, которые следует рассмотреть:

Node.js и ES Modules:

Node.js развился, чтобы полностью поддерживать ES Modules. Вы можете использовать ES Modules в Node.js, выполнив следующие действия:

Выбор правильной системы модулей

Выбор между CommonJS и ES Modules зависит от ваших конкретных потребностей и среды, в которой вы разрабатываете:

Заключение

Понимание различий между CommonJS и ES Modules необходимо любому разработчику JavaScript. Хотя CommonJS исторически был стандартом для Node.js, ES Modules быстро становятся предпочтительным выбором как для браузеров, так и для Node.js из-за их стандартизованной природы, преимуществ в производительности и поддержки статического анализа. Тщательно рассмотрев потребности вашего проекта и среду, в которой вы разрабатываете, вы можете выбрать систему модулей, которая лучше всего соответствует вашим требованиям, и создавать масштабируемые, поддерживаемые и эффективные JavaScript-приложения.

Поскольку экосистема JavaScript продолжает развиваться, крайне важно быть в курсе последних тенденций в системах модулей и передовых методов для достижения успеха. Продолжайте экспериментировать как с CommonJS, так и с ES Modules, и изучите различные инструменты и методы, доступные для помощи в создании модульного и поддерживаемого кода JavaScript.