Как стать автором
Поиск
Написать публикацию
Обновить

Комментарии 6

Смутился из-за названия "рекурсивные зависимости". Для меня, в базисе, рекурсия - самовызов функции. Вполне себе легитимный с точки зрения программирования подход. Разумеется, для этого у функции должно быть условие выхода из самовызова.

Рекурсивный подход вполне себе может применяться и для зависимостей на фронте (опять же, при наличии условия выхода из цепочки вызовов):

// ./one.mjs
import two from './two.mjs';

export default function one(x) {
    console.log(x);
    return (x > 0) ? two(x - 1) : 0;
}
// ./two.mjs
import one from './one.mjs';

export default function two(x) {
    console.log(x);
    return (x > 0) ? one(x - 1) : 0;
}
// ./index.html
<script type="module">
    import one from './one.mjs';

    one(4);
</script>

Пример синтетический, но рабочий:

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

Когда возникает циклическая зависимость (рекурсивная зависимость) при сборке

IMHO, "циклическая зависимость" лучше отображает суть того, о чём пишет автор.

я вас удивлю, но даже мои примеры с циклическими зависимостями корректно отрабатывает сборщик. Но когда у нас более сложные случаи, тогда сборщик не может обработать корректно импорт. Например кейс с enum при использовании ts-jest: https://github.com/kulshekhar/ts-jest/issues/281

Другие рабочие кейсы к сожалению не могу найти с ходу с данной проблемой.

Разрешение рекурсивных зависимостей хорошее дело для стабильности и чистоты кода.

Циклические зависимости усложняют работу если вы работаете, например, с фремворком, не понятно, где начало, где конец и откуда плясать.
Решением может быть применение принципов SOLID при построении приложения.

А как SOLID решит проблему циклических зависимостей? Учитывая что D в SOLID это Dependency Injection, а этот подход упрощает создание циклических зависимостей.

Все решения циклических зависимотей в DI контейнерах сводятся либо к внедрению функций вместо значения, либо к динамическим импортам (которые тоже функции). В лучшем случае контейнер может выдать сообщение об ошибке. Но это скорее костыль, нежели решение проблемы.

Мы вот это используем:
https://github.com/sverweij/dependency-cruiser

…хотя "используем" это не совсем правильное слово. Мы его запускаем, но результаты почти не смотрим, потому что в связке с TypeScript они чрезвычайно шумные. Ведь в TypeScript даже если импорт циклический "на бумаге" (в коде), он совершенно не обязательно циклический "по факту" (в рантайме), если импортируется только тип, который после транспиляции пропадает.

Планируем попробовать вернуться на eslint-plugin-import. Есть сомнения в том, что зависание пофиксили до конца: https://github.com/import-js/eslint-plugin-import/issues/2348

В прошлый раз когда я хотел eslint-plugin-import на актуальную версию eslint применить, у меня версия не подходила. но вроде в package.json они уже поддерживают eslint 9. Я это к тому, что в последней версии идет переосмысление использования eslint, они с него выкидывают вещи отвечающие за форматирование, чтобы как раз убыстрить выполнение.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации