Про фикс NODE_OPTIONS=--openssl-legacy-provider
У меня на работе в каждом втором проекте, который использует Node.js 17+, добавлен этот параметр при запуске
Начнём с того, что если убрать
Проблема появилась, когда Node.js 17 решили переехать на новую версию библиотеки OpenSSL. Её версия 3.0 использует новые методы шифрования, а многие старые методы (например, md4) оказались неподдерживаемыми.
В свою очередь, на методах из OpenSSL основана и Node.js библиотека crypto (мы можем увидеть её упоминание в самом коде ошибки).
А тут уже Webpack, и некоторые другие библиотеки, особенно устаревших версий, могут использовать старые алгоритмы шифрования из crypto. Далеко ходить не надо, вот ишью в Webpack 5 про использование md4.
Получается такая цепочка:
→ мы на нашем проекте используем, например, webpack
→ он использует алгоритм шифрования md4 из встроенной Node.js-библиотеки crypto
→ сам Node.js уже использует OpenSSL версии 3.0, а поэтому и md4 в crypto больше не работает
→ ловим ошибку при попытке собрать приложение
Если бы команда Node.js в свое время выкатила релиз без возможности поддержки старых инструментов, то у нас бы сломалось пол интернета. Поэтому они, конечно, предусмотрели фикс - та самая опция
или через специальный параметр, как встречается чаще всего:
Но конечно, лучше всего отказываться или обновлять библиотеки, которые требуют устаревший алгоритм (+1 причина переходить с Webpack на Vite)))
У меня на работе в каждом втором проекте, который использует Node.js 17+, добавлен этот параметр при запуске
npm run build
или pnpm run dev
. Хочется понять, что же он значит, а значит, пришло время покопаться.Начнём с того, что если убрать
NODE_OPTIONS=--openssl-legacy-provider
, то приложение может упасть с такой ошибкой:
error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:69:19)
at Object.createHash (node:crypto:133:10)
Проблема появилась, когда Node.js 17 решили переехать на новую версию библиотеки OpenSSL. Её версия 3.0 использует новые методы шифрования, а многие старые методы (например, md4) оказались неподдерживаемыми.
В свою очередь, на методах из OpenSSL основана и Node.js библиотека crypto (мы можем увидеть её упоминание в самом коде ошибки).
А тут уже Webpack, и некоторые другие библиотеки, особенно устаревших версий, могут использовать старые алгоритмы шифрования из crypto. Далеко ходить не надо, вот ишью в Webpack 5 про использование md4.
Получается такая цепочка:
→ мы на нашем проекте используем, например, webpack
→ он использует алгоритм шифрования md4 из встроенной Node.js-библиотеки crypto
→ сам Node.js уже использует OpenSSL версии 3.0, а поэтому и md4 в crypto больше не работает
→ ловим ошибку при попытке собрать приложение
Если бы команда Node.js в свое время выкатила релиз без возможности поддержки старых инструментов, то у нас бы сломалось пол интернета. Поэтому они, конечно, предусмотрели фикс - та самая опция
--openssl-legacy-provider
, которая позволяет использовать Legacy версию OpenSSL. Мы можем или добавить опцию сразу в консольную команду:
node --openssl-legacy-provider server.js
или через специальный параметр, как встречается чаще всего:
NODE_OPTIONS=--openssl-legacy-provider npm run build
Но конечно, лучше всего отказываться или обновлять библиотеки, которые требуют устаревший алгоритм (+1 причина переходить с Webpack на Vite)))
👍1
Недавно джавист спросил меня: "А в чём вообще проблема использования
Почему var считается устаревшим?
Когда в ES6 в 2015 году появились
1. var живёт в рамках функции, а не блока
Если объявить
2. var поднимается (hoisting), но остаётся undefined
Переменные, объявленные через
Такое поведение, что в первом, что во втором случае, очень нетипично для большинства языков программирования и в частности поэтому может запутать.
Почему работу с var не исправили сразу, как заметили проблемы?
Когда JavaScript создавался в 1995 году, он задумывался как язык для небольших скриптов, которые просто добавляли интерактивность на веб-страницы. Никто не думал, что на нем будут писать сложные приложения с десятками тысяч строк кода. Поэтому такие вещи, как
В ES6 наконец-то добавили
К слову, может показаться, что особенности
В общем-то, JS менялся и продолжает меняться под давлением времени, и отказ от
var
в JavaScript?". Я на автомате ответила что-то про замыкания, но потом поняла, что конкретику-то уже подзабыла. А значит, как я люблю, самое время покопаться и вспомнить, что же с ним не так.Почему var считается устаревшим?
Когда в ES6 в 2015 году появились
let
и const
, почти весь мир фронтенда перешёл на них. Но var
никуда не делся и до сих пор встречается в старом коде. Почему же все от него отказались?1. var живёт в рамках функции, а не блока
Если объявить
var
внутри if
, for
или `{}`-блока, он доступен во всей функции, а если функция не задана – в глобальной области видимости.
function example() {
if (true) {
var message = "Hello";
}
console.log(message); // "Hello"
}
example();
2. var поднимается (hoisting), но остаётся undefined
Переменные, объявленные через
var
, поднимаются в начало функции и принимают значение undefined
, если к ним обратиться до объявления.
console.log(user); // undefined
var user = "Cat";
Такое поведение, что в первом, что во втором случае, очень нетипично для большинства языков программирования и в частности поэтому может запутать.
Почему работу с var не исправили сразу, как заметили проблемы?
Когда JavaScript создавался в 1995 году, он задумывался как язык для небольших скриптов, которые просто добавляли интерактивность на веб-страницы. Никто не думал, что на нем будут писать сложные приложения с десятками тысяч строк кода. Поэтому такие вещи, как
var
с функциональной областью видимости, не казались проблемой – ведь весь скрипт обычно находился в одном файле и выполнялся сверху вниз. Но затем веб-разработка начала усложняться. JS стал полноценным языком для больших приложений, а старые решения начали тянуть за собой ошибки.В ES6 наконец-то добавили
let
и const
, чтобы исправить проблемы var
, но полностью убрать или изменить принцип его работы было невозможно. JavaScript выполняется на машинах пользователей, а браузеры у всех разные – кто-то сидит на новой версии Chrome, а кто-то на старом IE. В отличие от компилируемых языков, где ты контролируешь, какая версия используется, в вебе это сделать невозможно. Поэтому var
остался в языке таким, какой он есть, ради обратной совместимости.К слову, может показаться, что особенности
var
– это только источник багов, но в некоторых случаях это удобно. Например, hoisting
позволяет вызывать функции до их объявления.В общем-то, JS менялся и продолжает меняться под давлением времени, и отказ от
var
– одна из тех вещей, которые сделали разработку на этом языке чуть предсказуемее.👍2
Как я переношу проект с Webpack 4 на Vite
Сейчас на работе мы обновляем один старый проект и решили мигрировать его с Webpack 4 на последний Vite. В два этапа: сначала dev-сборку, потом уже продакшен.
Дано
• Проект на Webpack 4, dev- и прод-сборки собираются одной конфигурацией.
• Нужно перенести dev-сборку на Vite, а прод оставить на Webpack.
• У проекта кастомный сервер на Express, который сам отдаёт HTML.
• Vite же по умолчанию использует свой собственный HTML.
1. process.env
Первым делом выяснилось, что Vite не понимает process.env (что, в целом, логично), а у нас этого добра в коде много, и менять каждый экземпляр вручную не хочется. Помог vite-plugin-environment.
2. require()
В коде использовался require() для импорта переводов и языков в highlight.js, а Vite его не поддерживает. Решила заменить на import.iss.oneta.glob() – он как раз умеет динамически подгружать файлы! Но… Webpack 4 не поддерживает import.iss.oneta.glob(), и в прод-сборке всё снова сломалось. -_-
В итоге спасло третье решение:
• Для переводов – передаю данные сразу с сервера через тег в HTML.
• Для highlight.js – пока вручную использую await import, подгружаю все нужные языки. После отказа от Webpack можно будет переехать на import.iss.oneta.glob().
3. moment.js
Старая сборка прекрасно работала с moment.js и специальными плагинами для импорта локалей и таймзон, но с Vite они так себе друзья, и заставить его подгружать всё нужное оказалось нетривиальной задачей.
Решение:
• Добавила ручной импорт локали там, где это необходимо (import 'moment/dist/locale/ru'; moment.locale('ru');).
• Но перед окончательным переходом на Vite в проде хочется полностью отказаться от moment.js и связанных с ним компонентов (react-datetime).
Выводы
Если хотите перенести dev-сборку с Webpack 4 на Vite, обратите внимание на эти вещи:
• process.env в Vite по дефолту не работает – нужен либо import.iss.oneta.env, либо плагин.
• Если в коде есть require(), Webpack и Vite не договорятся – придётся искать обходные пути.
• moment.js + Vite могут создать проблемы с локалями и таймзонами, их нужно загружать вручную.
P.S. Пока я разбиралась с этой задачей, впервые на полную использовала ChatGPT (да-да, только сейчас, в 2025-м!))). Я постоянно загружала в него ошибки, с которыми сталкивалась, и решения, которые в итоге помогли (не обязательно из его предложенных).
Отчасти благодаря этому и родился этот пост – как эксперимент. Его мне помог написать чат, имея всю предыдущую информацию. Опыт интересный, но рассказ о формате лично моего взаимодействия с ChatGPT лучше вынести в отдельный пост)
Сейчас на работе мы обновляем один старый проект и решили мигрировать его с Webpack 4 на последний Vite. В два этапа: сначала dev-сборку, потом уже продакшен.
Дано
• Проект на Webpack 4, dev- и прод-сборки собираются одной конфигурацией.
• Нужно перенести dev-сборку на Vite, а прод оставить на Webpack.
• У проекта кастомный сервер на Express, который сам отдаёт HTML.
• Vite же по умолчанию использует свой собственный HTML.
1. process.env
Первым делом выяснилось, что Vite не понимает process.env (что, в целом, логично), а у нас этого добра в коде много, и менять каждый экземпляр вручную не хочется. Помог vite-plugin-environment.
2. require()
В коде использовался require() для импорта переводов и языков в highlight.js, а Vite его не поддерживает. Решила заменить на import.iss.oneta.glob() – он как раз умеет динамически подгружать файлы! Но… Webpack 4 не поддерживает import.iss.oneta.glob(), и в прод-сборке всё снова сломалось. -_-
В итоге спасло третье решение:
• Для переводов – передаю данные сразу с сервера через тег в HTML.
• Для highlight.js – пока вручную использую await import, подгружаю все нужные языки. После отказа от Webpack можно будет переехать на import.iss.oneta.glob().
3. moment.js
Старая сборка прекрасно работала с moment.js и специальными плагинами для импорта локалей и таймзон, но с Vite они так себе друзья, и заставить его подгружать всё нужное оказалось нетривиальной задачей.
Решение:
• Добавила ручной импорт локали там, где это необходимо (import 'moment/dist/locale/ru'; moment.locale('ru');).
• Но перед окончательным переходом на Vite в проде хочется полностью отказаться от moment.js и связанных с ним компонентов (react-datetime).
Выводы
Если хотите перенести dev-сборку с Webpack 4 на Vite, обратите внимание на эти вещи:
• process.env в Vite по дефолту не работает – нужен либо import.iss.oneta.env, либо плагин.
• Если в коде есть require(), Webpack и Vite не договорятся – придётся искать обходные пути.
• moment.js + Vite могут создать проблемы с локалями и таймзонами, их нужно загружать вручную.
P.S. Пока я разбиралась с этой задачей, впервые на полную использовала ChatGPT (да-да, только сейчас, в 2025-м!))). Я постоянно загружала в него ошибки, с которыми сталкивалась, и решения, которые в итоге помогли (не обязательно из его предложенных).
Отчасти благодаря этому и родился этот пост – как эксперимент. Его мне помог написать чат, имея всю предыдущую информацию. Опыт интересный, но рассказ о формате лично моего взаимодействия с ChatGPT лучше вынести в отдельный пост)
🔥2👍1🥴1
Когда-нибудь замечали в HTML что-то вроде
Nonce – это одноразовый токен, который помогает защитить сайт от XSS-атак. Когда на сайте используется механизм CSP (Content Security Policy), браузер по умолчанию блокирует все inline-скрипты. Но если очень хочется использовать их, можно, вместо указания директивы
Пример CSP-заголовка:
Теперь в коде можно использовать:
Обычно nonce создаётся для каждого запроса отдельно и передаётся в шаблон, чтобы его можно было подставить в скрипты.
Пример для Express:
Теперь каждый запрос получает новый nonce, который передаётся в CSP-заголовке и также вставляется в HTML. Это позволяет безопасно использовать inline-скрипты, не открывая сайт для XSS.
<script nonce="abc123">
?Nonce – это одноразовый токен, который помогает защитить сайт от XSS-атак. Когда на сайте используется механизм CSP (Content Security Policy), браузер по умолчанию блокирует все inline-скрипты. Но если очень хочется использовать их, можно, вместо указания директивы
unsafe-inline
(которая будет разрешать любые такие скрипты), добавить nonce, который заранее прописан в заголовках ответа сервера. Тогда браузер выполнит только те скрипты, у которых этот токен правильный.Пример CSP-заголовка:
Content-Security-Policy: script-src 'nonce-abc123'
Теперь в коде можно использовать:
<script nonce="abc123">console.log('Безопасный JS');</script>
<script nonce="efg567">console.log('Будет заблокирован');</script>
Обычно nonce создаётся для каждого запроса отдельно и передаётся в шаблон, чтобы его можно было подставить в скрипты.
Пример для Express:
app.use((req, res, next) => {
// Генерируем nonce
res.nonce = crypto.randomBytes(16).toString('base64');
// Устанавливаем CSP-заголовок
res.setHeader('Content-Security-Policy', `script-src 'nonce-${res.nonce}'`);
next();
});
app.get('/', (req, res) => {
res.send(`
<html>
...
<script nonce="${res.nonce}">
console.log('Этот скрипт выполнится');
</script>
</html>
`);
});
Теперь каждый запрос получает новый nonce, который передаётся в CSP-заголовке и также вставляется в HTML. Это позволяет безопасно использовать inline-скрипты, не открывая сайт для XSS.
🔥3
#startpoint_dev_nodejs
Как-то вечером я задумалась: мне ведь нравится Node.js, но я знаю о нём далеко не всё. Так зародилась идея копнуть глубже — разобраться в таинственных механизмах, которые заставляют эту систему работать на благо разработчиков.
Поэтому приглашаю вас в увлекательное путешествие по просторам вечных циклов макро- и микротасок, setTimeout-ов и nextTick-ов. Мы будем постепенно погружаться, в частности, в работу Event Loop — от базового “что это вообще такое” до фундаментальных вещей, на которых строится Node.js.
P. S. Я пишу эти посты прямо сейчас и, как истинный писатель, сама не знаю, куда заведёт меня эта история и чем закончится путь её героев. Так что если у вас есть интересные темы или экзистенциальные вопросы про Node.js — пишите, будем разбираться вместе!)
Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер.
Как-то вечером я задумалась: мне ведь нравится Node.js, но я знаю о нём далеко не всё. Так зародилась идея копнуть глубже — разобраться в таинственных механизмах, которые заставляют эту систему работать на благо разработчиков.
Поэтому приглашаю вас в увлекательное путешествие по просторам вечных циклов макро- и микротасок, setTimeout-ов и nextTick-ов. Мы будем постепенно погружаться, в частности, в работу Event Loop — от базового “что это вообще такое” до фундаментальных вещей, на которых строится Node.js.
P. S. Я пишу эти посты прямо сейчас и, как истинный писатель, сама не знаю, куда заведёт меня эта история и чем закончится путь её героев. Так что если у вас есть интересные темы или экзистенциальные вопросы про Node.js — пишите, будем разбираться вместе!)
Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер.
Telegraph
Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер.
Вопрос c собеседований Наверняка, вы не раз слышали один из любимых вопросов интервьюеров: “Расскажите про Event Loop в JavaScript”. Как правило, речь идёт про браузерную версию JavaScript. И если нужен простой ответ, он может звучать так:
👍4
Я долго к этому шла и наконец пришла!
Первое (и я надеюсь, не последнее) мое выступление в этом году как спикера. На митапе MinskJS я буду рассказывать про пугающую ошибку с node-gyp, как её одолеть и прийти к победе.
Подключайтесь в эту среду сюда 👉 https://youtube.com/live/ILRrXYSthsA
(запись будет!)
Первое (и я надеюсь, не последнее) мое выступление в этом году как спикера. На митапе MinskJS я буду рассказывать про пугающую ошибку с node-gyp, как её одолеть и прийти к победе.
Подключайтесь в эту среду сюда 👉 https://youtube.com/live/ILRrXYSthsA
(запись будет!)
Telegram
MinskCSS/MinskJS
🏁 Завершаем знакомить вас с программой MinskJS Meetup #12.
Анастасия Котова расскажет, почему при установке npm-зависимостей иногда падает ошибка, связанная с node-gyp, причём тут C++ и Python и как подготовить рабочее окружение, чтобы с такими ошибками…
Анастасия Котова расскажет, почему при установке npm-зависимостей иногда падает ошибка, связанная с node-gyp, причём тут C++ и Python и как подготовить рабочее окружение, чтобы с такими ошибками…
🔥3
#startpoint_dev_nodejs
Продолжаю погружаться в Node.js, и сегодня на очереди нюансы работы Event Loop.
Event Loop крутится, Node.js мутится. Часть 2. Нюансы работы Event Loop.
Продолжаю погружаться в Node.js, и сегодня на очереди нюансы работы Event Loop.
Event Loop крутится, Node.js мутится. Часть 2. Нюансы работы Event Loop.
Telegraph
Event Loop крутится, Node.js мутится. Часть 2. Нюансы работы Event Loop.
Предыдущие части Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер. В предыдущей статье мы разобрали, как базово работает Event Loop в Node.js и какие его основные отличия от браузерного. Теперь погрузимся в нюансы его работы. Предсказать порядок…
👍2
#startpoint_dev_nodejs
Третья часть моего погружения в Event Loop уже тут! В этот раз разбираюсь, как Node.js читает файлы, работает с потоками и почему одна регулярка может положить весь сервер.
Event Loop крутится, Node.js мутится. Часть 3. За пределами Event Loop.
Третья часть моего погружения в Event Loop уже тут! В этот раз разбираюсь, как Node.js читает файлы, работает с потоками и почему одна регулярка может положить весь сервер.
Event Loop крутится, Node.js мутится. Часть 3. За пределами Event Loop.
Telegraph
Event Loop крутится, Node.js мутится. Часть 3. За пределами Event Loop.
Предыдущие части Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер. Event Loop крутится, Node.js мутится. Часть 2. Нюансы работы Event Loop. В предыдущих частях мы разобрали, как работает Event Loop в Node.js, его отличия от браузерного, а…
👍1
Недавно решила переименовать локальный домен для проекта. Всё выглядело логично и красиво, но при запуске браузер выдал ошибку
Проблема оказалась в сертификате.
Для локальной разработки мы используем local-ssl-proxy и сертификат, выписанный на
Дело в том, что такие сертификаты (
То есть
Полезное напоминание: при работе с HTTPS даже локально лучше учитывать такие нюансы, иначе можно долго искать, почему всё сломалось, хотя раньше работало 🤡
net::ERR_CERT_COMMON_NAME_INVALID
и отказался доверять соединению.Проблема оказалась в сертификате.
Для локальной разработки мы используем local-ssl-proxy и сертификат, выписанный на
local.yandex.ru
. Старый домен попадал под *.local.yandex.ru
, и всё работало. А вот новый оказался на уровень глубже — и браузер это не простил.Дело в том, что такие сертификаты (
*.example.com
) покрывают только один уровень поддоменов.То есть
api.local.yandex.ru
— ок, а something.api.local.yandex.ru
— уже нет.Полезное напоминание: при работе с HTTPS даже локально лучше учитывать такие нюансы, иначе можно долго искать, почему всё сломалось, хотя раньше работало 🤡
👍2
Сегодня исполняется ровно год этому каналу!
За все это время я успела узнать много нового для себя, в том числе, когда готовила посты. Но конечно, больше всего сил и времени я вкладывала в статьи в Телеграфе. Возможно, когда-нибудь я переопубликую их где-нибудь ещё, ну а пока, в честь годовщины канала - дайджест статей в виде моего личного топа:
1️⃣ Первое место — серия постов про подкапотную работу Node.js в контексте Event Loop, но не только. Над ней я продолжаю работать прямо сейчас. Уже вышло три статьи, и на подходе еще три.
Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер.
Event Loop крутится, Node.js мутится. Часть 2. Нюансы работы Event Loop.
Event Loop крутится, Node.js мутится. Часть 3. За пределами Event Loop.
UPD: Оставшиеся три статьи из цикла:
Event Loop крутится, Node.js мутится. Часть 4. HTTP-сервер.
Event Loop крутится, Node.js мутится. Часть 5. Настоящая многопоточность.
Event Loop крутится, Node.js мутится. Часть 6. Профилировать и замерять.
2️⃣ Две части про pnpm — лично я, после подготовки этих статей стала сильным фанатом pnpm, присоединяйтесь, если ещё нет)
Pnpm: чем он так хорош?
Pnpm: особенности peer dependencies при работе над проектом
3️⃣ Пошаговая инструкция с примером, как настроить обвязку всех нужных линтеров в проекте с нуля — на мой взгляд, получился очень полезный гайд
Как настроить Prettier, ESLint, Stylelint и Husky в проекте с нуля
4️⃣ Статья с гифками про работу breakpoints в Chrome — хорошо визуализирует все основное, что нужно знать про дебаг в браузере
Инструменты отладки: точки останова и дебаг в DevTools
5️⃣ Рассказ про JWT и его использование — дает базовое overview этого инструмента
JWT - что это такое и с чем его едят
6️⃣ Отличия Webpack, Babel, Vite, Esbuild и других инструментов — для тех, кто устал путаться, как и я в своё время
Webpack, Babel, Vite и другие инструменты: что, зачем и в чем отличия
7️⃣ Небольшая заметка с примерами про useLayoutEffect — для понимания, когда этот React-хук может пригодиться
Что такое useLayoutEffect?
А также не могу не отметить появившуюся запись моего недавнего выступления с докладом на MinskJS. Там я развеиваю страхи вокруг ошибки с node-gyp. Приятного просмотра!)
За все это время я успела узнать много нового для себя, в том числе, когда готовила посты. Но конечно, больше всего сил и времени я вкладывала в статьи в Телеграфе. Возможно, когда-нибудь я переопубликую их где-нибудь ещё, ну а пока, в честь годовщины канала - дайджест статей в виде моего личного топа:
1️⃣ Первое место — серия постов про подкапотную работу Node.js в контексте Event Loop, но не только. Над ней я продолжаю работать прямо сейчас. Уже вышло три статьи, и на подходе еще три.
Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер.
Event Loop крутится, Node.js мутится. Часть 2. Нюансы работы Event Loop.
Event Loop крутится, Node.js мутится. Часть 3. За пределами Event Loop.
UPD: Оставшиеся три статьи из цикла:
Event Loop крутится, Node.js мутится. Часть 4. HTTP-сервер.
Event Loop крутится, Node.js мутится. Часть 5. Настоящая многопоточность.
Event Loop крутится, Node.js мутится. Часть 6. Профилировать и замерять.
2️⃣ Две части про pnpm — лично я, после подготовки этих статей стала сильным фанатом pnpm, присоединяйтесь, если ещё нет)
Pnpm: чем он так хорош?
Pnpm: особенности peer dependencies при работе над проектом
3️⃣ Пошаговая инструкция с примером, как настроить обвязку всех нужных линтеров в проекте с нуля — на мой взгляд, получился очень полезный гайд
Как настроить Prettier, ESLint, Stylelint и Husky в проекте с нуля
4️⃣ Статья с гифками про работу breakpoints в Chrome — хорошо визуализирует все основное, что нужно знать про дебаг в браузере
Инструменты отладки: точки останова и дебаг в DevTools
5️⃣ Рассказ про JWT и его использование — дает базовое overview этого инструмента
JWT - что это такое и с чем его едят
6️⃣ Отличия Webpack, Babel, Vite, Esbuild и других инструментов — для тех, кто устал путаться, как и я в своё время
Webpack, Babel, Vite и другие инструменты: что, зачем и в чем отличия
7️⃣ Небольшая заметка с примерами про useLayoutEffect — для понимания, когда этот React-хук может пригодиться
Что такое useLayoutEffect?
А также не могу не отметить появившуюся запись моего недавнего выступления с докладом на MinskJS. Там я развеиваю страхи вокруг ошибки с node-gyp. Приятного просмотра!)
🔥9
#startpoint_dev_nodejs
Четвёртая часть моей серии про Event Loop! На этот раз — HTTP-серверы: как Node.js принимает запросы, что происходит под капотом, зачем нужны таймауты и обработка ошибок.
Event Loop крутится, Node.js мутится. Часть 4. HTTP-сервер.
Четвёртая часть моей серии про Event Loop! На этот раз — HTTP-серверы: как Node.js принимает запросы, что происходит под капотом, зачем нужны таймауты и обработка ошибок.
Event Loop крутится, Node.js мутится. Часть 4. HTTP-сервер.
Telegraph
Event Loop крутится, Node.js мутится. Часть 4. HTTP-сервер.
Предыдущие части Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер. Event Loop крутится, Node.js мутится. Часть 2. Нюансы работы Event Loop. Event Loop крутится, Node.js мутится. Часть 3. За пределами Event Loop. Мы уже говорили про Event Loop…
👍1
#startpoint_dev_nodejs
В новой статье — разложила по полочкам, что такое cluster, worker_threads, чем они отличаются от child_process, и в каких случаях всё это нужно.
Event Loop крутится, Node.js мутится. Часть 5. Настоящая многопоточность.
Ну а через неделю будет уже финальная часть: разберу, как профилировать и замерять Event Loop.
В новой статье — разложила по полочкам, что такое cluster, worker_threads, чем они отличаются от child_process, и в каких случаях всё это нужно.
Event Loop крутится, Node.js мутится. Часть 5. Настоящая многопоточность.
Ну а через неделю будет уже финальная часть: разберу, как профилировать и замерять Event Loop.
Telegraph
Event Loop крутится, Node.js мутится. Часть 5. Настоящая многопоточность.
Предыдущие части Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер. Event Loop крутится, Node.js мутится. Часть 2. Нюансы работы Event Loop. Event Loop крутится, Node.js мутится. Часть 3. За пределами Event Loop. Event Loop крутится, Node.js…
👍1🔥1
#startpoint_dev_nodejs
Пока я в отпуске, новая и последняя часть моего цикла про Event Loop в Node.js уже тут!
Event Loop крутится, Node.js мутится. Часть 6. Профилировать и замерять.
Пока я в отпуске, новая и последняя часть моего цикла про Event Loop в Node.js уже тут!
Event Loop крутится, Node.js мутится. Часть 6. Профилировать и замерять.
Telegraph
Event Loop крутится, Node.js мутится. Часть 6. Профилировать и замерять.
Предыдущие части Event Loop крутится, Node.js мутится. Часть 1. Браузер VS сервер. Event Loop крутится, Node.js мутится. Часть 2. Нюансы работы Event Loop. Event Loop крутится, Node.js мутится. Часть 3. За пределами Event Loop. Event Loop крутится, Node.js…
❤1👍1
Недавно мне понадобилось быстро прогнать нагрузочный тест для одной гипотезы в духе: “а что будет, если на сервер одновременно упадёт 1765323 запроса?”
Так я познакомилась с autocannon.
Установка — одна команда, запуск — в одну строку.
Результат — удобная табличка со всеми нужными метриками. Подходит и для локальной проверки, и для CI.
Кастомизировать тоже можно, но в моём случае хватило дефолта.
Люблю инструменты, которые делают много, а требуют мало.
Так я познакомилась с autocannon.
Установка — одна команда, запуск — в одну строку.
Результат — удобная табличка со всеми нужными метриками. Подходит и для локальной проверки, и для CI.
Кастомизировать тоже можно, но в моём случае хватило дефолта.
Люблю инструменты, которые делают много, а требуют мало.
npx autocannon https://localhost:3000
🔥6👍3
За последнее время в канал добавилось много новых людей — добро пожаловать! 💫
Здесь я в основном выкладываю статьи и посты с разбором всяких интересных технологических загогулин (в последнее время особенно много по Node.js). Но сегодня решила разбавить контент мемом)
У меня, признаюсь, есть одна проблема — я не очень хорошо знаю английский. Поэтому иногда, чтобы побыстрее найти ответ, перевожу статьи или куски документации через переводчик. И конечно, он часто выдает перлы. Подвезла вам некоторые из них (последний не имеет ничего общего с разработкой, но тоже смешон).
Здесь я в основном выкладываю статьи и посты с разбором всяких интересных технологических загогулин (в последнее время особенно много по Node.js). Но сегодня решила разбавить контент мемом)
У меня, признаюсь, есть одна проблема — я не очень хорошо знаю английский. Поэтому иногда, чтобы побыстрее найти ответ, перевожу статьи или куски документации через переводчик. И конечно, он часто выдает перлы. Подвезла вам некоторые из них (последний не имеет ничего общего с разработкой, но тоже смешон).
❤13😁5👏3🔥1😢1
Сборка мусора в Node.js
Когда мы говорим о сборке мусора в JavaScript, мы имеем в виду то, как это реализовано в движке. В случае и Node.js, и большинства браузеров (например, Chrome) речь идёт про один и тот же механизм: сборку мусора в V8.
Сердцем движка V8 является Generational GC — поколенческая сборка мусора. Её основная идея: объекты, которые живут долго, — редкость, большинство умирает вскоре после появления (феномен “высокой детской смертности”). Чтобы использовать это наблюдение, V8 делит память (heap) на поколения:
- New space — молодое поколение. Здесь появляются все новые объекты. Это небольшая область памяти, которую можно быстро и часто очищать.
- Old space — старое поколение. Если объект прожил несколько циклов сборки в New space и всё ещё нужен — его «повышают» и переносят сюда. Эта область больше по размеру и чистится реже.
Внутри New space работает Scavenge — быстрый алгоритм копирования. Его реализация основана на двух зонах:
- From-space — где живут текущие объекты.
- To-space — пустая зона, куда будут скопированы только «живые» объекты.
Когда запускается сборка, GC перебирает объекты из from-space, и те, которые всё ещё достижимы (то есть на них есть ссылки), копируются в to-space. Остальные просто забываются — они исчезают вместе со старой областью. Затем роли зон меняются. Такой подход прост и быстр: не нужно ничего удалять, достаточно скопировать нужное.
Но этот трюк работает, пока объектов немного — он отлично подходит для New space, где всё ещё «свежее». А вот для Old space он неэффективен: там уже много данных, копировать всё — слишком дорого.
Для старого поколения V8 использует алгоритмы Mark-Sweep и Mark-Compact:
- Mark-Sweep: сначала проходит по графу объектов, помечая «живые». Потом всё, что не помечено, удаляется. Это экономно по времени, но может оставить фрагментированное пространство.
- Mark-Compact: дополнительно уплотняет память, передвигая объекты в один конец heap-а, чтобы не оставалось дыр. Это происходит небыстро, но снижает фрагментацию.
Обе эти стратегии медленнее, чем Scavenge, но подходят для устойчивых структур данных, которые не хочется копировать по несколько раз.
Чтобы сборка не вызывала внезапных тормозов, V8 применяет ещё и инкрементальные и конкурентные оптимизации:
- Incremental GC разбивает большие этапы сборки на мелкие порции и выполняет их между основными задачами.
- Concurrent GC работает в отдельных потоках, параллельно с кодом, стараясь вообще не останавливать исполнение.
Таким образом, сборка мусора в V8 — это не один алгоритм, а комбинация техник, каждая из которых применяется в нужное время и в нужном месте.
И, в отличие от браузеров, в Node.js у нас есть возможность чуть больше контролировать процесс: если запустить скрипт с флагом
#startpoint_dev_nodejs
Когда мы говорим о сборке мусора в JavaScript, мы имеем в виду то, как это реализовано в движке. В случае и Node.js, и большинства браузеров (например, Chrome) речь идёт про один и тот же механизм: сборку мусора в V8.
Сердцем движка V8 является Generational GC — поколенческая сборка мусора. Её основная идея: объекты, которые живут долго, — редкость, большинство умирает вскоре после появления (феномен “высокой детской смертности”). Чтобы использовать это наблюдение, V8 делит память (heap) на поколения:
- New space — молодое поколение. Здесь появляются все новые объекты. Это небольшая область памяти, которую можно быстро и часто очищать.
- Old space — старое поколение. Если объект прожил несколько циклов сборки в New space и всё ещё нужен — его «повышают» и переносят сюда. Эта область больше по размеру и чистится реже.
Внутри New space работает Scavenge — быстрый алгоритм копирования. Его реализация основана на двух зонах:
- From-space — где живут текущие объекты.
- To-space — пустая зона, куда будут скопированы только «живые» объекты.
Когда запускается сборка, GC перебирает объекты из from-space, и те, которые всё ещё достижимы (то есть на них есть ссылки), копируются в to-space. Остальные просто забываются — они исчезают вместе со старой областью. Затем роли зон меняются. Такой подход прост и быстр: не нужно ничего удалять, достаточно скопировать нужное.
Но этот трюк работает, пока объектов немного — он отлично подходит для New space, где всё ещё «свежее». А вот для Old space он неэффективен: там уже много данных, копировать всё — слишком дорого.
Для старого поколения V8 использует алгоритмы Mark-Sweep и Mark-Compact:
- Mark-Sweep: сначала проходит по графу объектов, помечая «живые». Потом всё, что не помечено, удаляется. Это экономно по времени, но может оставить фрагментированное пространство.
- Mark-Compact: дополнительно уплотняет память, передвигая объекты в один конец heap-а, чтобы не оставалось дыр. Это происходит небыстро, но снижает фрагментацию.
Обе эти стратегии медленнее, чем Scavenge, но подходят для устойчивых структур данных, которые не хочется копировать по несколько раз.
Чтобы сборка не вызывала внезапных тормозов, V8 применяет ещё и инкрементальные и конкурентные оптимизации:
- Incremental GC разбивает большие этапы сборки на мелкие порции и выполняет их между основными задачами.
- Concurrent GC работает в отдельных потоках, параллельно с кодом, стараясь вообще не останавливать исполнение.
Таким образом, сборка мусора в V8 — это не один алгоритм, а комбинация техник, каждая из которых применяется в нужное время и в нужном месте.
И, в отличие от браузеров, в Node.js у нас есть возможность чуть больше контролировать процесс: если запустить скрипт с флагом
--expose-gc
, можно вручную вызывать в коде global.gc()
— это бывает полезно, например, в нагрузочных тестах, о которых мы, кстати, говорили совсем недавно)#startpoint_dev_nodejs
👍11🔥4❤1
Недавно увидела в одной статье аббревиатуру REPL, которая оказалась для меня на первый взгляд незнакомой. Но на самом деле, я знаю, что это такое, и хочу, чтобы теперь знали и вы)
REPL — это Read–Eval–Print–Loop: интерактивная оболочка, в которой можно писать JavaScript-код построчно, и он сразу выполняется. Похоже на консоль в инструментах разработчика в браузере.
Когда мы просто запускаем
Неожиданность для меня была в другом. В Node.js есть отдельный модуль для REPL. С его помощью можно встроить собственный REPL прямо в код, например, для дебага приложения.
Такой подход используется и в NestJS. Запустить REPL там можно командой
А волшебный доступ ко всем сервисам приложения реализуется с помощью дополнения контекста repl. Вот так можно сделать свой микро-repl с доступными в контексте переменными и функциями:
Вывод будет вот такой:
#startpoint_dev_nodejs
REPL — это Read–Eval–Print–Loop: интерактивная оболочка, в которой можно писать JavaScript-код построчно, и он сразу выполняется. Похоже на консоль в инструментах разработчика в браузере.
Когда мы просто запускаем
node
в терминале и дальше можем писать разные команды вида 2 + 2
— вот это и есть REPL.Неожиданность для меня была в другом. В Node.js есть отдельный модуль для REPL. С его помощью можно встроить собственный REPL прямо в код, например, для дебага приложения.
Такой подход используется и в NestJS. Запустить REPL там можно командой
npm run start -- --entryFile repl
, если заранее настроен файл repl.ts (документация). Там можно получить доступ к инстансам сервисов и вызывать их методы руками. И для реализации такого механизма NestJS как раз использует модуль repl, исходники можно посмотреть тут.А волшебный доступ ко всем сервисам приложения реализуется с помощью дополнения контекста repl. Вот так можно сделать свой микро-repl с доступными в контексте переменными и функциями:
import repl from 'node:repl';
const context = {
hello: 'world',
add: (a, b) => a + b,
};
const r = repl.start('> ');
Object.assign(r.context, context)
Вывод будет вот такой:
node repl-test.js
> hello
'world'
> add(2, 3)
5
>
#startpoint_dev_nodejs
🔥17👍4❤2