dev.easy
130 subscribers
11 links
заметки full stack девелопера - находки, фишечки и боль современной web-разработки


notion blog: https://bit.ly/deveasy

github: https://github.com/z4o4z
Download Telegram
Все наши nodejs сервисы и пакеты(либы которые шарятся между сервисами, а иногда и фронтом, и паблишатся в npm) написаны на TS и билдятся тоже им. Под билдом я имею ввиду убрать типы и сделать валидный ES2017 код. Не транспилируем в ES5, т.к. и нода, и все последние браузеры отлично хавают ES2017, а ES5 только делает размер пакета больше. В билдах, в основном, мы используем cjs(commonjs) модули, они работают во всех версиях ноды, вебпак и прочие бандлеры их тоже саппортят. И только в последние пакеты, которые юзаются и на фронте, и на бэке, мы добавили возможность билда в ES модули (это те, которые import {} from ''; export const a = 10; ), при этом cjs никуда не делся. Сделано это для того, что бы помочь бандлерам удалять неиспользуемый код(tree shaking). И до недавнего времени все работало замечательно.

И вот в новом сервисе в качестве кор депенденси у нас есть Logux(это тип Redux, но с уклоном на бэк и реалтайм). Под капотом у него ES модули, и все бы ничего, но Logux не использует .mjs расширение для своих файлов, а без этого расширения нельзя зарекварить( require('esmodule') ) ES модуль из cjs, это ограничения ноды что бы юзать esm в cjs.

И так, солюшенов у нас 2:
- форкнуть logux и добавить туда билд в cjs или `.msj` расширение для es модулей
- перейти на новый стандарт, добавить type="module" в package.json и юзать в билдах esm

Мы выбрали второй вариант и переход на новый стандарт. Но, как всегда, все оказалось не так-то и просто. После того, как изменили тип модулей в конфиге TSа, сбилженный код перестал запускаться. Проблема в том, что уже в es модулях нельзя заимпортить cjs через impoprt { a } from 'cjsmodule', так как частичный импорт работает только с esm. Окей, нашли все cjs модули и порефачили импорты в import * as cjs from 'cjsmodule', в этом случае нода это хавает, и по сути, ассайнит все что есть в exports переменной cjsmodule в cjs импорт. Но и это еще не все, т.к. в сорцах наших пакетов используется esm, а при билде мы имеем cjs, то при импорте таких либ через * as module, дефолтный экспорт будет в module.default, что логично, т.к. после билда export default A; превратился в exports.default = A. Пришлось везде поменять использование дефолтных импортов из cjs на module.default()|new module.default() и тд. В итоге мы смогли завести сбилженный esm код. Потом еще выяснилось, что наш run local скрипт перестал работать, т.к. ts-node-dev не хочет работать с esm и резолверами которые мы юзаем, переехали на nodemon и ts-node, в итоге и это завелось. Все это заняло в районе 6 часов, и тупо для того, что бы начать использовать ОДНУ единственную либу с ES модулями внутри и без .mjs расширения.

Вывод: если хотите юзать современные модули в ноде, а особенно в NPM пакетах, билдите их с .mjs расширением или делайте 2 билда(cjs или esm), иначе кто-то будет страдать, МНОГО страдать.

#npm #nodejs #dependency
💯1