В большинстве проектов Javascript, будь то внешний проект React или внутренний проект node.js, у вас есть возможность сгруппировать все ваши импорты в один index.js. Это может «удобно» отображать все соответствующие экспорты в одном файле. Затем можно извлечь импорт из этого файла. Выглядит мило и аккуратно, но довольно быстро может выйти из-под контроля.
TLDR; почему вам не следует группировать все импортируемые данные в один файл index.js?
- Круговая зависимость
- Непреднамеренный импорт при использовании динамического импорта
- Потому что так сказал создатель узла js :)
- При использовании index.js все в порядке? если вы создаете пакет npm.
Как обычно выглядит файл index.js
типичный файл index.js может выглядеть так, вы группируете все экспорты в один файл,
1. Круговая зависимость
Итак, время идет, и индексный файл становится больше. и один разработчик использует функцию автоматического импорта, импортируя из index.js родственный файл. (IDE предпочитают импортировать кратчайший путь импорта)
Теперь разработчик будет экспортировать его в наш index.js, конечно же, как это делали все до него.
В чем проблема? Он создал циклическую зависимость.
Как? «composition.js» импортирует «index.js» для получения элементов. «index.js» импортирует «composition.js» для экспорта «CompostionsOfItems».
Хьюстон у нас проблема
composition.js → index.js → композиция.js
Теперь файл (например, «items.js»), который импортирует некоторую переменную из файла index.js, выдает это исключение: cannot read property "Item1" of undefined
некоторые компиляторы могут обойти циклический импорт (например, Webpack с babel), но в некоторых случаях (jest + ts-jest, jest + babel) компиляция не может преодолеть циклический импорт, и результатом является неоднозначное сообщение об ошибке. это довольно сложно отлаживать, но если вы знаете, что нужно избегать index.js, это будет гораздо реже.
Вопрос: как нам правильно это сделать?
Ответ: избегайте index.js и импортируйте только то, что вам нужно, откуда вам это нужно. в нашем случае импорт Item1 и Item2 из файла Items.js не создаст проблем.
Отказ от index.js не гарантирует отсутствие проблем с циклическими зависимостями. Вы должны структурировать операторы импорта в виде дерева.
Еще один способ избежать цикличности — использовать правило Eslint no-cycle
eslint-plugin-import.
2. Непреднамеренный импорт при использовании динамического импорта
При написании внешнего интерфейса обычно и считается лучшей практикой разделение кода с помощью динамического импорта (также известного как разделение кода). например. в React вы можете использовать React.lazy()
, чтобы разделить код на несколько частей. Неважно, какой фреймворк, но допустим, вы пишете приложение для реагирования, и все ваши маршруты красиво расположены в одном файле `routes.js`
// routes.js export Route1 from 'route1' export Route2 from 'route2' export Route3 from 'route3' export Route4 from 'route4'
если вы хотите воспользоваться преимуществами отложенной загрузки, чтобы ваше приложение загружалось быстрее. у вас, вероятно, есть этот код где-то в вашем приложении
const LazyRoute1 = React.lazy(() => import('./routes').then(module => ({ default: module.Route1 }));
Кто виноват? вместо того, чтобы загружать только Route1 «по запросу», вы фактически получаете все маршруты одновременно, что приводит к большей пропускной способности, чем ожидалось, и сводит на нет всю цель ленивой загрузки и разделения кода.
3. Потому что так сказал создатель node js 😉
На javascript-конференции JSConf EU создатель node.js Райан Даль рассказал о 10 вещах, о которых сожалеет о node.js, одним из которых был файл «index.js». это хороший доклад, и я предлагаю вам посмотреть его полностью.
Резюме: 10 причин, по которым я сожалею о Node.js — Райан Даль
Видео: 10 причин, по которым я сожалею о Node.js — Райан Даль — JSConf EU
Когда вам следует использовать index.js?
Если вы создаете пакет с открытым исходным кодом и хотите предоставить общедоступный модуль, обычно принято использовать файл, который предоставляет все, что предоставляет библиотека.