Що таке серіалізація і навіщо вона потрібна при передачі даних між Node.js і браузером?

  1. Об’єкт в JavaScript живе в оперативній пам’яті конкретного процесу як структура з адресами — { name → адреса 0x7f4b → 'Iuliia' }. Ці адреси мають сенс тільки всередині цього одного процесу.
  2. Мережа і файли передають байти. Якщо відправити адресу 0x7f4b — на іншому комп’ютері вона вкаже на іншу ділянку пам’яті або нікуди. Об’єкт прив’язаний до конкретної пам’яті процесу.
  3. Серіалізація — перетворення об’єкта з “адрес в пам’яті” в текст де значення записані явно. Текст не залежить від конкретної машини.
  4. Десеріалізація — зворотній процес: текст назад в об’єкт.
  5. JSON — найпоширеніший формат серіалізації у вебі. Виглядає майже як JavaScript об’єкт, розуміє будь-яка мова програмування і будь-який сервер.
  6. У Playwright серіалізація відбувається коли передаємо аргументи в evaluate() або waitForFunction() — Playwright перетворює JavaScript об’єкт в JSON, відправляє через WebSocket в браузер, браузер десеріалізує назад в об’єкт.

Аналогія: об’єкт — це будинок у твоєму місті. Ти не можеш “відправити будинок” другу в іншому місті. Але можеш зробити план будинку і відправити його — це і є серіалізація. Друг отримує план і будує такий самий будинок — це десеріалізація.

TypeScript — серіалізація і десеріалізація

const user = { name: 'Iuliia', age: 30 }; // об'єкт в пам'яті

// Серіалізація — перетворюємо в рядок (JSON текст)
const text = JSON.stringify(user);
// text = '{"name":"Iuliia","age":30}'
// тепер можна зберегти у файл або відправити через мережу

// Десеріалізація — перетворюємо рядок назад в об'єкт
const obj = JSON.parse(text);
// obj = { name: 'Iuliia', age: 30 }

TypeScript — серіалізація в Playwright: передача аргументів між Node.js і браузером

const expected = 48; // змінна в Node.js

// Playwright серіалізує 48 в JSON і передає через WebSocket в браузер
// Браузер десеріалізує і отримує число 48 як аргумент функції
await page.waitForFunction(
  (count) => document.querySelectorAll('.product-card').length >= count,
  expected // ← серіалізується і передається в браузер
);

// Closure НЕ працює через межу процесів — бо функція переїжджає в браузер
// а змінна expected залишається в Node.js (різні процеси, різна пам'ять)
await page.waitForFunction(
  () => document.querySelectorAll('.product-card').length >= expected // ❌ undefined!
);

🔧 TypeScript / JS патерни в цьому прикладіJSON.stringify(obj) — статичний метод класу JSON, серіалізує об’єкт в рядок; JSON.parse(text) — десеріалізує рядок назад в об’єкт; { name: 'Iuliia', age: 30 } — об’єктний літерал; серіалізація обмежена: функції, undefined, і посилання на DOM елементи серіалізувати не можна.

🗣 Як читати вголосСеріалізація — це перетворення об’єкта з оперативної пам’яті в текст для передачі через мережу або запису у файл. Об’єкт не можна передати напряму бо він існує як структура адрес в пам’яті конкретного процесу — ці адреси не мають сенсу в іншому процесі або на іншому комп’ютері. JSON це найпоширеніший формат серіалізації у вебі — JSON.stringify() перетворює об’єкт в рядок, JSON.parse() — назад. У Playwright це важливо при передачі аргументів в evaluate() або waitForFunction(): Playwright серіалізує значення в JSON, відправляє через WebSocket в браузер, браузер десеріалізує назад. Саме тому closure не працює через межу процесів — функція переїжджає в браузер, але змінні з Node.js залишаються в Node.js, і їх треба явно передавати як аргументи через серіалізацію.