Марк Эриксон «Мой опыт модернизации пакетов до ESM»
ссылка на оригинал
Наши мнения можете послушать в подкасте, а ниже вольный пересказ (статья больно интересная).
TL;DR Марк мейнтейнер redux, react-redux, redux-thunk, reselect и @reduxjs/toolkit. В конце 2022 он попытался перетащить эти пакеты на ESM но к августу 2023 так и не смог закончить работу. Потому что всё очень плохо.
Итак, на дворе 2022 и Марк садится за работу. Пора бы уже перетащить пакеты на ESM! В этот момент он осознаёт, что нет ни одного руководства, как сделать универсальный пакет, который будет работать везде. Как вы можете догадаться, он не хочет идти по пути Синдре Сорхуса и выпускать Pure ESM, нет, он хочет оставить совместимость для старых приложений и поддержать вообще всё, что можно. Включая Webpack 4. Похвальное желание.
Прочитав 175 статей он приходит к выводу, что нужно:
- добавить
- прописать exports с энтри-поинтами для разных окружений
- кажется нужно поставить расширение
Дело нехитрое, Марк собирает RTK с новым
Альфа собрана, опубликована и... БУМ! Тайпскрипт с
- Если мы написали
- Если мы не написали
Всё по спеке! Да, бандлерам зачастую тут по барабану, они проглотят и так, но Node.js требовательна. Открытым остаётся вопрос нужно ли делать несколько
Марк собирается с духом и делает ещё один заход. Чтобы было проще, он откладывает в сторону RTK и берёт в руки
Тут он узнаёт, что Webpack 4 всё ещё популярнее Webpack 5. А Webpack 4 не поддерживает поле exports и ему не нравится .mjs в поле main. А так же Webpack 4 не понимает optional chaining. Придётся для него сделать артефакт-фоллбек: ESM в синтаксисе ES2017, с расширением .js. И пусть этот артефакт лежит в поле main.
Кажется победа близка, альфы выпущены, отзывы хорошие. Всё работает!
В начале мая выходит
Тут Марк сгорел. Он потратил месяцы на стабилизацию сборки и вот такая засада — нужно пилить новое решение чтобы не ломались RSC. И никакой нормальной документации нет. Просто всё стало сложнее, для мейнтейнеров пакетов.
Ну и вывод в целом такой, что переход с CJS на ESM это кошмар и конца ему не видно. А тут ещё и RSC. Удивительно, что наша экосистема хоть как-то работает. А Redux Toolkit 2.0 выйдет, точно выйдет.
ссылка на оригинал
Наши мнения можете послушать в подкасте, а ниже вольный пересказ (статья больно интересная).
TL;DR Марк мейнтейнер redux, react-redux, redux-thunk, reselect и @reduxjs/toolkit. В конце 2022 он попытался перетащить эти пакеты на ESM но к августу 2023 так и не смог закончить работу. Потому что всё очень плохо.
Итак, на дворе 2022 и Марк садится за работу. Пора бы уже перетащить пакеты на ESM! В этот момент он осознаёт, что нет ни одного руководства, как сделать универсальный пакет, который будет работать везде. Как вы можете догадаться, он не хочет идти по пути Синдре Сорхуса и выпускать Pure ESM, нет, он хочет оставить совместимость для старых приложений и поддержать вообще всё, что можно. Включая Webpack 4. Похвальное желание.
Прочитав 175 статей он приходит к выводу, что нужно:
- добавить
"type": "module"в
package.jsonчтобы показать, что это ESM
- прописать exports с энтри-поинтами для разных окружений
- кажется нужно поставить расширение
.mjs, но это уродливо, так что нафиг
Дело нехитрое, Марк собирает RTK с новым
package.json, всё выглядит неплохо, он кидает PR и БУМ, всё сломалось. Да, рантайм работает как надо, но вот
Jestотвалился.
Jestне переварил `
export default` в ESM и как бы Марк не пытался обойти проблему — ничего не вышло. Что же, пришлось перейти на
Vitest. Прощай,
Jest.
Альфа собрана, опубликована и... БУМ! Тайпскрипт с
moduleResolution
node16и
nodenextне может вытащить типы. А
Node.jsне может работать
.jsCommonJS если пакет переключен впакеты на ESM но к а CommonJS файлы в таких пакетах должны иметь расширение
.cjs.
- Если мы написали
"type": "module"то используем
.jsдля ESM и
.cjsдля CommonJS
- Если мы не написали
"type": "module"то используем
.mjsдля ESM и
.jsдля CommonJS
Всё по спеке! Да, бандлерам зачастую тут по барабану, они проглотят и так, но Node.js требовательна. Открытым остаётся вопрос нужно ли делать несколько
d.ts-файлов. Есть мнение, что нужно.
Марк собирается с духом и делает ещё один заход. Чтобы было проще, он откладывает в сторону RTK и берёт в руки
redux-thunk. 20 строк кода, что может пойти не так? Выкидывает
Babelс
Rollup, берет в руки
ESBuildи tsup. Пара часов игры с конфигом и вот на выходе два файла:
.mjsи
.cjs
Тут он узнаёт, что Webpack 4 всё ещё популярнее Webpack 5. А Webpack 4 не поддерживает поле exports и ему не нравится .mjs в поле main. А так же Webpack 4 не понимает optional chaining. Придётся для него сделать артефакт-фоллбек: ESM в синтаксисе ES2017, с расширением .js. И пусть этот артефакт лежит в поле main.
Кажется победа близка, альфы выпущены, отзывы хорошие. Всё работает!
В начале мая выходит
Next 13.4. Да-да, тот самый, с React Server Components. Те самые RSC в которых не работает код использующий контекст.
React.createContext()
и useLayoutEffect
— они отсутствовали на сервере и взрывали код. Команда Next предложила использовать отдельный export
react-server
в который положить код оптимизированный для серверных компонент (рекомендация с «use client» появилась чуть позже).Тут Марк сгорел. Он потратил месяцы на стабилизацию сборки и вот такая засада — нужно пилить новое решение чтобы не ломались RSC. И никакой нормальной документации нет. Просто всё стало сложнее, для мейнтейнеров пакетов.
Ну и вывод в целом такой, что переход с CJS на ESM это кошмар и конца ему не видно. А тут ещё и RSC. Удивительно, что наша экосистема хоть как-то работает. А Redux Toolkit 2.0 выйдет, точно выйдет.