Node.js Recipes
3.23K subscribers
174 photos
7 videos
1 file
622 links
По буднях нотатки по #Nodejs розробці, по вихідним огляди конференцій та доповідей (с) @galkin_nikita
Download Telegram
О 18-й почну воркшоп «Infrastructure for Firebase project». Для тих, хто хоче не лише подивитися, а й одразу повторювати, рекомендую:
- Підготувати обліковий запис Google Cloud (https://console.cloud.google.com)
- Встановити terraform, gcloud CLI, firebase CLI, nodejs

PS Цитата від організаторів: “лайв доступен для всіх) Запис для full квитків”
👍13🔥4🥰1
Forwarded from Natali
Лічені хвилини до нашої зустрічі на воркшопі «Інфраструктура для Firebase проєкту» 😌

Розпочинаємо о 18:00!

Приєднуйтесь за лінком та не блукайте 👉 https://us02web.zoom.us/j/81709177877
GitHub оновив RSA SSH host key
#news

Що таке RSA SSH host key?

RSA SSH host key це криптографічний ключ, який використовується в протоколі SSH для забезпечення безпеки підключення до сервера, він використовується для перевірки автентичності сервера. Ключі RSA мають дві частини: приватний та публічний ключі. Приватний ключ залишається на сервері, а публічний ключ розповсюджується серед клієнтів, які підключаються до сервера. При першому підключенні до сервера клієнт отримує публічний ключ сервера, який потім зберігається на клієнті. При наступному підключенні клієнт перевіряє, що ключ не змінівся.

Що робіти?
Запустити у терміналі
ssh-keygen -R github.com
curl -L https://api.github.com/meta | jq -r '.ssh_keys | .[]' | sed -e 's/^/github.com /' >> ~/.ssh/known_hosts

Джерело: https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/
👍34
Завтра у 19:00 буду в гостях на youtube каналі Сергія Бабіча. Підключайтеся подивитися прямий ефір.
Будемо теревеніти про розробку загалом та про ноду зокрема.
https://www.youtube.com/watch?v=QgFr9CxpL3Y
🔥31👍12
Forwarded from Той самий Бабіч (Сергій Бабіч)
Готовність — 2 хвилини!

https://www.youtube.com/live/QgFr9CxpL3Y
👍6
Правильний перехід на typescript v5
#typescript

На відміну від решти JavaScript екосистеми, TypeScript не слідує SemVer. Тобто немає різниці в переході між 4.8➡️4.9 та 4.9➡️5.0. В обох випадках можливі breaking changes.

Однак багато пакетів не використовують цю інформацію та в залежностях вказують, що очікують TypeScript@4.x. Приклад помилки під час install:
npm ERR! Could not resolve dependency:
npm ERR! peer typescript@"^3.7.5 || ^4.0.0" from eslint-plugin-deprecation@1.3.3
npm ERR! node_modules/eslint-plugin-deprecation
npm ERR!  dev eslint-plugin-deprecation@"^1.3.3" from the root project
Помилки під час встановлення це не страшно. Ось важкоуловимі баги під час компіляції – це великі втрати часу на налагодження. Рецепт написаний за підсумком саме такого налагодження.

Обидва типи проблем легко вирішуються за допомогою npm overrides або yarn resolutions у package.json:
"typescript": "^5.0.2"
},
"overrides": {
"typescript": "$typescript"
}

$typescript каже npm перевикористовувати вказану версію для всіх пакетів. Тепер ваш код використовуватиме потрібну версію тайпскрипту під час компіляції.
👍49💯1
Переліку питань для інтерв'ю про масивах
#list

1. Розкажіть, як працюють Array.concat і Array.push. У яких випадках краще використовувати кожен метод?
2. Напишіть поліфіл для Array.group. На момент написання цього списку метод знаходиться вже на stage 3, але ще не підтримується Node.js
3. Наведіть приклад 3 методів, які існують в Array, але не в ReadonlyArray в TypeScript.
4. Розкажіть про різницю в використанні Array.at(i) та arr[i].
5. Наведіть приклад поганого коду, використовуючи Array. Поясніть, чому погано писати такий код.
6. Напишіть функцію, яка приймає масив чисел і повертає новий масив з усіма числами, які зустрічаються в вихідному масиві більше одного разу.
7. Напишіть функцію, яка приймає два масиви чисел і повертає новий масив, що містить лише ті елементи, які є спільними для обох масивів.
8. Напишіть функцію, яка приймає масив і повертає, чи містить він прогалини. Приклад f([1,2,,4]) === true
9. Напишіть функцію, яка приймає масив arr, число concurrency, асинхронну функцію processing і повертає результат обробки масиву функцією processing з вказаним рівнем concurrency.
10. Напишіть функцію, яка приймає масив чисел arr, число target і повертає два елементи масиву, сума яких дорівнює target.

PS Інші переліки питань для інтерв'ю ви можете знайти за тегом #list.
👍354🔥1
Цього місяця пройде Node Congress 2023. Його роблять хлопці з GitNation. Якість доповідей на минулих конференціях можна оцінити на їхньому порталі. Конференція пройде в Берліні та онлайн. 32 доповідача, включаючи Раяна Даля. 9 воркшопів з яких 3 безкоштовні.

Посилання:
🔗 nodecongress.com
🔗 portal.gitnation.org
👍19🔥1
Не соромно виправляти неполадки за допомогою console.log замість debug-mode. Шкода не знати про console.trace. Використовуйте console.trace, щоб зрозуміти, звідки викликається ваш код.
👍618💯1
Як швидко перейти на return await?
#eslint #typescript

Спочатку коротко розповім, навіщо це робити. Помилки в логах записуються у stack trace. Якщо функція повертає not resolved promise, то у stack trace буде дірка. Приклади коду та докладний розбір є у Node.js Best Practices 2.12 Always await promises before returning to avoid a partial stacktrace

Минулого тижня я занурився у debugging. Проблема була замаскована обірваними stack trace. Виявляється, що позбутися цього можна дуже швидко. Достатньо додати @typescript-eslint/return-await . Він має автофікс! Після eslint --fix дебаг втратив детективний сюжет, бо стало очевидним, що проблема у відсутності транзакцій на рівні бази даних. Так що додайте це правило до вашого проекту, щоб наступне налагодження пройшло швидше.
👍54🤔4🤯31
Використовуйте правильну термінологію!
Node.js – це середовище виконання JavaScript (runtime environment). Не фреймворк, не двигун, не бібліотека, а саме runtime!
48👍18
Нещодавно один з моїх колег, з яким ми не спілкувалися протягом 3-х років, написав мені. Два року тому колега виконав тестове завдання, яке полягало в створенні одного специфічного фронтенд компонента. Він навіть отримав за це офер, але так і не прийняв його. До кінця минулого року компонент був опублікований тільки в його особистому GitHub профайлі, а потім він змінив видимість репозиторія з публічної на приватну.

Після Нового року йому написали: "Друже, а чому ти видалив свій пакет? У нас зараз проект не збирається." Колега повернув все назад, ввічливо поцікавився, чи працює тепер все так, як має. Наступного листа він спитав як зв'язатися з адвокатом компанії.

Справа в тому, що під час спільної роботи я пояснив йому, як працює ліцензії і підказав npm config set init-license="UNLICENSED". Листування з інженером було достатньою доказовою базою того, що компонент використовувався без його дозволу.

Листування з адвокатом та СТО показало, що компанії не вела і не аналізувала SBOM (software bill of materials). Помилку визнали без суду. У березні компанія впровадила SBOM. А на початку квітня колега передав компонент та права на нього, підписав NDA та й отримав від них виплату!
🔥61👍12🤔1
Як додати у PostgreSQL тернарний оператор?
#db

TL;DR; додайте замість тернарника збережену процедура iif

PostgreSQL має дуже обмежену функціональність для умовних виразів (Conditional Expressions):
CASE дуже схожий на switch case
COALESCE, що повертає перший зі своїх аргументів, який не є нульовим
NULLIF повертає null, якщо значення дорівнює одне іншому; інакше повертає перше значення.
GREATEST/LEAST повертає найбільше/найменше значення

Тернарного оператора немає, його заміна за допомогою CASE виглядає так:
CASE WHEN condition THEN true_result ELSE false_result END
Багатослівно, та й ще важко знаходити помилки коли використовуються різні типи даних. Це типова проблема на проектах з LowCode admin UI (наприклад retool) чи LowCode Analytics (наприклад Looker Studio).

Для спрощення я додаю збережену процедура:
CREATE or replace FUNCTION iIF(
condition boolean, -- IF condition
true_result anyelement, -- THEN
false_result anyelement -- ELSE
) RETURNS anyelement AS $f$
SELECT CASE WHEN condition THEN true_result ELSE false_result END
$f$ LANGUAGE SQL IMMUTABLE;

Після цього можна використовувати
iff(condition, true_result, false_result)

Читати та підтримувати це простіше. Особливо аналітикам, які звикли до Google Sheets.

⚠️Традиційне застереження⚠️ не використовує збережені процедури для бізнес-логіки, бо це розмазує її реалізацію між Node.js кодом та кодом збережених процедур.
👍21🔥32
Node.js 18.16
#release

Цього тижня вийшов мінорний реліз Node.js 18.16. Він включає:
👉 початкова підтримка компіляції JavaScript в виконувану програму (single standalone executable). Поки що лише для одного файлу, при цьому копіює весь бінарник Node.js, а значить це не кроссплатформенно. Для мене виглядає як спроба зробити silver bullet. Щоб створити власну думку, ви можете переглянути документацію репозиторію nodejs/single-executable
👉 новий url parser Ada. Нагадаю, що Node.js та браузери використовують однакову сигнатуру для класу URL, але мають різну реалізацію. Node.js документація, браузерна документація. ⚠️ Рекомендую перечитати браузерну документацію. Особисто я упустив, що в конструктор можна передавати другий аргумент base. Так ось новий парсер швидший і написаний на чистому сучасному C++. У наступному релізі ноди, можна чекати на його оновлення на 2-у версію. Детальніше у пості автора.
👉 експериментальні методи AsyncLocalStorage.bind та AsyncLocalStorage.snapshot, для яких я не розумію застосування.

повний список змін у changelog
16👍9🔥3
Як працює watch-mode у NestJS?
#nestjs

Під час розробки NestJS прийнято запускати у watch-mode (live-reload). Приклад:
"scripts": {
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch"
}

У цьому режимі NestJS cli стежить за зміною ts файлів і перезапускає ваш додаток. У nest-cli.json є compilerOptions, який визначає що буде використовуватися для цього – webpack або tsc. У цьому файлі можна визначити watchAssets та перелік не ts файлів assets, при зміни яких необхідно перезапускати додаток. Приклади використання:
– MVC, тобто html-рендерінг.
– email-templates
– .env файл

Детальніше про налаштування NestJS cli у документації.

На завершення кілька цікавостей:
1️⃣ У watch-mode iснує відома проблема нескінченного циклу "File change detected" у Windows-користувачів з TypeScript 4.9+. Рішення у FAQ.
2️⃣ У @nestjs/cli v9.4, яка вийшла минулого тижня, додали manual-restart-watchmode. Про це свідчить напис To restart at any time, enter rs
👍17
Ноді вже понад 10 років. Для усвідомленого формування стратегії розвитку на наступні десяток років проводять опитування. Пропоную вам взяти у ньому участь:
👉 https://hubs.la/Q01LHCBD0.

Результати опитування будуть використовуватись командою next-10. Їхня робота документується в однойменному репозиторії. Там можна знайти звіти та відео з нарад. Ось наприклад звіт з опитуванням за 2021 рік.
14👍11
Як не втрачати stack trace?
#nodejs_api

Сьогодні ми обговоримо, що робити з помилками, у яких stack trace закінчується at processTicksAndRejections (node:internal/process/task_queues)

Багато популярних пакетів викидають помилки таким чином, що stack trace обривається у коді самого пакета. Це ускладнює відлагодження таких виключень, оскільки втрачається стек викликів у коду додатка. Нажаль, у багатьох випадках контрибутори пакетів відхиляють запити на виправлення цієї проблеми. Приклади:
- Improve axios stack traces axios/axios#2387
- Missing stack trace on errors stripe/stripe-node#1066

Якщо пакет популярний, то ком'юніті запропонує якісь рішення. Наприклад axios-better-stacktrace.

Загальним рішенням є використання try-catch та викидати нову помилки з cause. Нагадую, що ми маємо Error: cause з Node v16.9.0. Для цього я використовую такий хелпер:

export function reThrow(reason: unknown, errorConstructor: ErrorConstructor = Error): never {
const errorMessage = reason instanceof Error ? reason.message : errorConstructor.name;
const error = new errorConstructor(errorMessage, { cause: reason });
Error.captureStackTrace(error, reThrow);
throw error;
}

Error.captureStackTrace(... видаляє з stack trace рядки хелпера.

Приклад використання:
const session = await stripeClient.billingPortal.sessions.create({customer: ''}).catch(reThrow);
👍25🤔2🔥1💩1👌1
#typescript

На вихідних вийшла нова версія VSCode розширення pretty-ts-errors. Воно додає до вашого редактора:
👉 підсвічування синтаксису для типів у повідомленнях про помилки
👉 кнопка, яка відкриває оголошення відповідного типу поруч з типом у повідомленні про помилку.
👉 кнопка, яка відкриває помилку на typescript.tv
👉 кнопка, яка відкриває помилку на ts-error-translator

Якщо ви ще не користуєтеся цим розширенням, рекомендую встановити. pretty-ts-errors дуже спрощує роботу джунів та їх менторів.

Автор просить підтримати лайками додавання до VSCode необхідного API. Якщо ви віддаєте перевагу WebStorm, то ставте лайк JetBrains support. Будь ласка, ⚠️використовуйте лайк, а не коментарі⚠️ – це дозволить робити правильні метрики без спам сповіщень через коментар.

Посилання
🔗 source code
🔗 VSCode marketplace
🔗 upvotes to move forward
👍39
TDD це не догма, а процес розробки. А який у вас процес?
#npm

Щоразу, коли я роблю аудит і бачу у package.json:
"test": "echo 'not implemented yet'"
я запитую одне й те саме питання, а чому у вас існує саме такий test скрипт? Не залежно від відповіді наступне питання завжди одне й те саме, яке винесене в заголовок. Подальше обговорення у 95% випадків показує, що в цьому конкретно репозиторії на тести немає часу/необхідності. А та ще за CI/CD відповідає інша команда, яка не знає про прапор --if-present.

Будь-який неоголошений скрипт із цим прапором не буде провалений. Тому, якщо ви виконуєте функцію техлід або DevOps інженера на проекті, то використовуйте де необхідно npm run test --if-present.

Ще нагадаю, що не кожен проект потребує юніт тестів, що лежать в основі TDD. Але кожен проект вимагає здорового глузду та знання використовуваних інструментів. Тож перечитайте документацію npm, node та вашого фреймворку.
👍45
Як уникнути Race Conditions у JavaScript коді?
#worth_seeing

Цього тижня з консалтингу був цікавий баг. Проблему ілюструє такий код:
import { scheduler } from 'node:timers/promises';

async function countLikes() {
const postIds = [1, 2, 3];
let likes = 0;
await Promise.all(
postIds.map(async (id) => {
likes += await fetchLikes(id);
})
);
return likes;
}

async function fetchLikes(id: number) {
await scheduler.wait(Math.random() * 1000);
return id;
}
Очікуваний результат виконання функції countLikes це 6, але в коді є Race Condition. Щоб його виправити необхідно замінити likes += await fetchLikes(id) на
const count = await fetchLikes(id);
likes += count;

Щоб уникати таких випадків існує eslint правило require-atomic-updates. Воно за замовчуванням вимкнено у eslint:recommended . Як правило воно надто суворе, оскільки змушує писати код у Defensive programming style. Особисто мені це не зручно, тому я тримаю його вимкненим, але час від часу вмикаю його, щоб переглянути ризиковані місця.

Академічно правильний спосіб боротьби з Race Conditions є у доповіді Тимура Шемседінова Web Locks API in Node.js and browser.
👍509
Прямо зараз почалися два стрими:
👀 https://www.youtube.com/watch?v=EbqxKNW6Hpk
ТЕРЕВЕНІ Сергія Бабіча @toisamyibabich з Віктором Турським @jabascript

👀 https://www.youtube.com/watch?v=PB0rXYyEeP0
JavaScript балачки #9 від Іллі Клімова @jsninja_news
👍183