Проблемы экспорта по умолчанию в модулях JavaScript
Что такое экспорт по умолчанию в модулях JavaScript
Экспорт по умолчанию позволяет экспортировать одно значение из модуля, которое может быть импортировано с любым именем.
Это значение является экспортом по умолчанию для модуля и может быть любого типа, например, функцией, объектом или примитивным значением. Например, модуль экспортирует функцию по умолчанию:
// math.js
export default function subtract(a, b) {
return a - b;
}
В этом примере функция subtract
является экспортом по умолчанию для модуля math
. Её можно импортировать с любым именем в другой файл, например, так:
// app.js
import add from './math.js';
const result = add(2, 2); // returns 0
Обратите внимание, что функция вычитания была импортирована как multiply
(умножение). Это возможно потому, что экспортируемые по умолчанию функции можно импортировать с любым именем. Это может привести к путанице и усложнить сопровождение кода по мере роста кодовой базы.
Проблема с экспортом по умолчанию
Экспорт по умолчанию не обнаруживается IDE
Основная проблема экспорта по умолчанию заключается в том, что его нельзя обнаружить.
При импорте модуля, имеющего только именованные экспорты, IDE показывает список доступных экспортов, которые могут быть использованы в коде. Однако с экспортом по умолчанию это невозможно, поскольку он не имеет имени. Это означает, что разработчики могут не знать, что у модуля есть экспорт по умолчанию, или не знать, как он называется. В результате может возникнуть путаница, и модуль станет сложнее использовать.
Экспорт по умолчанию неудобен при рефакторинге
Другая проблема с экспортом по умолчанию заключается в том, что он неудобен в плане рефакторинга.
Переименование именованного экспорта в модуле автоматически переименовывает и любое использование этого экспорта, если используется IDE, поддерживающая эту функцию. Однако с экспортом по умолчанию это невозможно, поскольку он может быть импортирован с любым именем. Это означает, что если переименовать экспорт по умолчанию, то необходимо вручную обновить все случаи его использования в коде.
Экспорт по умолчанию — кошмар именования
Экспорт по умолчанию также может создать проблемы с именованием. Поскольку его можно импортировать с любым именем, разные разработчики могут использовать разные названия для одного и того же экспорта по умолчанию. Это может привести к несогласованности и затруднить сопровождение кода по мере роста кодовой базы.
Напротив, именованные экспорты обеспечивают чёткое и последовательное соглашение об именовании, что значительно упрощает понимание и поддержку кода.
Альтернативы экспорта по умолчанию
Именованный экспорт
Именованные экспорты — хорошая альтернатива экспорту по умолчанию. С помощью именованных экспортов можно экспортировать несколько значений из модуля и дать каждому из них чёткое и последовательное имя. Это облегчает другим разработчикам понимание и использование кода.
Пример модуля, экспортирующего две именованные функции:
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
В данном примере экспортируются две именованные функции, add
и subtract
. Их можно импортировать в другой файл следующим образом:
// app.js
import { add, subtract } from './math';
const sum = add(2, 2); // returns 4
const difference = subtract(2, 2); // returns 0
Обратите внимание, что функции импортируются с использованием их имён, что облегчает понимание и сопровождение кода.
Обёртка для экспорта по умолчанию
Другая альтернатива экспорту по умолчанию — использование обёртки экспорта по умолчанию. Для этого необходимо создать отдельный модуль, экспортирующий функцию по умолчанию, которая просто импортирует и реэкспортирует нужное значение из исходного модуля.
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// math-wrapper.js
// Выбираем, что экспортировать
export { add, subtract } from './math';
// ИЛИ экспортируем целиком
export * as default from './math';
Эта обёртка — ещё один уровень абстракции, где можно выбрать модули, которые требуется экспортировать из связанной папки, или экспортировать всё содержимое файла по умолчанию. Таким образом, их можно использовать в app.js
следующим образом:
Это также позволяет сохранить чёткое и последовательное именование, избежав проблем с экспортом по умолчанию.
Необходимость экспорта по умолчанию
Не существует абсолютов во всём, и в некоторых случаях экспорт по умолчанию необходим. Например, при инкапсуляции обычных компонентов:
ls ./components
Row.jsx Form Upload.jsx
Select Alert.jsx Skeleton
...
В данном случае каталог или файл представляют собой компонент, и в этом случае может потребоваться использовать экспорт компонентов по умолчанию.
Рекомендуется называть экспортируемый по умолчанию компонент в соответствии с именем файла и именем компонента в файле. Это минимизирует недоразумения и ошибки и позволит изменять имена IDE.
// app.js
import Row from './Row.jsx';
import Select from "./Select"
Кроме того, рекомендуется использовать index.js
в папке components
, для объединения компонентов и использования именованных экспортов:
// components/index.js
export { default as Row } from './Row.jsx';
export { default as Select } from './Select';
// app.js
import { Row, Select } from "./components";
Другие лучшие практики
Помимо рассмотренных альтернативных вариантов, существуют и другие лучшие практики, которым стоит следовать, чтобы улучшить сопровождаемость кода:
- Используйте последовательные соглашения об именовании экспортируемых файлов. Это облегчит другим разработчикам понимание и использование вашего кода.
- Избегайте экспорта слишком большого количества значений из одного модуля. Это может усложнить понимание и поддержку вашего кода.
Заключение
Хотя экспорт по умолчанию может быть удобен в некоторых ситуациях, его следует использовать с осторожностью и только в случае необходимости. Опять, это лишь общий совет. Не существует универсального решения для каждого проекта. В конечном счёте, выбор наиболее подходящего метода остаётся за вами.