Будни разработчика
14.6K subscribers
1.36K photos
398 videos
8 files
2.28K links
Download Telegram
#js #es #esnext #webpack #twitter

Отличный тред Андрея Ситника о том, что же не так в мире ES-модулей и почему радоваться рано.

Коротко для фронтенда: реализация модулей в Webpack отличается от стандарта, поддержка браузерами чистых модулей ещё не совсем достаточна, а когда она будет достаточна — встанет проблема доставки до потребителя и генерации карт исходного кода. В общем, от бандлеров избавиться удастся совсем не скоро, а скорее всего — никогда. Но это и не нужно.

https://twitter.com/andrey_sitnik/status/1229753395961044993
#инструмент дня

Не нравятся create-react-app или дефолтные консольные инструменты Vue.js, но конфигурировать Webpack тоже не нравится?

Да, конфигурирование может быть простым накидыванием плагинов, а может потрепать нервы.

Но для старта можно воспользоваться https://createapp.dev/ и радоваться.

Выбираем базу, транспилятор, тестовую среду, загрузчики стилей, накидываем оптимизаций – и 💥 вы уже фронт-опс!

#webpack #snowpack #react #vue #svelte #tool
#инструмент дня

Мой Страшно_секретный_проект.ts, который есть не что иное как расширение для Chrome DevTools, собирается Webpack 4 от 14 до 20 секунд. Он не то чтобы большой, моего кода там немного, но Material-UI накладывает свои нюансы…

Короче, я решил дать шанс сборщику Parcel. Недавно вышла его вторая версия, в которой список изменений (канал Вебня, крайне рекомендую) просто какой-то нереальный:

- Новая система плагинов
- Tree shaking включён по умолчанию
- Улучшения производительности, включающие новый компилятор JavaScript, написанный на языке Rust, а также распараллеливание задач
- Улучшение бандлера с ES модулями
- Автоматический code-splitting (разделение кода)
- Обработка изображений
- Улучшенное кэширование
- Улучшенный hot-reloading
- Инлайнинг бандлов
- Поддержка создания библиотек
- Ленивый режим разработки (пересобирает только необходимые файлы)
- Улучшения поддержка веб воркеров
- Улучшенная диагностика ошибок
- Более надёжный вотчер файлов
- Более быстрые и точные source maps

В общем, сборка теперь занимает 1.5 секунды. Полторы секунды вместо пятнадцати до того.

Я аж прыгаю до потолка. Раньше не любил Parcel потому что мне всегда нужны были достаточно сложные кастомные конфиги, но для этого проекта встал как родной.

Осталось разобраться, как в манифест расширения пробросить версию из package.json.

#parcel #webpack #tool #bundler
👍2
#заметка дня

Разработка продукта с Google AppsScript в основе означает, что вместо нормального API у вас будет вызов функций через объект google.script.run.

Я завернул это в Promise, но вот проблема: хочется же разрабатывать локально с комфортом, накидать JSON с тестовыми данными от сервера, замокать глобальные переменные и стор (приложение гибридное). Конечно, удобнее всего просто эти данные импортировать.

Но очень не хотелось бы, чтобы замоканные данные попали в итоговую сборку. Значит, надо модули эти на лету заменять.

Вторая похожая проблема — это A/B-тесты: одним пользователям показываем одно, другим — другое. А собирать хотим из одних исходников.

И вот эту проблему решает модуль webpack с простым названием NormalModuleReplacementPlugin.

Документация модуля максимально проста, но я бы хотел обратить внимание вот на такой момент: не стоит привязываться в названиях таких модулей к среде выполнения (development/production). Вы можете очень легко случайно заменить вообще все загружаемые модули, где есть слово development, например.

Также обратите внимание на путь до модуля. В моём приложении одни и те же компоненты могли импортироваться из разных его частей и собираться отдельно, что делало почти невозможным указывание от корня. Эту проблему придётся решать отдельно на уровне разрешения путей.

В итоге, я остановился на таком подключении и пока доволен:


new webpack.NormalModuleReplacementPlugin(
/(window|mocks)\.dev/,
function (resource) {
resource.request = resource.request.replace(
/dev/,
'production'
);
}
),


Подменяю глобальный стор и моки на их пустые альтернативы и всё прекрасно работает.

Быстрой сборки вам! Кстати, об этом: хочу достичь того же на Parcel 2. Знаете, как? Делитесь!

#webpack #build #module
👍3
#заметка дня

Разработка продукта с Google AppsScript в основе означает, что вместо нормального API у вас будет вызов функций через объект google.script.run.

Я завернул это в Promise, но вот проблема: хочется же разрабатывать локально с комфортом, накидать JSON с тестовыми данными от сервера, замокать глобальные переменные и стор (приложение гибридное). Конечно, удобнее всего просто эти данные импортировать.

Но очень не хотелось бы, чтобы замоканные данные попали в итоговую сборку. Значит, надо модули эти на лету заменять.

Вторая похожая проблема — это A/B-тесты: одним пользователям показываем одно, другим — другое. А собирать хотим из одних исходников.

И вот эту проблему решает модуль webpack с простым названием NormalModuleReplacementPlugin.

Документация модуля максимально проста, но я бы хотел обратить внимание вот на такой момент: не стоит привязываться в названиях таких модулей к среде выполнения (development/production). Вы можете очень легко случайно заменить вообще все загружаемые модули, где есть слово development, например.

Также обратите внимание на путь до модуля. В моём приложении одни и те же компоненты могли импортироваться из разных его частей и собираться отдельно, что делало почти невозможным указывание от корня. Эту проблему придётся решать отдельно на уровне разрешения путей.

В итоге, я остановился на таком подключении и пока доволен:


new webpack.NormalModuleReplacementPlugin(
/(window|mocks)\.dev/,
function (resource) {
resource.request = resource.request.replace(
/dev/,
'production'
);
}
),


Подменяю глобальный стор и моки на их пустые альтернативы и всё прекрасно работает.

Быстрой сборки вам! Кстати, об этом: хочу достичь того же на Parcel 2 или Vite. Знаете, как? Делитесь!

#webpack #build #module
👍8👎1
#заметка дня

Тоже считаете, что поведение dart-sass и их мэнтейнеров не является логичным?

Можно пойти и поставить «большие пальцы» в этот issue на GitHub: https://github.com/sass/dart-sass/issues/568, в котором люди просят добавить флаг для вывода результирующего CSS в ASCII, без конвертации в Unicode.

Ну нельзя же жить в отрыве от реальности, да и неудобно это для многих применений.

Тем временем, отвлечёмся. То тут то там спрашивают о конфиге Webpack. Мол, поделиться.

Ребят, я когда-то давно до последнего игнорировал вебпак и тоже думал, что вот где-то там есть идеальный конфиг. Так вот, его нет. Каждый пишет свой.

Для начала надо понять, что вебпак собирает всё, что ты ему скормишь, в один большой JS-файл. Это была изначальная идея. Даже точка входа не index.html, а index.js.

Отсюда пошла концепция «загрузчиков»: css-loader, font-loader, svg-loader… чтобы можно было просто импортировать разные виды файлов прямо в JS.

Когда файлы импортированы и внедрены в JS — настаёт время их оттуда извлекать. И тут начинается время т. н. экстракторов: css-extract-plugin, text-extract-plugin, assets-extract-plugin…

Вот вокруг этой логики и крутятся все конфиги. Это и дикая мощь, и не менее дикие проблемы.

Да, в Webpack 5 концепция чуток поменялась, но лишь чуток.

Мы живём в 2022 году, есть шикарные инструменты сборки вроде Vite, Parcel. Gulp тоже никуда не исчезал. Генераторы статичных сайтов типа 11ty и Enhance тоже прекрасно справляются с работой.

Например, точкой входа в Vite является index.html, сразу становится логичным, в случае мультистраничного сайта, просто добавить несколько файлов HTML в конфиг, а Vite сделает остальное. А уж генераторы сайтов и подавно под это заточены.

Так что не надо нервничать, что не получается единственно верный конфиг вебпака.

Ни у кого не получается. И у всех получается.

#webpack
👍13
#статья дня

Что самое опасное может сказать фронтенд-разработчик, верстающий макет или готовящий ui-kit?

Опустим сейчас (несуществующее) разделение на настоящий и ненастоящий фронтенд.

Вот это:

— Я умею нормально называть классы, они у меня всегда уникальные!

Окей, дай мне гарантию, что ты не ошибёшься на десятке страниц, нескольких десятках комбинаций компонентов и все твои коллеги такие же смышлёные. Ещё скажи, в композицию умеешь и специфичность на лету посчитаешь.

Ребят, штуки вроде пространств имён, БЭМ, OOCSS, CSS-in-JS, CSS modules появились не потому что их разработчики глупы или ленивы. Они появились потому что все мы люди и толпа может быть как умнее одного человека, так и бесконечно глупее. Ок, если не глупее, то, как минимум невнимательнее.

Ведь подобная ситуация она везде, не только в вёрстке.

Ну вот давайте возьмём для примера Next.js. За базу там взяты CSS-модули, поэтому уже один только этот факт делает вопрос: «А css-модули уже устарели, да?», — некорректным.

Да, «гладить» фреймворк против шерсти не стоит. Да, создать глобальный класс для компонента способом, не предусмотренным документацией (созданием отдельного глобального скоупа) будет проблемой (То же самое касается и css-in-js).

Но зато насколько легче решаются остальные 99% задач!

Короче, чтобы вам сегодня сделать своё понимание кода и его сборки чуть лучше и заодно понять сопутствующие проблемы CSS-модулей горячо рекомендую эту статью: https://habr.com/ru/post/688844/

Как включить их в сборку, как типизировать. Зачем вообще типизировать и как экспорты по умолчанию всё портят.

Прекрасно и максимально понятно написано. Заодно скилл вебпака подтянете :)

#css #cssmodules #webpack
👍13👎2😁1
#статья дня

Vite очень быстро набирает обороты. Ещё бы, без необходимости, собственно, сборки на этапе разработки скорость работы (как минимум, старта) увеличивается в десятки раз. Но почему?

Всё просто, Vite и аналогичные утилиты работают с "чистыми" es6-модулями, перезаписывая адреса импорта и предоставляя современному браузеру сделать остальное.

Чувствуете, проблему? Чем больше модулей — тем больше браузеру грузить. Даже локально это может стать проблемой. Собственно, об этом бенчмарки в статье и говорят: https://betterprogramming.pub/is-vite-really-faster-than-webpack-b414f6cc751c

На такой конфигурации Webpack соберёт бандл быстрее, чем браузер загрузит файлы.

Есть ли решение? Конечно, «ленивая» загрузка файлов и модулей!

История на этом не оканчивается и Webpack продолжает весьма успешную жизнь и борьбу, поскольку покрывает гораздо больше сложных ситуаций. Но для быстрого старта современные инструменты подходят лучше.

#vite #webpack #rollup
👍12😱21😁1
#тред дня

Отличный тред Андрея Ситника о том, что же не так в мире ES-модулей и почему радоваться рано. Тред из конца 2020, но не потерял популярности и сейчас.

Почему вспомнил сейчас? Потому что отлично дополняет предыдущий пост про Vite.

Коротко для фронтенда: реализация модулей в Webpack отличается от стандарта, поддержка браузерами чистых модулей ещё не совсем достаточна, а когда она будет достаточна — встанет проблема доставки до потребителя и генерации карт исходного кода. В общем, от бандлеров избавиться удастся совсем не скоро, а скорее всего — никогда. Но это и не нужно.

https://twitter.com/andrey_sitnik/status/1229753395961044993

Для тех, кто не про твиттер: https://threadreaderapp.com/thread/1229753395961044993.html

#js #es #esnext #webpack #twitter
👍3
#инструмент дня

Кто сократил время билда с шестидесяти секунд до четырёх?

Правильно, я. С помощью этого милого крабика с КДПВ.

Проект называется Rspack: https://www.rspack.dev/

Чем хорош помимо скорости?

Ребята не стали придумывать велосипед, а сделали Webpack-подобный инструмент с аналогичным API для плагинов и максимально совместимым конфигом.

Поддержка sass-loader, postcss-loader, less-loader из коробки. Удобная (и понятная!) работа с ассетами, адекватное управление путями.

Да, не все плагины работают из коробки. Например, NormalModuleReplacementPlugin не заработал. Но за ускорение в 15-20 раз я готов немного переделать процессы (а не переделывать всё вообще, как предлагает тот же Turbopack).

Для некоторых лоадеров имеются замены, чем я не преминул воспользоваться. Больше никаких MiniCssExtractPlugin. Поддержка HTML тоже из коробки.

В общем, мне нравится. Одобрение на внедрение я получил, проведём аудит кода и вперёд.

И вам рекомендую попробовать.

#webpack #rust #rspack
6👍1
#статья дня

Что самое опасное может сказать фронтенд-разработчик, верстающий макет или готовящий ui-kit?

Опустим сейчас (несуществующее) разделение на настоящий и ненастоящий фронтенд.

Вот это:

— Я умею нормально называть классы, они у меня всегда уникальные!

Окей, дай мне гарантию, что ты не ошибёшься на десятке страниц, нескольких десятках комбинаций компонентов и все твои коллеги такие же смышлёные. Ещё скажи, в композицию умеешь и специфичность на лету посчитаешь.

Ребят, штуки вроде пространств имён, БЭМ, OOCSS, CSS-in-JS, CSS modules появились не потому что их разработчики глупы или ленивы. Они появились потому что все мы люди и толпа может быть как умнее одного человека, так и бесконечно глупее. Ок, если не глупее, то, как минимум невнимательнее.

Ведь подобная ситуация она везде, не только в вёрстке.

Ну вот давайте возьмём для примера Next.js. За базу там взяты CSS-модули, поэтому уже один только этот факт делает вопрос: «А css-модули уже устарели, да?», — некорректным.

Да, «гладить» фреймворк против шерсти не стоит. Да, создать глобальный класс для компонента способом, не предусмотренным документацией (созданием отдельного глобального скоупа) будет проблемой (То же самое касается и css-in-js).

Но зато насколько легче решаются остальные 99% задач!

Короче, чтобы вам сегодня сделать своё понимание кода и его сборки чуть лучше и заодно понять сопутствующие проблемы CSS-модулей горячо рекомендую эту статью: https://habr.com/ru/post/688844/

Как включить их в сборку, как типизировать. Зачем вообще типизировать и как экспорты по умолчанию всё портят.

Прекрасно и максимально понятно написано. Заодно скилл вебпака подтянете :)

#css #cssmodules #webpack #бородач
👍101🥰1💩1
#заметка дня

Одна из самых раздражающих, хоть и по-своему логичных, вещей в CSS — это тот факт, что стили сопутствующих селекторов подключаются в порядке появления в CSS-файле, а не в порядке, определённом, например, классами или атрибутами.

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

Вот только в случае двух селекторов с одинаковой специфичностью, правила из того, что определены в файле ниже, победят.

Это, кстати, вполне себе одна из причин, почему атомарные классы набирают такую дикую популярность.

Короче, к моей проблеме. Я переписываю "классическое" веб-приложение на React. Таким образом, у меня уже имеется файл стилей, который я хочу использовать как базу. Естественно, я подключаю его в index.tsx:
import * as React from 'react';
import { App } from './App';
import '../src/scss/style.scss';


Мне кажется, с учётом введения вы уже поняли, в чём косяк. Стили, которые я использую в компонентах моего App успешно сбрасываются назад стилями из оригинального style.scss.

Как это победить? Вы не поверите, но в случае Webpack (у меня Rspack, но сути дела не меняет) не нужно ничего дописывать в конфигурации.

Нужно просто импортировать старые стили первыми. Кто бы мог подумать. Как-то так:

import '../src/scss/style.scss';
import * as React from 'react';
import { App } from './App';


Можете расчехлять помидоры, но, думаю, я оказался не один такой. Может кому ещё пригодится 🫠

#webpack #rspack #css
👍18
#видео дня


Итак, системы сборки проектов. Бандлеры, по простому. Старые и современные. От Webpack до OXC.

Зачем были нужны и как появились. Как развивались и при чём тут Rust. Почему oxc быстрее swc в пять раз, но это не всегда имеет значение.

На всё это отвечает Девон Говетт, создатель Parcel.js и разработчик проектов React Aria и React Spectrum в Adobe: https://www.youtube.com/watch?v=JUS6EPMbk0U&feature=youtu.be

Очень погружающая лекция, затрагивающая даже архитектуру проектов, чтобы было что сравнивать.

Если вы, котаны, запутались в JS-тулинге — вот самое оно.

#js #bundler #swc #webpack
👍171
#заметка дня

Сказ о том, как я Hot Module Reload в секьюрном iframe настраивал.

Итак, если вы на канале достаточно давно, то можете вспомнить, что продукт, над которым я работаю — это расширение для Google Sheets и работает оно в iframe. Довольно таки огороженном iframe.

Ну как, огороженном... Там довольно странная система из четырёх вложенных iframe, каждый из которых имеет довольно жёсткие скоупы.

И в итоге, такая простая вещь как Live Reload оказалась мне попросту недоступна!

Можете себе представить, как задалбывало перезапускать проект каждый раз, когда я что-то менял? А перезапуск — это секунд 10-15, даже если сборка почти моментальная.

Любая попытка сделать window.location.reload() не то чтобы по команде из Live Server-решения, но даже по кнопке — приводила к краху iframe и, соответственно, продукта.

Оставался только один вариант — Hot Module Replacement. Да, горячая перезагрузка компонентов с нами уже несколько лет, но для легаси-проектов это достаточно проблематично. И хоть я уже 2 года как перелез на https://rspack.dev/ (и дико доволен), использовать на полную катушку не выходило.

Как я справлялся?

А я запускал куски продукта в песочницах. Набрасывал моки и запускал блоки компонентов как обычное SPA-приложение. Не очень удобно? Не то слово. Зато очень быстро и легко покрывается тестами — потому что все моки уже на месте. Сплошные плюсы.

Но при работе в команде это всё максимально неудобно. В итоге всё же пришлось разбираться с HMR.

Итак, в чём же сложности?

1. Для начала, в Google Sheets нужно передать адрес, по которому будут грузиться данные. Нет, просто localhost нельзя, нужно сохранять возможность поделиться dev-средой, как обычной таблицей.

Решение — туннели (вроде ngrok) с прокидыванием локального домена (try_files в nginx) прямо к файлам сборки.

2. Естественно, данные должны грузиться по https. К счастью, туннели и это решают.

3. Не всем разработчикам в компании нужен HMR, им достаточно и простой сборки.

4. А вот что туннели решали с трудом — это прокидывание WebSocket. Именно по ним сборка и узнаёт, что пришло время обновиться. Я никак не мог понять, как же правильно поднять одновременно https и туннель, чтобы браузер не ругался на несекьюрный источник.

И тут до меня дошло: localhost же у нас по-соглашению всегда секьюрный. Поднимать на нём https не только не имеет смысла, но и браузерам абсолютно всё равно не несекьюрные данные оттуда!

Но был нюанс: если прописать localhost в конфиге webpack-dev-server (а Rspack использует именно его), то он просто... исчезал. Растворялся в basePath, указывая на текущую страницу (aka источник iframe). Что, конечно, меня не устраивало.

К счастью, решилось старым добрым 127.0.0.1.

В остальном же проблем не возникло: HMR прекрасно настроился по официальной документации с React Fast Refresh и получился следующий конфиг:

1. Три режима среды сборки: dev, none и production. Под none подразумевается дев-билд, без запуска сервера.

2. Туннели прокинуты до каталога build внутри репозитория и предоставляют доступ из открытого интернета по кастомному домену, с https на http.

3. webpack-dev-server настроен таким образом, что чанки с обновлениями сохраняются на диск и таким способом доставляются по адресу этого же тоннеля. Формат имён одинаков для сред dev и none.

4. CORS отключён ('Access-Control-Allow-Origin': '*'), и это пока мне не очень нравится.

5. WebSocket-соединение просто запущено на 127.0.0.1.

Таким образом, получился отличный универсальный способ!

Все разработчики компании без необходимости в HMR могут просто запустить локальный билд. А те, кому надо — запускают yarn dev и больше никакой дополнительной конфигурации не требуется.

А главное, за счёт скорости работы Rspack я могу смело указать несколько точек входа (entrypoints) и запускать независимые друг от друга части продукта с сохранением горячей перезагрузки.

Да, немного сумбурно вышло, и большинству такое в жизни не пригодится. Но если вдруг у вас возникнет такая же необходимость шарить dev-среду проекта наружу в открытую сеть — вы знаете, что делать.

#rspack #webpack #hmr
👍11🫡61
#ссылка дня

Сначала Bun сделал вызов Node.js и Deno, впихнув невпихуемое и сделав рантайм быстрым. Теперь он выходит на территорию фронтенд-сборщиков, где позиции Node.js и сопутствующих сборщиков казались весьма стабильными.

С Bun 1.3 можно сёрвить HTML-файлы напрямую, а JavaScript, TypeScript, JSX и CSS обрабатываются автоматически. Горячая перезагрузка позволяет видеть изменения мгновенно, а для проектов на React достаточно bun init --react, чтобы получить готовую среду. Сборка для продакшн стала проще: bun build --production оптимизирует проект без лишних конфигов.

Внутри появились новые возможности: поддержка MySQL наряду с PostgreSQL и SQLite, встроенный Redis-клиент, улучшенная маршрутизация, WebSocket, работа с cookies и новые механизмы изолированных установок пакетов. Всё это делает Bun 1.3 полноценной средой, где фронтенд, бэкенд и сборка объединены в одном инструменте.

Теперь Bun действительно бандлит, простите

https://bun.com/blog/bun-v1.3

#bun #node #bundle #webpack
119👎4👍3