🧑💻 Node.js: Как избавиться от пачки require или import для CommonJS и ECMAScript модулей
HTML-код
- Опубликовано: 19 июн 2023
- Примеры кода из видео: github.com/HowProgrammingWork...
Оглавление нового курса по Node.js: github.com/HowProgrammingWork...
Видео обзор курса: • 🎧 Node JS 2022 - 2023 ...
Открытый курса по Node.js: github.com/HowProgrammingWork...
Разобрал в видео максимально кратко, потому что, иначе люди смотрели только скриншоты и не шли по ссылке в исходники, а потом я встречаю три типовых комментария:
1. Но так нельзя сделать для ECMAScript моделей (есть пример) и
2. Так не видно что именно импортируем (есть пример, как деструктурировать импорт)
3. У меня IDE скрывает импорты (ну проблемы не вижу, значит ее нет).
На самом деле у решения этого есть проблемы, но они в другом:
1. Оно не решит за вас задачу правильной декомпозиции
2. Оно не решит за вас задачу понижения зацепления моделей
3. Оно не решит за вас задачу уменьшения зависимостей
Все это нужно деллать вручную и головой, пока нет другого варианта.
Тимур, спасибо Вам большое за подробный разбор. Правильно ли я понял, все эти методы потребляют одинаковое количество ресурсов железа и не тормозят в работе?
@@NOX_69RUS на ресурсы и скорость вообще не влияет
я думаю цей коментар варто прикріпити
@@bkatsevychя дописал сообщение и закрепил
Что насчет tree shaking, чтобы не используемые зависимости не тянуть?
Тимур, я когда смотрю Ваши уроки, мне прям обнять Вас хочется😊
Ого, супер подход, буду пользоваться
Спасибо !
Очень интересный подход. Мне также не нравится куча импортов.
export * as fs from "node:fs";
export * as path from "node:path";
import * as nodeTimers from "node:timers";
import * as timersPromises from "node:timers/promises";
export const timers = {
...nodeTimers,
promises: timersPromises,
};
Хорошая идея. Большое спасибо.
Только почему-то у меня в VSCode при таком импорте не работает IntelliSense (в смысле, автодополнение кода).
Сначала думала, что в своём проекте сделала что-то не так. Но потом попробовала скачать Ваш пример - но нет, там тоже не работает.
Подскажите, пожалуйста, что нужно сделать, чтобы IntelliSense заработал?
global.d.ts сделать, как тут github.com/metarhia/Example
@@TimurShemsedinov, спасибо за столь быстрый ответ.
Да, я уже сообразила, что дело, скорее всего, в файле `global.d.ts`.
К сожалению, всё равно почему-то не работает автодополнение. То есть, как не работает - если написать что-нибудь типа `node.fs.writeFile(`, всплывает подсказка с описанием метода, аргументов и вот этого всего. Но вот путь до метода и, самое главное, методы, в данном случае модуля `fs` не отображаются. А помнить все их - чёт как-то перебор.
Много уже погуглила по этой проблеме, пробовала менять настройки `tsconfig.json` - но нет, не работает.
Решила пока не париться и обойтись статическими импортами, просто консолидировать их все в одном модуле, собрать в неймспейсы, и уже их экспортировать по другим модулям.
@@pcaptanovskyну так неймспейсы в .d.ts можно перестроить под себя
👏👍💥
есть даже практики когда делают один файл на экспорты из текущей папки) наверное думают так меньше когнитивная нагрузка если так делать (не меньше)
Так и есть, index.js делают для упаковки экспортов в одну пачку. Ну это ровно обратная проблема.
// в этом файле-прослойке вы подмените, например, fs на api сетевого файлового хранилища
У меня давно сидит такая мысль, хочется найти какой-то фреймворк, который будет это делать за меня. Условно, в entrypoint'е приложения я регистрирую какой-нибудь virtualFs модуль, для него есть .d.ts, а далее во все импорты автоматически подставляется нужная реализация в зависимости от конфига. Вы случайно такого не знаете?
Ну так зачем фреймворк? Вот это решение для такого подходит, можно подменять любые зависимости, прям как Dependency Injection, только без ООП, а на уровне модулей
А работает такой подход с IDE autocomplete?
А как быть со статическим анализом кода в таком случае?
Я не тестил, но кажется, что eslint такое не потянет
Тайпинги рядо описывают неймспейсы, все все работает, а если проблему найдете - пишите
Если взять с твоей репы пример 3 -esm то все что в node.* имеет тип any в VsCode. typescript-language-server стоит. В чем может быть проблема? Соотвественно - нет автокомплита как ты говоришь в видео что он есть. Нашел такую информацию что импорты и експорты в глобал файле делает его модулем - соотвесвенно приватным, может в этом проблема?
Попробуй тут и настрой eslint и tsconfig так же github.com/metarhia/Example
@@TimurShemsedinov Проверил и этот пример.metarhia.metasql имеет тип any. node v: 20.9. Arch linux / macOS /github codespace везде показывает при наведении тип any причем как и в global.d.ts в строчке с typeof так и в прикладном коде. если поставить точку предлагаются идентификаторы не имеющие ничего общего с этим неймспейсом.
Lasy loading? Такой пример есть?
А воно не буде мати перегрузку по пам'яті (якщо для кожного файлика вичитувати всі пакети навіть ті які не потрібні) ?
Подивіться мої лекції про commonjs та esm, про те, як працюють вони під капотом та як досягається оптимізація, керування та інтероперабильність між ними. Ні яких накладних витрат це не несе, хоч 1000 разів у циклі завантажте один модуль, він все одно створить лиш єдину кложуру (функцію огортку) навколо модуля, що забезпечує контекст файлу та тримає усі ідентифікатори в собі, з кложури експортується значення (зазвичай об'єкт, іноді функція, структура даних чи клас), і все що експортується зберігається у кешу (навіть у двох різних, але це не принципово) і експортоване замкнено на кложуру та тримає її, щоб gc не забрав
Тимур, а как это будет с ts кодом?
Да точно так же, в чем проблема?
Мой редактор кода сворачивает импорты, редко туда смотрю
Это еще раз подтверждает наличие проблемы. Если под мойкой протекает, будем сантехника вызывать или соседей затапливать?
@@TimurShemsedinov Так проблема же в том, что связанность у модулей большая, а не в количестве строчек импортов. Ни сворачивание импортов, ни скрытие их в одном импорте не решает проблему.
Но полезно знать такую технику. Правда мне больше нравится иметь большие импорты, но зато в коде иметь `await readFile(filePath)`, чем `await node.fs.promises.readFile(filePath)`, мало того что писать дольше, ещё и при чтении дополнительное время тратить)
Показал знакомому СТО эти примеры чтоб поделится полезным а он ответил что они делают следующим образом:
// File a
export * as source1 from 'source1'
export * as moduleName from 'module'
// ----
// File b
import { source1, moduleName } from './a'
// ...
Теперь у меня нет знакомый СТО 😅
А почему собственно нет, это почти то же самое
А не проще использовать нормальную IDE вместо vim'a и включить одну галочку в настройках "сворачивать импорты", я хочу писать код и бизнес логику, нахрена мне извращаться, создавать на один файл другой файл, переносить иморты и т.д. Какое-то мнимое решение проблемы
Скрытие импортов тоже ничего не решает, все что мы не видим имеет тенденцию опухать и приходить в хаос. Это решение тоже не все на свете решает, например, оно не решит проблемы с сильным зацеплением модулей, которая может приводить к разрастанию импортов. А где Вы vim у меня увидели?
@@TimurShemsedinovтоесть в вашем варианте мы видим импорты? Серьезно? Такого говнокода я уже лет 5 не видел, потом не удивляйтесь когда вебпак вам соберет бандл на 2гб, а джун решить что классной идей будет заменить весь fs на свой очень клевый модуль.
никогда так не делайте, поубивал бы за такой подход
@@Virus191288 Вебпак? Вы серьезно бекенды на ноде вебпаком собираете? Да и даже с вебпаком такой подход после минимальных изменений будет прекрасно работать, подумайте как, на досуге )))
@@Virus191288 так даже фронт можно писать со сборщиками, какие 2 гб, какой джун...
@@TimurShemsedinov
1. Я извиняюсь, а в чем вообще проблема импортов? В том что они сверху просто есть? Так свёртывание их и решает эту проблему.
2. "сильным зацеплением модулей", я не понял немного, объясните что вы имеете ввиду пожалуйста.
3. У вас есть модуль "npm", а если будет другой пакетный менеджер? Нужно идти и менять название этого модуля по всем файлам?
Я видел такой подход в последний раз года 3 назад на фронте, где выносятся импорты в отдельный index файл чтобы уменьшить импорты, но по сути этим может спокойно заниматься какой-нибудь бандлер.
В мире существуют ide которые позволяют не обращать внимание на такие вещи.
Это попросту бессмысленно