— Не могу сейчас говорить, мой PR вмерживают в swc..
— Но ты же сам первый написал!
Поздравьте меня!
Теперь я frontops rust opensource good first issue developer💻
PS. Также сделал внутренний доклад про то, как написать простейший swc плагин. А когда появится свободное время, постараюсь написать в канал текстовую выжимку с некоторыми дополнениями, чтобы поделиться этим опытом и с вами.
— Но ты же сам первый написал!
Поздравьте меня!
Теперь я frontops rust opensource good first issue developer
PS. Также сделал внутренний доклад про то, как написать простейший swc плагин. А когда появится свободное время, постараюсь написать в канал текстовую выжимку с некоторыми дополнениями, чтобы поделиться этим опытом и с вами.
Please open Telegram to view this post
VIEW IN TELEGRAM
4❤71🔥55😁5👍2🫡1
Уверен, что вы не раз встречались с тем пониманием, что связка webpack и babel может работать или даже работает в вашем проекте медленно, причем, как правило, это какой-то legacy проект. Возможно вы пробовали ее ускорить, используя специальные комбинации опций, или возможно вы искали альтернативы.
Сейчас существует несколько альтернатив этой связке и кажется, что очень просто выбирать что-то из них. Например, вот есть интересное сравнение времени сборки, откуда выглядит так, что можно взять bun.sh и забыть про все проблемы. Однако, это если делать проект с нуля. А что если стоит вопрос миграции?
Какое бы решение вы не использовали, я предлагаю вам рассмотреть SWC. Этот инструмент выходит в состав компилятора фреймворка nextjs, бандлера parceljs и используется как основной loader в rspack, а также является частью архитектуры deno runtime.
SWC это компилятор из JavaScript и TypeScript в JavaScript (source-to-source компиляторы еще называют транспиляторами), поддерживает все proposals в stage 3 и preset-env, является непосредственно альтернативой babel и с некоторыми допущениями альтернативой tsc компилятору.
Миграция на babel согласно документации выглядит так:
На лендинге компилятора swc.rs сообщается, что инструмент даст безумный прирост скорости сборки проекта относительно babel — в 20 раз на одном потоке и быстрее в 70 раз на 4ых ядрах. Помимо этого компилятор еще и сравнительно хорошо минифицирует получившийся результат. На первый взгляд все выглядит превосходно. Ну а как еще продавать убийцу babel?
Правда, когда я тестировал скорость сборки проекта на случайном репозитории и заменил babel-loader на swc-loader в настройках webpack.config.js, то получил прирост намного скромнее, babel-loader ~1.5s против swc-loader 728 ms, измерял с помощью rsdoctor. Профит не такой уж и фантастический. Десятикратный рост скорости можно заметить, когда компилятор работает независимо, то есть без webpack. Например, вы тестируете трансформации плагинов на уровне JavaScript или разрабатываете библиотеки исключительно на swc (цифры про сборку библиотек, можно посмотреть в докладе Фёдора Сорокина про миграцию ВКонтакте на SWC по таймкоду, как и весь доклад целиком).
Вернусь к вопросу миграции на swc. У вас есть сборка, есть babel, у babel могут быть плагины — необходимо мигрировать и их. Конечно уже существуют некоторые аналоги babel плагинов под swc, но это буквально пара десятков. Если искать по топикам на github типа swc-plugin и babel-plugin, то можно получить репозиториев 58 versus 811 соответственно. К чему веду? Есть немалая вероятность, что вам придется писать плагин, но верьте мне на слово, что для больших проектов ваши усилия полностью окупятся.
Интересно продолжить тему swc?
Двадцать эмоджи ✍️ и будет еще один большой пост✍️
Сейчас существует несколько альтернатив этой связке и кажется, что очень просто выбирать что-то из них. Например, вот есть интересное сравнение времени сборки, откуда выглядит так, что можно взять bun.sh и забыть про все проблемы. Однако, это если делать проект с нуля. А что если стоит вопрос миграции?
Какое бы решение вы не использовали, я предлагаю вам рассмотреть SWC. Этот инструмент выходит в состав компилятора фреймворка nextjs, бандлера parceljs и используется как основной loader в rspack, а также является частью архитектуры deno runtime.
SWC это компилятор из JavaScript и TypeScript в JavaScript (source-to-source компиляторы еще называют транспиляторами), поддерживает все proposals в stage 3 и preset-env, является непосредственно альтернативой babel и с некоторыми допущениями альтернативой tsc компилятору.
Миграция на babel согласно документации выглядит так:
$ npx babel # old
$ npx swc # new
На лендинге компилятора swc.rs сообщается, что инструмент даст безумный прирост скорости сборки проекта относительно babel — в 20 раз на одном потоке и быстрее в 70 раз на 4ых ядрах. Помимо этого компилятор еще и сравнительно хорошо минифицирует получившийся результат. На первый взгляд все выглядит превосходно. Ну а как еще продавать убийцу babel?
Правда, когда я тестировал скорость сборки проекта на случайном репозитории и заменил babel-loader на swc-loader в настройках webpack.config.js, то получил прирост намного скромнее, babel-loader ~1.5s против swc-loader 728 ms, измерял с помощью rsdoctor. Профит не такой уж и фантастический. Десятикратный рост скорости можно заметить, когда компилятор работает независимо, то есть без webpack. Например, вы тестируете трансформации плагинов на уровне JavaScript или разрабатываете библиотеки исключительно на swc (цифры про сборку библиотек, можно посмотреть в докладе Фёдора Сорокина про миграцию ВКонтакте на SWC по таймкоду, как и весь доклад целиком).
Вернусь к вопросу миграции на swc. У вас есть сборка, есть babel, у babel могут быть плагины — необходимо мигрировать и их. Конечно уже существуют некоторые аналоги babel плагинов под swc, но это буквально пара десятков. Если искать по топикам на github типа swc-plugin и babel-plugin, то можно получить репозиториев 58 versus 811 соответственно. К чему веду? Есть немалая вероятность, что вам придется писать плагин, но верьте мне на слово, что для больших проектов ваши усилия полностью окупятся.
Интересно продолжить тему swc?
Двадцать эмоджи ✍️ и будет еще один большой пост
Please open Telegram to view this post
VIEW IN TELEGRAM
✍61👍9🔥6🤔1💯1
Написание плагинов для swc в отличие от babel требуют больше усилий, но по итогу дают существенный выигрыш в производительности, однако цена этому — минимальное владение rust. swc плагины пишутся на rust, компилируется в wasm, после подключаются в nodejs c помощью @swc/core или swc-loader в бандлере (также оберткой над @swc/core).
Напомню, что swc это компилятор из tsx/jsx в js. И если говорить совсем кратко, то плагины занимаются тем, что обрабатывают, полученное после парсинга AST-дерево, а также могут останавливать компиляцию, сообщая об ошибках. Чтобы было понятнее, давайте напишем максимально простой плагин, удаляющий из кода console.log.
Приготовления
Начнем с установки и настройки окружения:
Чтобы не писать с нуля, вызовем кодогенерацию:
В результате получим плагин, который ничего не делает,
И собирается в wasm,
Код этого шага: ufocoder/swc-plugin-example#713c951
Реализация трансформации
Перейдем к написанию трансформации. Первое с чего нужно начать — взять какой-нибудь код с использованием console.log и получить его AST представление, чтобы опередить от каких узлов мы хотим избавиться, например:
Далее, если изучить получившиеся AST-дерево в JSON-виде, то можно выделить, что вот такое поддерево описывает вызовы console.log, ниже представил в виде yaml:
Однако, мы хотим избавиться от этого поддерева, а значит нам нужно найти родительский узел и сделать трансформации относительного него. Также изучив AST дерево, мы определим, что это тип ExpressionStatement. Для этого типа узла необходимо реализовать обработку. Найдем метод в VisitMut трейте c похожим именем, и реализуем его для нашей структуры TransformVisitor, добавив немного паттерн-матчинга:
Если сравнивать с кодом реализации возможного babel плагина на JavaScript, то можно заметить, что на уровне идеи или подхода трансформации не отличается:
Код этого шага: ufocoder/swc-plugin-example#4c39886
Напомню, что swc это компилятор из tsx/jsx в js. И если говорить совсем кратко, то плагины занимаются тем, что обрабатывают, полученное после парсинга AST-дерево, а также могут останавливать компиляцию, сообщая об ошибках. Чтобы было понятнее, давайте напишем максимально простой плагин, удаляющий из кода console.log.
Приготовления
Начнем с установки и настройки окружения:
cargo install swc_cli # устанавливаем crate
rustup target add wasm32-wasip1 # для возможности сборки в wasm
Чтобы не писать с нуля, вызовем кодогенерацию:
swc plugin new --target-type wasm32-wasip1 swc-remove-console
В результате получим плагин, который ничего не делает,
src/lib.rs:// ..
pub struct TransformVisitor;
impl VisitMut for TransformVisitor {
// ..
}
#[plugin_transform]
pub fn process_transform(mut program: Program, _metadata: TransformPluginProgramMetadata) -> Program {
program.visit_mut_with(&mut TransformVisitor);
program
}
test_inline!(
Default::default(),
|_| visit_mut_pass(TransformVisitor),
boo,
r#"console.log("transform");"#,
r#"console.log("transform");"#
);
И собирается в wasm,
package.json:{
// ..
"scripts": {
"prepublishOnly": "cargo build-wasip1 --release"
},
// ..
}Код этого шага: ufocoder/swc-plugin-example#713c951
Реализация трансформации
Перейдем к написанию трансформации. Первое с чего нужно начать — взять какой-нибудь код с использованием console.log и получить его AST представление, чтобы опередить от каких узлов мы хотим избавиться, например:
function myFunction() {
console.log('test');
}
console.log('test');
myFunction();Далее, если изучить получившиеся AST-дерево в JSON-виде, то можно выделить, что вот такое поддерево описывает вызовы console.log, ниже представил в виде yaml:
type: CallExpression
callee:
type: MemberExpression
object:
type: Identifier
value: console
property:
type: Identifier
value: log
arguments:
- expression:
type: StringLiteral
value: test
Однако, мы хотим избавиться от этого поддерева, а значит нам нужно найти родительский узел и сделать трансформации относительного него. Также изучив AST дерево, мы определим, что это тип ExpressionStatement. Для этого типа узла необходимо реализовать обработку. Найдем метод в VisitMut трейте c похожим именем, и реализуем его для нашей структуры TransformVisitor, добавив немного паттерн-матчинга:
impl VisitMut for TransformVisitor {
fn visit_mut_stmt(&mut self, stmt: &mut Stmt) {
if let Stmt::Expr(expr_stmt) = stmt {
if let Expr::Call(call_expr) = &*expr_stmt.expr {
if is_console_call(&call_expr.callee) {
*stmt = Stmt::Empty(EmptyStmt { span: DUMMY_SP });
return;
}
}
}
}
}
fn is_console_call(callee: &Callee) -> bool {
if let Callee::Expr(expr) = callee {
if let Expr::Member(member_expr) = &**expr {
if let Expr::Ident(obj_ident) = &*member_expr.obj {
return obj_ident.sym == "console";
}
}
}
false
}Если сравнивать с кодом реализации возможного babel плагина на JavaScript, то можно заметить, что на уровне идеи или подхода трансформации не отличается:
module.exports = function() {
return {
visitor: {
CallExpression(path) {
const callee = path.node.callee;
if (callee.type === 'MemberExpression' &&
callee.object.type === 'Identifier' &&
callee.object.name === 'console' &&
callee.property.type === 'Identifier' &&
callee.property.name === 'log') {
path.remove();
}
}
}
};
};Код этого шага: ufocoder/swc-plugin-example#4c39886
👍8🔥7❤2
Реализация опций
Добавим в наш плагин возможность указывать какие методы из объекта console следует вырезать в коде через передаваемые в плагин опции. Выглядеть это будет так:
Swc плагин в функции, к которой применяем макрос
Код этого шага: ufocoder/swc-plugin-example#bcac4ea
Правда есть проблема и заключается в том, что плагин получает строку. Это означает, что плагин не может принимать в качестве опций callback функции и/или ссылки на JavaScript объекты извне. Если сравнить некоторые аналоги babel плагинов под swc, то можно увидеть, что там как раз таки отсутствует поддержка callback-функций.
Тестирование
Есть два уровня тестирования: можем писать тесты для трансформаций на rust с одной стороны и с другой стороны мы можем писать тесты на уровне JavaScript для скомпилированного в wasm и подключенного к swc плагина.
При тестировании на уровне rust проверяется как правило корректность самой трансформации AST-дерева. Используется макрос
Тестирование на уровне JavaScript, это проверка, что плагин скомпилирован под нужную версию swc_core, что он корректно принимает и обрабатывает опции, он корректно работает вместе со всеми встроенными в компилятор оптимизациями и другими подключенными вместе с ним плагинами. В качестве библиотек тестирования здесь могут использоваться известные всем jest или vitest.
Код этого шага: ufocoder/swc-plugin-example#499de4e
Заключение
Уверен, что этого минимума должно хватить, если вам вдруг придется писать плагины самостоятельно. Самое сложное здесь — это начать, потому что у swc очень скромная документация, но одновременно с этим емкая.
Идти глубже в устройство и работу swc придется, исключительно читая исходный код, чтобы, например: понять каким образом wasm плагины встраваются в swc, что именно, несмотря на компиляцию в wasm32-wasip1, ограничивает доступ к файловой системе, почему в проекте два runtime для wasm (wasmtime и wasmer), за счет чего происходит параллельная компиляция файлов и прочие тонкости. Но об этом возможно как-нибудь в другой раз.
Добавим в наш плагин возможность указывать какие методы из объекта console следует вырезать в коде через передаваемые в плагин опции. Выглядеть это будет так:
import { transformSync } from '@swc/core';
// ..
const { code } = transformSync(initialCode, {
jsc: {
target: 'es2020',
parser: {
syntax: 'ecmascript',
},
experimental: {
plugins: [
['@ufocoder/swc-plugin-example', {
methods: ['log', 'warn', 'info']
}]
]
}
}
});Swc плагин в функции, к которой применяем макрос
plugin_transform, через аргумент metadata имеет доступ к опциям, которые передаются извне, метод get_transform_plugin_config позволяет их получить. Опции передают в виде JSON строки, которую необходимо будет декодировать. Здесь придется описывать структуры, использовать для декодирования библиотеку serde_json. Также придется расширить ранее созданную структуру TransformVisitor, чтобы иметь доступ к декодированным опциям:pub struct PluginOptions {
#[serde(default = "default_methods")]
pub methods: MethodsOption,
}
#[serde(untagged)]
pub enum MethodsOption {
All,
List(Vec<String>),
}
// ..
pub struct TransformVisitor {
options: Options,
}
impl TransformVisitor {
pub fn new(options: Options) -> Self {
Self { options }
}
}
#[plugin_transform]
pub fn process_transform(
mut program: Program,
metadata: TransformPluginProgramMetadata
) -> Program {
let options = metadata
.get_transform_plugin_config()
.and_then(|config|
serde_json::from_str::<Options>(&config).ok())
.unwrap_or_default();
program.visit_mut_with(
&mut TransformVisitor::new(options)
);
program
}Код этого шага: ufocoder/swc-plugin-example#bcac4ea
Правда есть проблема и заключается в том, что плагин получает строку. Это означает, что плагин не может принимать в качестве опций callback функции и/или ссылки на JavaScript объекты извне. Если сравнить некоторые аналоги babel плагинов под swc, то можно увидеть, что там как раз таки отсутствует поддержка callback-функций.
Тестирование
Есть два уровня тестирования: можем писать тесты для трансформаций на rust с одной стороны и с другой стороны мы можем писать тесты на уровне JavaScript для скомпилированного в wasm и подключенного к swc плагина.
При тестировании на уровне rust проверяется как правило корректность самой трансформации AST-дерева. Используется макрос
test! из swc_core::ecma::transforms::testing. Результат работы макроса сравнивается с ранее созданными фикстурами в tests/__swc_snapshots__/src/tests.rs.Тестирование на уровне JavaScript, это проверка, что плагин скомпилирован под нужную версию swc_core, что он корректно принимает и обрабатывает опции, он корректно работает вместе со всеми встроенными в компилятор оптимизациями и другими подключенными вместе с ним плагинами. В качестве библиотек тестирования здесь могут использоваться известные всем jest или vitest.
Код этого шага: ufocoder/swc-plugin-example#499de4e
Заключение
Уверен, что этого минимума должно хватить, если вам вдруг придется писать плагины самостоятельно. Самое сложное здесь — это начать, потому что у swc очень скромная документация, но одновременно с этим емкая.
Идти глубже в устройство и работу swc придется, исключительно читая исходный код, чтобы, например: понять каким образом wasm плагины встраваются в swc, что именно, несмотря на компиляцию в wasm32-wasip1, ограничивает доступ к файловой системе, почему в проекте два runtime для wasm (wasmtime и wasmer), за счет чего происходит параллельная компиляция файлов и прочие тонкости. Но об этом возможно как-нибудь в другой раз.
1❤10👍8🔥4✍1
В посте выше обозначил такую проблему при работе с swc компилятором, как очень скромная документация (или ее отсутствие), и что необходимо читать исходники, чтобы собрать в голове архитектуру проекта, выделить используемые сущности и связи между ними, а все для того, чтобы понимать ограничения своих решений, написанных wasm-плагинов. А в прошлом мне потребовалось две пары выходных, чтобы прочитать код, прежде чем внести исправление и закрыть issue в swc.
Сейчас на досуге пытался понять почему в swc два runtime для wasm — wasmtime и wasmer. Быстро нашел ADR, в котором было указано, что wasmer был выбран как основной runtime для wasm-плагинов. Но если хочется узнать как он запускает wasm-плагины, как встраивается в компилятор — иди читай исходники.
Здесь мне помог проект deepwiki.com, который в ситуации подобной моей делает прекрасный onboarding: отвечает на вопросы, знакомит с основными частями кодовой базы и тем, как они связаны, рисует графики зависимостей, сопровождает свои ответы участками исходного кода. Более того он собирает лендинг с документацией на основе исходников, например, https://deepwiki.com/swc-project/swc
В общем, рекомендую приглядеться к deepwiki.com
Сейчас на досуге пытался понять почему в swc два runtime для wasm — wasmtime и wasmer. Быстро нашел ADR, в котором было указано, что wasmer был выбран как основной runtime для wasm-плагинов. Но если хочется узнать как он запускает wasm-плагины, как встраивается в компилятор — иди читай исходники.
Здесь мне помог проект deepwiki.com, который в ситуации подобной моей делает прекрасный onboarding: отвечает на вопросы, знакомит с основными частями кодовой базы и тем, как они связаны, рисует графики зависимостей, сопровождает свои ответы участками исходного кода. Более того он собирает лендинг с документацией на основе исходников, например, https://deepwiki.com/swc-project/swc
В общем, рекомендую приглядеться к deepwiki.com
1🔥17❤1
Канал и немного саморефлексии
В прошлом, когда канал добавили в папку каналов, посвященных фронтенду, пришло много подписчиков и количество подписок выросло до 3 тысяч. В связи с этим был проведен розыгрыш премиум подписок и на время розыгрыша откуда ни возьмись пришла еще тысяча подписчиков, которые также стремительно пропали после розыгрыша, как и появились. С тех пор кто-то подписывается, возможно случайно, кто-то отписывается, не найдя ничего про любимые фреймворки (они мне не интересны) — однако уже давно как нет гонки за числом подписчиков. Если автору телеграмм канала хочется славы, то телеграмм не лучше место для этого как по мне.
Канал посвящен исключительно (около) техническим темам. Посвящен тому, во что было бы интересно погрузиться самому или тому, что уже изучено и хочется зафиксировать этот опыт в виде заметки. Скорее всего, пока я продолжаю писать код, тематика и направленность канала будет сохраняться.
Вы когда-нибудь видели рекламу на канале? Я тоже. Были некоторые предложения о рекламе,слишком маленький чек, но не хочется навязывать то, во что сам не веришь или чего не знаешь. Возможно когда-нибудь вы увидите рекламу моего небольшого платного воркшопа по созданию чего-то с нуля, но это лишь планы. Иногда пиарю других ребят по доброй воле, и только потому что считаю их контент полезным и желаю поддержать автора.
Чего ждать? Вот некоторые профессиональные планы на самое ближайшее время, а именно то из-за чего будут или не будут выходить новые заметки:
— хочется зафиксировать в виде доклада или продолжить серию заметок о накопленном опыте в использовании rust, swc, rspack;
— сделать несколько сольных выпусков подкаста, пилотный выпуск похоже многим зашел;
— завершить объяснение, как написать DOOM с нуля с минимально-рабочими примерами, проложить свою дорожку, а не пройтись по чужой.
Конечно, что будет в будущем никто не знает. Лично у меня намеченные планы никогда не сбывались в полном обьеме, но будем стараться придерживать плана.
Спасибо, что продолжаете следить за каналом, читать мои заметки как разработчика! Для вас пытаюсь вытачивать каждую перед публикацией — все заметки крафтовые и пишутся без использования ИИ, а очепятки тому пример.
PS Если хотите поофтопить у нас есть небольшой ламповый чатик
В прошлом, когда канал добавили в папку каналов, посвященных фронтенду, пришло много подписчиков и количество подписок выросло до 3 тысяч. В связи с этим был проведен розыгрыш премиум подписок и на время розыгрыша откуда ни возьмись пришла еще тысяча подписчиков, которые также стремительно пропали после розыгрыша, как и появились. С тех пор кто-то подписывается, возможно случайно, кто-то отписывается, не найдя ничего про любимые фреймворки (они мне не интересны) — однако уже давно как нет гонки за числом подписчиков. Если автору телеграмм канала хочется славы, то телеграмм не лучше место для этого как по мне.
Канал посвящен исключительно (около) техническим темам. Посвящен тому, во что было бы интересно погрузиться самому или тому, что уже изучено и хочется зафиксировать этот опыт в виде заметки. Скорее всего, пока я продолжаю писать код, тематика и направленность канала будет сохраняться.
Вы когда-нибудь видели рекламу на канале? Я тоже. Были некоторые предложения о рекламе,
Чего ждать? Вот некоторые профессиональные планы на самое ближайшее время, а именно то из-за чего будут или не будут выходить новые заметки:
— хочется зафиксировать в виде доклада или продолжить серию заметок о накопленном опыте в использовании rust, swc, rspack;
— сделать несколько сольных выпусков подкаста, пилотный выпуск похоже многим зашел;
— завершить объяснение, как написать DOOM с нуля с минимально-рабочими примерами, проложить свою дорожку, а не пройтись по чужой.
Конечно, что будет в будущем никто не знает. Лично у меня намеченные планы никогда не сбывались в полном обьеме, но будем стараться придерживать плана.
Спасибо, что продолжаете следить за каналом, читать мои заметки как разработчика! Для вас пытаюсь вытачивать каждую перед публикацией — все заметки крафтовые и пишутся без использования ИИ, а очепятки тому пример.
PS Если хотите поофтопить у нас есть небольшой ламповый чатик
❤38👍22🔥10👏1🤝1
Про технический долг в бандлерах
Представьте себе абстрактную задачу
Дано: список хэш значений, он хранится у вас в файле или в памяти, есть список JavaScript файлов, в котором используется одно или несколько значений из списка выше
Необходимо: обновить указанное хэш-значение в списке и в файлах, где это хэш значение используется
В голову приходит сразу два решения. Первое решение это наивно найти подстроку в строке, другими словами в исходном коде, и заменить ее. Второй путь — это получить структуру AST дерева для каждого файла и искать по определенным типам узлов, брать значения этих узлов, сравнивать с искомым значением и делать замену.
Алгоритмическая сложность обхода строки и обхода по всем узлам AST-дерева O(n) по времени. Но очевидно, что для второго решения нужно еще построить то самое дерево, необходимо найти какой-то паттерн, где может лежать искомый хэш: может ли он быть частью математического выражения, является ли он ключом какого-то объекта, может ли он являться значением какого-то массива — в общем вариантом множество. Для второго решения нужны будут дополнительные вводные, как следствие код решения от каждого нового условия будет расти и более того потребуется дополнительная память.
Первое решение дешевле и легче. Попробуем им воспользоваться? Есть риск, что найдется какая-то часть кода похожая на хэш, но может хэшем не являться. Получим новый битый код или еще хуже рабочий синтаксически код, но с битой логикой. Пример, у вас хэш функция, которая на выходе отдает N-значное целое число, одновременно с этим в коде массив ID пользователей и вы по итогу меняете одного пользователя на другого по алгоритму замену строки. Как тестировать? Без знания контекста об этих ID никак. В результате терпим фиаско.
Теперь поговорим о фронтенд разработке. В декабрьских заметках обозначил, что существует тренд ухода от webpack. Так, например, ребята из Яндекса для некоторых проектов используют rspack. Rspack – бандлер написанный на rust, пытается быть совместимым с webpack и местами пытается повторять его поведение.
И в webpack и в rspack среди прочих настроек присутствует такая как output.realContentHash, которая говорит о том, что необходимо высчитывать обновленное значение хэш для чанка на основе контента, а затем делать замену в других чанках . Как происходит замена хэш значений? Вспомните задачу выше. Вот это оно и есть.
Исходники webpack: webpack/lib/optimize/RealContentHashPlugin.js
Исходники rspack: rspack/crates/rspack_plugin_real_content_hash/src/lib.rs
Webpack на мой взгляд взял технический долг и вместо честного анализа AST дерева и замены хэш значений проходится по исходному коду и меняет найденные подстроки на новые хэши на свой страх и риск. Rspack в свою очередь просто повторяет идею этого поведения, но со своей реализацией на другом языке. Правда в webpack используется md4, а в rspack md4, sha256, xxhash64 — чуть больше реализаций (если я не ошибся).
Тем не менее появляются вот такие issues:
https://github.com/web-infra-dev/rspack/issues/5339
https://github.com/web-infra-dev/rspack/issues/8474
Проблема может возникнуть в любом проекте с настройками из коробки, конечно это маловероятно, но поверьте мне на слово, когда это произойдет с вами, то будет очень неприятно. Вся эта ситуация напоминает отрывок из известного фильма с цитатами "Может бахнем?", "Обязательно бахнем, но потом".
Как от этого уберечься? Только пытаться уменьшить вероятность такой коллизии. Пытаться не использовать обрезанные значений хэш функций. Пытаться не использовать в исходном коде значения похожие на результаты хэширования. А пока так и живем.
Представьте себе абстрактную задачу
Дано: список хэш значений, он хранится у вас в файле или в памяти, есть список JavaScript файлов, в котором используется одно или несколько значений из списка выше
Необходимо: обновить указанное хэш-значение в списке и в файлах, где это хэш значение используется
В голову приходит сразу два решения. Первое решение это наивно найти подстроку в строке, другими словами в исходном коде, и заменить ее. Второй путь — это получить структуру AST дерева для каждого файла и искать по определенным типам узлов, брать значения этих узлов, сравнивать с искомым значением и делать замену.
Алгоритмическая сложность обхода строки и обхода по всем узлам AST-дерева O(n) по времени. Но очевидно, что для второго решения нужно еще построить то самое дерево, необходимо найти какой-то паттерн, где может лежать искомый хэш: может ли он быть частью математического выражения, является ли он ключом какого-то объекта, может ли он являться значением какого-то массива — в общем вариантом множество. Для второго решения нужны будут дополнительные вводные, как следствие код решения от каждого нового условия будет расти и более того потребуется дополнительная память.
Первое решение дешевле и легче. Попробуем им воспользоваться? Есть риск, что найдется какая-то часть кода похожая на хэш, но может хэшем не являться. Получим новый битый код или еще хуже рабочий синтаксически код, но с битой логикой. Пример, у вас хэш функция, которая на выходе отдает N-значное целое число, одновременно с этим в коде массив ID пользователей и вы по итогу меняете одного пользователя на другого по алгоритму замену строки. Как тестировать? Без знания контекста об этих ID никак. В результате терпим фиаско.
Теперь поговорим о фронтенд разработке. В декабрьских заметках обозначил, что существует тренд ухода от webpack. Так, например, ребята из Яндекса для некоторых проектов используют rspack. Rspack – бандлер написанный на rust, пытается быть совместимым с webpack и местами пытается повторять его поведение.
И в webpack и в rspack среди прочих настроек присутствует такая как output.realContentHash, которая говорит о том, что необходимо высчитывать обновленное значение хэш для чанка на основе контента, а затем делать замену в других чанках . Как происходит замена хэш значений? Вспомните задачу выше. Вот это оно и есть.
Исходники webpack: webpack/lib/optimize/RealContentHashPlugin.js
Исходники rspack: rspack/crates/rspack_plugin_real_content_hash/src/lib.rs
Webpack на мой взгляд взял технический долг и вместо честного анализа AST дерева и замены хэш значений проходится по исходному коду и меняет найденные подстроки на новые хэши на свой страх и риск. Rspack в свою очередь просто повторяет идею этого поведения, но со своей реализацией на другом языке. Правда в webpack используется md4, а в rspack md4, sha256, xxhash64 — чуть больше реализаций (если я не ошибся).
Тем не менее появляются вот такие issues:
https://github.com/web-infra-dev/rspack/issues/5339
https://github.com/web-infra-dev/rspack/issues/8474
Проблема может возникнуть в любом проекте с настройками из коробки, конечно это маловероятно, но поверьте мне на слово, когда это произойдет с вами, то будет очень неприятно. Вся эта ситуация напоминает отрывок из известного фильма с цитатами "Может бахнем?", "Обязательно бахнем, но потом".
Как от этого уберечься? Только пытаться уменьшить вероятность такой коллизии. Пытаться не использовать обрезанные значений хэш функций. Пытаться не использовать в исходном коде значения похожие на результаты хэширования. А пока так и живем.
👍18🔥10❤6
С наступающим 2026 годом и рождеством🎅
Желаю всем и каждому профессиональных успехов, счастья в личной жизни, здоровья и всего того, что сделает вас счастливее в этом новом году🎁
Также подготовил для вас несколько предсказаний.
Загадайте число от 1 до 10. Загадали? А теперь открывайте:
1) Тебя не заменит ИИ, потому что ты незаменимый
2) Станешь амбассадор бигтех компании
3) Уйдешь в тимлиды и будешь меньше писать кода
4) Когда ты положишь production, никто не заметит, потому что это будет stage
5) У тебя будет 50 pull request'ов, которые пройдут review с первого раза
6) Тебя повысят в компании
7) Сможешь пропускать встречи и созвоны на протяжении месяца
8) Получишь известность и признание в сообществе
9) Следующий проект будет на технологиях, которые выберешь ты
10) Сможешь отложить дедлайн на 2 месяца
Желаю всем и каждому профессиональных успехов, счастья в личной жизни, здоровья и всего того, что сделает вас счастливее в этом новом году
Также подготовил для вас несколько предсказаний.
Загадайте число от 1 до 10. Загадали? А теперь открывайте:
2) Станешь амбассадор бигтех компании
3) Уйдешь в тимлиды и будешь меньше писать кода
4) Когда ты положишь production, никто не заметит, потому что это будет stage
5) У тебя будет 50 pull request'ов, которые пройдут review с первого раза
6) Тебя повысят в компании
7) Сможешь пропускать встречи и созвоны на протяжении месяца
8) Получишь известность и признание в сообществе
9) Следующий проект будет на технологиях, которые выберешь ты
10) Сможешь отложить дедлайн на 2 месяца
Please open Telegram to view this post
VIEW IN TELEGRAM
5🎄19❤9👍3
Frontend CTF 2026
Ранее на канале писал, что в этом году будет несколько поводов взять паузу в написании заметок и вот создание CTF для Frontend-разработчиков как раз и послужила первой такой паузой. Несколько лет подряд мы с ребятами создаем Frontend CTF и уже устали считать сколько их было проведено, поэтому пришлось сделать лендинг, на котором можно посмотреть прошлогодние игры и вспомнить победителей прошлых лет.
В одной из следующих заметок расскажу о том, как появилась эта активность, как создается и за счет чего и на чем держится. Знаю, большие текста вы любите читать, а я писать. А пока анонс:
Запуск сегодня в 18:47 (по мск) Frontend CTF 2026
Запуск сегодня в 18:47 (по мск) Frontend CTF 2026
Запуск сегодня в 18:47 (по мск) Frontend CTF 2026
А это уже практически через 1 час⏳
Чат участников - @yalovefrontend_ctf
— Слушай, а почему ты меня не спрашиваешь - где ты пропадал все это время?
— Где ты пропадал-то все это время?
Малыш и Карлсон
Ранее на канале писал, что в этом году будет несколько поводов взять паузу в написании заметок и вот создание CTF для Frontend-разработчиков как раз и послужила первой такой паузой. Несколько лет подряд мы с ребятами создаем Frontend CTF и уже устали считать сколько их было проведено, поэтому пришлось сделать лендинг, на котором можно посмотреть прошлогодние игры и вспомнить победителей прошлых лет.
В одной из следующих заметок расскажу о том, как появилась эта активность, как создается и за счет чего и на чем держится. Знаю, большие текста вы любите читать, а я писать. А пока анонс:
Запуск сегодня в 18:47 (по мск) Frontend CTF 2026
Запуск сегодня в 18:47 (по мск) Frontend CTF 2026
Запуск сегодня в 18:47 (по мск) Frontend CTF 2026
А это уже практически через 1 час
Чат участников - @yalovefrontend_ctf
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16❤3👍3
UfoStation
Заметки на полях – Пилотный выпуск
Есть желание рассказать немного про CTF и в частности про Frontend CTF в аудиоформате, то есть записать подкаст.
Было бы интересно послушать? 30 положительных ответов и иду готовить выпуск
Было бы интересно послушать? 30 положительных ответов и иду готовить выпуск
Anonymous Poll
70%
Да
12%
Нет
19%
Мяу
Воспоминания о CTF
Заметки на полях
Заметки на полях
Воспоминания о CTF
00:00 История CTF
04:31 Виды соревнований
09:13 Первый опыт
13:12 Организую свои CTF
16:17 Frontend CTF
Небольшая рефлексия на прошлое и личный скромный CTF опыт. Надеюсь выпуск понравится тем, кто только знакомится с этим движением и тем, кому интересны скромные мемуары очередного веб-разработчика, свернувшего с пути ИБ
Слушать через веб-сайт
Воспоминания о CTF
00:00 История CTF
04:31 Виды соревнований
09:13 Первый опыт
13:12 Организую свои CTF
16:17 Frontend CTF
Небольшая рефлексия на прошлое и личный скромный CTF опыт. Надеюсь выпуск понравится тем, кто только знакомится с этим движением и тем, кому интересны скромные мемуары очередного веб-разработчика, свернувшего с пути ИБ
Слушать через веб-сайт
🔥8👍5❤1
Референсы ко второму выпуску подкаста
История соревнований Capture The Flag в России и мире, статья
RuCTF 2008 - первые всероссийские соревнования
CTFtime - агрегатор и хаб для международных соревнований
FCTF #3 - сохранившийся CTF для локального JS сообщества
Frontend CTF - в рамках Я 💛 Фронтенд (первый CTF c Мона Лизой)
История соревнований Capture The Flag в России и мире, статья
RuCTF 2008 - первые всероссийские соревнования
CTFtime - агрегатор и хаб для международных соревнований
FCTF #3 - сохранившийся CTF для локального JS сообщества
Frontend CTF - в рамках Я 💛 Фронтенд (первый CTF c Мона Лизой)
🔥6
Forwarded from 💻 Coding interviews in a nutshell
Всем привет! 👋
Вместо Advent of Code в декабре устроил себе небольшой Advent of Vibecode и сделал https://systemdesigntrainer.com/ — кому актуально, кто готовится к секции по системному дизайну сейчас, пожалуйста, велком в бету. 🚀
Какую проблему решает сервис 👇
Зачастую системный дизайн заваливают не потому, что не знают, как делать бэкенд (нормальная ситуация: когда 10 лет программируешь, потом идёшь на собес и заваливаешь его), а потому что не знакомы с форматом интервью. Этапы: сбор требований, back-of-the-envelope, high-level дизайн, модель данных, deep dive и так далее. Либо слишком быстро уходят в детали, не уточнив требования, либо, напротив, долго ходят по кругу, когда уже прошла половина интервью.
https://app.systemdesigntrainer.com — это тренажёр, чтобы набить руку: укладываться в формат и тайминг, вспомнить основные концепции и диаграммы порисовать, все как на настоящем интервью. По ходу интервью собираются сигналы (как бы это делал живой интервьюер), в конце выдаётся фидбек (как на мок-интервью).
Вместо Advent of Code в декабре устроил себе небольшой Advent of Vibecode и сделал https://systemdesigntrainer.com/ — кому актуально, кто готовится к секции по системному дизайну сейчас, пожалуйста, велком в бету. 🚀
Какую проблему решает сервис 👇
Зачастую системный дизайн заваливают не потому, что не знают, как делать бэкенд (нормальная ситуация: когда 10 лет программируешь, потом идёшь на собес и заваливаешь его), а потому что не знакомы с форматом интервью. Этапы: сбор требований, back-of-the-envelope, high-level дизайн, модель данных, deep dive и так далее. Либо слишком быстро уходят в детали, не уточнив требования, либо, напротив, долго ходят по кругу, когда уже прошла половина интервью.
https://app.systemdesigntrainer.com — это тренажёр, чтобы набить руку: укладываться в формат и тайминг, вспомнить основные концепции и диаграммы порисовать, все как на настоящем интервью. По ходу интервью собираются сигналы (как бы это делал живой интервьюер), в конце выдаётся фидбек (как на мок-интервью).
Systemdesigntrainer
AI System Design Mock Interview Simulator | Practice Free | AI Mock System Design
AI-powered system design mock interviews with instant feedback. Realistic FAANG scenarios, expert evaluation on every architecture decision. Start free — no credit card required.
❤2
👆Один знакомый, мы кстати с ним делали выпуск подкаста про FAANG, сделал в прошлом проект и хотел бы получить обратную связь по нему, чтобы вы его поругали или похвалили
Telegram
UfoStation
s03e04: FAANG, алгоритмы и собеседования
Гости выпуска
Виктор Карпов, Software Engineer & Educator:
- Twitter аккаунт
- Youtube канал. Алгосики для самых маленьких
- Coding interviews in a nutshell
Содержание выпуска
00:00:44 Знакомство с гостем
00:07:40…
Гости выпуска
Виктор Карпов, Software Engineer & Educator:
- Twitter аккаунт
- Youtube канал. Алгосики для самых маленьких
- Coding interviews in a nutshell
Содержание выпуска
00:00:44 Знакомство с гостем
00:07:40…
🔥4✍1
This media is not supported in your browser
VIEW IN TELEGRAM
Какие три слова хочет услышать докладчик?
Твой доклад принят 👍
Последующие 3 месяца будут посты исключительно с фиксацией некоторых идей и опыта вокруг и про создание DOOM-like игры или не будет постов совсем (потому что будет просто некогда), а все потому что мне одобрили выступление на CodeFest.
PS. В видео выше умельцы запустилиdoom-like wolfenstein3d-like игру на бумаге
Последующие 3 месяца будут посты исключительно с фиксацией некоторых идей и опыта вокруг и про создание DOOM-like игры или не будет постов совсем (потому что будет просто некогда), а все потому что мне одобрили выступление на CodeFest.
PS. В видео выше умельцы запустили
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥23👍2
Forwarded from Front-End Engineer Blog (Evgenii Ray)
Frontend Interview - Intensive course - Live event 🚀
Всем привет!
Последние последний год, пока я готовился к интервью к различным компаниям (HFT / Finance / FAANG) , накопилось много фронтенд задач, которыми я так и не поделился, просто из-за нехватки времени. Мне хотелось представить их в более менее структурированном формате, чтобы люди могли получить максимальную пользу. Поэтому я решил записать курс по подготовке к кодинг интервью и я снова сколлаборировался с FrontendMaster, так как курс по Системному дизайну вышел очень удачным.
18-19 Марта, в 14.00 по Лондону, приходите на бесплатный двухдневный стрим, где мы в течении 12ти часов решим самые интересные и часто встречаемые задачи с фронтенд интервью
Будем очень очень много кодить крафтово и без АИ агентов! В сумме решим около 60ти задачек и даже напишем свой небольшой клон Google Sheet.
Стрим бесплатный, подписка не нужна. Задачи будут также доступны на гитхабе, где ты можешь можешь скачать репу и решить все сам.
-----
Hi everyone!
Over the past year, while preparing for interviews with various companies (HFT / Finance / FAANG), I accumulated a lot of frontend interview problems that I never shared—mostly due to lack of time. I wanted to present them in a more structured format so people could get the most value from them.
So I decided to record a course on coding interview preparation, and I’ve collaborated again with Frontend Masters, since our System Design course turned out to be very successful.
On March 18–19 at 14:00 London time, join us for a free two-day livestream where, over the course of 12 hours, we’ll solve some of the most interesting and frequently asked frontend interview problems.
We’ll do a lot of hands-on coding—craft-style and without AI agents! In total, we’ll solve around 60 problems, and even build a small Google Sheets clone.
The stream is completely free, and no subscription is required. The problems will also be available on GitHub, so you can download the repository and solve everything on your own.
Всем привет!
Последние последний год, пока я готовился к интервью к различным компаниям (HFT / Finance / FAANG) , накопилось много фронтенд задач, которыми я так и не поделился, просто из-за нехватки времени. Мне хотелось представить их в более менее структурированном формате, чтобы люди могли получить максимальную пользу. Поэтому я решил записать курс по подготовке к кодинг интервью и я снова сколлаборировался с FrontendMaster, так как курс по Системному дизайну вышел очень удачным.
18-19 Марта, в 14.00 по Лондону, приходите на бесплатный двухдневный стрим, где мы в течении 12ти часов решим самые интересные и часто встречаемые задачи с фронтенд интервью
Будем очень очень много кодить крафтово и без АИ агентов! В сумме решим около 60ти задачек и даже напишем свой небольшой клон Google Sheet.
Стрим бесплатный, подписка не нужна. Задачи будут также доступны на гитхабе, где ты можешь можешь скачать репу и решить все сам.
-----
Hi everyone!
Over the past year, while preparing for interviews with various companies (HFT / Finance / FAANG), I accumulated a lot of frontend interview problems that I never shared—mostly due to lack of time. I wanted to present them in a more structured format so people could get the most value from them.
So I decided to record a course on coding interview preparation, and I’ve collaborated again with Frontend Masters, since our System Design course turned out to be very successful.
On March 18–19 at 14:00 London time, join us for a free two-day livestream where, over the course of 12 hours, we’ll solve some of the most interesting and frequently asked frontend interview problems.
We’ll do a lot of hands-on coding—craft-style and without AI agents! In total, we’ll solve around 60 problems, and even build a small Google Sheets clone.
The stream is completely free, and no subscription is required. The problems will also be available on GitHub, so you can download the repository and solve everything on your own.
Frontendmasters
Interviewing for Front-End Engineers, v2 — Exclusive Workshop
Spend two full days with Evgenii Ray learning the skills and techniques to ace front-end engineering interviews.
✍5❤5🤔2
cssDOOM
На днях вышел проект, который попытался воссоздать в браузере оригинальный DOOM 1993 года, судя по популярной карте, и перенести всю отрисовку в CSS.
Играть в браузере
Исходники на github
На днях вышел проект, который попытался воссоздать в браузере оригинальный DOOM 1993 года, судя по популярной карте, и перенести всю отрисовку в CSS.
Играть в браузере
Исходники на github
❤2👍2🥱1
Однако проект выше не является клоном doom и не воссоздает оригинальный отрисовщик, разберем почему?
Anonymous Poll
65%
Да, подушним по полной
35%
Нет, порадуемся за автора и оставим его в покое