Запрос «как сделать es» чаще всего означает одно из двух: создать ES-модуль в JavaScript (файл с export/import) или подключить скрипт как модуль через type="module". Если скрипт с import выдаёт в консоли ошибку «Cannot use import statement outside a module» — это верный признак, что файл загружается как обычный скрипт, а не как ES-модуль.

Ниже разберём оба сценария: создание модуля с экспортом функций, подключение его в браузере и в Node.js, а также типичные ошибки. Если под «es» вы имели в виду что-то другое (например, файл конфигурации или испанскую раскладку), уточните задачу — общие принципы работы с файлами из статьи всё равно пригодятся.

Что такое ES-модуль и чем он отличается от обычного скрипта

ES-модуль — это файл JavaScript, который использует стандартные ключевые слова export и import, появившиеся в спецификации ECMAScript 2015 (ES6). В отличие от классического скрипта, модуль имеет собственную область видимости: переменные, объявленные внутри него, не попадают в глобальный объект window.

Ещё одно отличие — модули по умолчанию работают в строгом режиме (strict mode), а их загрузка в браузере происходит отложенно, как у скрипта с атрибутом defer. Это влияет на порядок выполнения кода и на то, какие ошибки вы увидите при нарушении правил.

💡

ES-модуль — это обычный JS-файл с export/import, который браузер или Node.js загружает в особом режиме с изолированной областью видимости.

Как создать ES-модуль: экспорт функций и переменных

Создайте обычный текстовый файл с расширением .js, например utils.js. Внутри опишите функции или константы и пометьте те из них, которые должны быть доступны снаружи, ключевым словом export.

// utils.js

export const VERSION = "1.0";

export function sum(a, b) {

return a + b;

}

export default function greet(name) {

return `Привет, ${name}!`;

}

Различают два вида экспорта. Именованный экспорт (export function sum) позволяет вывозить из файла несколько сущностей, а экспорт по умолчанию (export default) — только одну на файл. Смешивать оба подхода в одном модуле можно, как показано в примере выше.

  • 📦 Именованный экспорт — для наборов функций и констант
  • ⭐ Экспорт по умолчанию — для главной сущности модуля
  • 🔒 Всё без export остаётся приватным внутри файла

Как подключить ES-модуль в браузере

Чтобы браузер трактовал скрипт как модуль, добавьте в тег script атрибут type="module". Без него встреченный import вызовет синтаксическую ошибку.

<script type="module">

import greet from "./utils.js";

import { sum, VERSION } from "./utils.js";

console.log(greet("мир"));

console.log(sum(2, 3), VERSION);

</script>

Обратите внимание на путь ./utils.js: в браузерных модулях расширение файла указывать обязательно, а относительный путь начинается с ./ или ../. Голое имя вроде import ... from "utils" браузер без дополнительных инструментов (import map или сборщика) не разрешит.

⚠️ Внимание: ES-модули не работают при открытии HTML-файла напрямую по протоколу file:// — браузер блокирует такие запросы из соображений безопасности. Запустите локальный сервер, например через расширение редактора или команду npx serve, и открывайте страницу по адресу http://localhost.

☑️ Проверка перед запуском модуля в браузере

Выполнено: 0 / 4

Как сделать ES-модуль в Node.js

В Node.js исторически использовалась система CommonJS с require и module.exports. Чтобы включить поддержку ES-модулей, есть два общепринятых способа: дать файлу расширение .mjs либо добавить в package.json поле "type": "module". Во втором случае все файлы .js проекта будут считаться ES-модулями.

{

"name": "my-project",

"type": "module"

}

После этого синтаксис import/export работает так же, как в браузере. Учтите: в Node.js при импорте локальных файлов расширение тоже обязательно, а импорт JSON-файлов и встроенных модулей имеет свои особенности — детали зависят от версии Node.js, поэтому сверяйтесь с официальной документацией вашей версии.

📊 Где вы планируете использовать ES-модули?
В браузере на чистом JS
В Node.js на сервере
В проекте со сборщиком (Vite, Webpack)
Только изучаю тему

Типичные ошибки и их причины

Большинство проблем при переходе на ES-модули сводится к нескольким повторяющимся сценариям. Таблица ниже помогает быстро сопоставить сообщение об ошибке с вероятной причиной.

ОшибкаВероятная причинаЧто проверить
Cannot use import statement outside a moduleФайл загружен как обычный скриптАтрибут type="module" или поле "type": "module"
Failed to fetch dynamically / CORSСтраница открыта по file://Запуск через локальный сервер
The requested module does not provide an exportИмя в import не совпадает с экспортомТочное написание и регистр имён
Cannot find moduleНеверный путь или нет расширенияПрефикс ./ и суффикс .js

Отдельного внимания заслуживает смешение двух систем модулей. Если в проекте с "type": "module" остался файл с require(), он перестанет работать — такие файлы нужно либо переписать на import, либо переименовать в .cjs, чтобы Node.js трактовал их как CommonJS.

⚠️ Внимание: импорт и экспорт чувствительны к регистру имён. export function sum и import { Sum } — разные идентификаторы, и на некоторых файловых системах регистр важен даже в именах самих файлов. Проверяйте соответствие символ в символ.
💡

Если проект большой и использует сторонние пакеты, рассмотрите сборщик вроде Vite — он сам разрешает пути, собирает модули в бандл и избавляет от рутины с расширениями файлов.

Именованный импорт против импорта по умолчанию

Частый вопрос новичков: почему один импорт пишется в фигурных скобках, а другой — без них. Правило простое. Именованные экспорты импортируются строго по имени в скобках: import { sum } from "./utils.js". Экспорт по умолчанию импортируется без скобок, и имя при импорте можно выбрать любое: import greet from "./utils.js".

Комбинированная форма import greet, { sum } from "./utils.js" тоже допустима. Если нужно забрать всё содержимое модуля разом, используйте конструкцию import * as utils from "./utils.js" — тогда все экспорты окажутся свойствами объекта utils.

Динамический импорт — что это

Кроме статического import существует динамический: import("./utils.js").then(m => m.sum(1, 2)). Он возвращает промис и позволяет загружать модуль по требованию — например, только когда пользователь открыл определённый раздел страницы. Это сокращает время первоначальной загрузки.

Часто задаваемые вопросы

Чем ES-модуль отличается от CommonJS?

ES-модули используют import/export и являются стандартом языка, тогда как CommonJS с require/module.exports — историческая система Node.js. ES-модули поддерживают статический анализ и динамический импорт через промисы; в браузере работает только формат ES.

Почему import работает в Node.js, но не в браузере?

Скорее всего, в браузере скрипт подключён без атрибута type="module", либо страница открыта по протоколу file://. Также браузер требует полный путь с расширением файла, а Node.js в некоторых случаях допускает сокращения.

Можно ли использовать import без сборщика в реальном проекте?

Да, современные браузеры поддерживают ES-модули нативно. Ограничения: нужен сервер вместо file://, явные расширения в путях и осторожность со сторонними библиотеками, распространяемыми не в модульном формате.

Что делать, если библиотека экспортирует только CommonJS?

В Node.js CommonJS-модули обычно можно импортировать из ES-модуля через импорт по умолчанию. В браузере потребуется сборщик (Vite, Webpack, Rollup) либо версия библиотеки, собранная специально в формате ES.

Нужно ли писать "use strict" в ES-модуле?

Нет. Код внутри ES-модуля автоматически выполняется в строгом режиме, директива избыточна.

💡

Для браузера достаточно type="module" и локального сервера, для Node.js — поля "type": "module" в package.json. Остальное — внимательность к путям, расширениям и регистру имён.