naver/fe-news ๋‰ด์Šค๋ ˆํ„ฐ ๋ทฐ์–ด (๋น„๊ณต์‹)

๋ชฉ์ฐจ
๋ชฉ์ฐจ

    2021-12

    ๋งํฌ & ์ฝ์„๊ฑฐ๋ฆฌ

    DEVIEW 2021

    ๊ตญ๋‚ด ๊ฐœ๋ฐœ์ž ์ฝ˜ํผ๋Ÿฐ์Šค์ธ DEVIEW 2021์ด ์ง€๋‚œ 11์›” 24์ผ ~ 26์ผ 3์ผ๊ฐ„ ์ง„ํ–‰๋˜์—ˆ๋‹ค.

    ํ‚ค๋…ธํŠธ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ์„ธ์…˜ ์˜์ƒ์ด ๊ณต๊ฐœ๋˜์–ด ํ™•์ธํ•ด ๋ด๋„ ์ข‹์„ ๋“ฏํ•˜๋‹ค.

    [์ฐธ๊ณ ] DEVIEW 2021 Front-end ์„ธ์…˜

    React Split Components: A new way of Function Components without Hooks

    React 16.8์—์„œ Hook์ด ๋“ฑ์žฅํ•œ ์ดํ›„๋กœ ์ด์ œ ๋Œ€๋ถ€๋ถ„์˜ React ๊ฐœ๋ฐœ์€ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋„˜์–ด๊ฐ€๋Š” ์ถ”์„ธ์ด๋‹ค. ํ•˜์ง€๋งŒ Hook์€ ์ดˆ์‹ฌ์ž์—๊ฒŒ React๋ฅผ ๋”์šฑ ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ์š”์†Œ์ด๊ธฐ๋„ ํ•˜๋‹ค.

    ์ด ๊ธ€์—์„œ๋Š” ์ด๋Ÿฌํ•œ Hook๋“ค์„ ๋ž˜ํ•‘ ํ•˜์—ฌ ์ข€ ๋” ์‰ฝ๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” RiC(React Split Component)๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์„ ๋ณด์—ฌ์ค€๋‹ค.

    ๊ฐ ๊ตฌํ˜„ ๊ณผ์ •์„ ํ•œ ๋‹จ๊ณ„์”ฉ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋ฉฐ ์ง„ํ–‰ํ•˜๋Š”๋ฐ, ๋ฌด์—‡๋ณด๋‹ค ๊ตฌํ˜„ ๋ฐฉ์‹์ด ์žฌ๋ฏธ์žˆ์œผ๋‹ˆ ํ•œ๋ฒˆ ์ฝ์–ด๋ณด๊ธธ ์ถ”์ฒœํ•œ๋‹ค.

    Record, replay and measure user flows

    Chrome 97์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์œผ๋กœ recorder ํŒจ๋„์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ์•ก์…˜์„ ๋…นํ™”ํ•˜๊ณ  ์ด๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•ด ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ๋‹จ์ˆœ ๋…นํ™”๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ €์žฅํ•œ ์‚ฌ์šฉ์ž์˜ ์•ก์…˜์„ ์ˆ˜์ •ํ•  ์ˆ˜๋„ ์žˆ๊ธฐ์— ๋‹ค์–‘ํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด๋ผ ์ƒ๊ฐํ•œ๋‹ค.

    Suspense for Data Fetching์˜ ์ž‘๋™ ์›๋ฆฌ์™€ ์ปจ์…‰ (feat.๋Œ€์ˆ˜์  ํšจ๊ณผ)

    ๊ธฐ์กด์˜ ๋ช…๋ น์ ์ธ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋Š” ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋–จ์–ด๋œจ๋ฆฌ๊ธฐ ์‰ฝ๋‹ค. ๊ทธ๋ž˜์„œ Suspense์™€ ErrorBoundary๋ฅผ ์ด์šฉํ•˜์—ฌ ์„ ์–ธ์  ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” Suspense๋ฅผ ์ด์šฉํ•œ data fetching์˜ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์ด๋ฅผ ํ†ตํ•ด ๋Œ€์ˆ˜์  ํšจ๊ณผ์— ๋Œ€ํ•ด ์ดํ•ดํ•œ ์ž‘๊ฐ€์˜ ๋ฉ˜ํƒˆ ๋ชจ๋ธ์„ ์„ค๋ช…ํ•œ๋‹ค.

    CS Visualized: Useful Git Commands

    Git์˜ ๋ช…๋ น์–ด๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ์ž˜ ์„ค๋ช…ํ•œ ๊ธ€์ด๋‹ค. Git์— ์ต์ˆ™ํ•œ ์‚ฌ์šฉ์ž๋“  ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž๋“  Git ๋ช…๋ น์–ด๋ฅผ ๋ณด๋‹ค ์ž˜ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€ ๋˜๋Š” ๊ธ€์ด๋‹ค.

    ์Šค๋ฒจํŠธ vs ๋ฆฌ์•กํŠธ, ๋ˆ„๊ฐ€ ๋” ๋›ฐ์–ด๋‚ ๊นŒ?

    ๋‹ค์†Œ ์ž๊ทน์ ์ธ ์ œ๋ชฉ์œผ๋กœ, ๊ฐ„๋‹จํ•˜๊ฒŒ Svelte์™€ React๋ฅผ ๋น„๊ตํ•œ ๊ธ€์ด๋‹ค. React์™€๋Š” ์ต์ˆ™ํ•˜์ง€๋งŒ Svelte๋Š” ์ƒ์†Œํ•œ ๊ฐœ๋ฐœ์ž๋“ค์ด React์™€ ๋น„๊ต๋ฅผ ํ†ตํ•ด Svelte์— ๋Œ€ํ•œ ๋Œ€๋žต์ ์ธ ์ดํ•ด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์„ ๊ฑฐ๋ผ ์ƒ๊ฐํ•œ๋‹ค.

    proposals.es

    ECMAScript proposal๋“ค์„ ํ•œ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๋Š” ์‚ฌ์ดํŠธ์ด๋‹ค.

    ๊ฐ stage ๋ณ„๋กœ ์ง„ํ–‰ ์ค‘์ธ proposal๋“ค์„ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์›ํ•˜๋Š” proposal์„ ๊ฒ€์ƒ‰ํ•ด ๋ณผ ์ˆ˜๋„ ์žˆ๋‹ค.

    Rust Is The Future of JavaScript Infrastructure

    Mozilla์—์„œ ๋งŒ๋“  ์ €์ˆ˜์ค€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ธ Rust๊ฐ€ JavaScript ์–ธ์–ด๋ฅผ ๋Œ€์‹ ํ•ด์„œ JavaScript ๋„๊ตฌ ์ƒํƒœ๊ณ„์˜ ๋งŽ์€ ๋ถ€๋ถ„์„ ๋Œ€์ฒดํ•˜๊ณ  ์žˆ๋‹ค. ๊ทธ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋Š” SWC, Deno ๋“ฑ์ด ์žˆ๋‹ค.

    ์ด ๊ธ€์—์„œ๋Š” Rust๊ฐ€ JavaScript ๋„๊ตฌ ์ƒํƒœ๊ณ„์— ๋งŽ์€ ๋ถ€๋ถ„์„ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ๋Š” ์ด์œ ๋ฅผ ์„ค๋ช…ํ•œ๋‹ค.

    Under-the-hood-ReactJS

    ์‹œ๊ฐ์  ๋ธ”๋ก ๋ฐฉ์‹์œผ๋กœ React ๋‚ด๋ถ€์—์„œ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์ฝ”๋“œ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๋ช…ํ•œ๋‹ค. ์ด 15๊ฐœ์˜ ์„น์…˜์œผ๋กœ ๊ตฌ๋ถ„๋˜์–ด ์žˆ์œผ๋ฉฐ, ๋ฌธ์„œ๋Š” Stack Reconciler๋ฅผ ์‚ฌ์šฉํ•˜๋Š” React 15.4.2์— ๊ธฐ๋ฐ˜ํ•ด ์„ค๋ช…ํ•œ๋‹ค. ์ตœ์‹  ๋ฒ„์ „์˜ React๋Š” ์•„๋‹ˆ์ง€๋งŒ, React ๋‚ด๋ถ€ ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•œ ๊ถ๊ธˆ์ฆ์„ ํ•ด๊ฒฐํ•ด ์ค„ ๊ฒƒ์ด๋‹ค.

    ์ถ”๊ฐ€์ ์œผ๋กœ React์˜ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ๊ณผ ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๋ช…ํ•˜๋Š” ๋‹ค์Œ์˜ ๊ธ€๋„ ์œ ์šฉํ•˜๋‹ค. ๋‚˜๋งŒ์˜ ๋ฆฌ์•กํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋งŒ๋“ค๊ธฐ

    ํŠœํ† ๋ฆฌ์–ผ

    Canvas StarCraft

    HTML canvas element๋ฅผ ์ด์šฉํ•ด ์Šคํƒ€ํฌ๋ž˜ํ”„ํŠธ ์œ ๋‹› ์„ ํƒ ๋ฐ ์ด๋™์„ ํ‰๋‚ด ๋‚ด์–ด ๊ตฌํ˜„ํ•œ ๊ธ€์ด๋‹ค.

    GIF์™€ ํ•จ๊ป˜ ์ž์„ธํ•œ ๊ตฌํ˜„ ๋‚ด์šฉ์ด ๋‹ด๊ฒจ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•ด ๋ณด๋ฉด ์ข‹์„ ๋“ฏํ•˜๋‹ค.

    How to Create and Publish a React Component Library

    Custom React Component๋ฅผ ๋งŒ๋“ค๊ณ  NPM์„ ํ†ตํ•ด ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ธ€์ด๋‹ค.

    ํ•œ ๋‹จ๊ณ„์”ฉ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜์—ฌ Custom React Component๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ์ด๋ผ๋ฉด ๋ˆ„๊ตฌ๋ผ๋„ ์‰ฝ๊ฒŒ ๋”ฐ๋ผ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

    RegexLearn

    ์ •๊ทœ ํ‘œํ˜„์‹์„ interactive ํ•˜๊ฒŒ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋Š” ์‚ฌ์ดํŠธ์ด๋‹ค. ์ด 55๊ฐœ์˜ ๋ฌธ์ œ๋ฅผ ๊ฐ„๋‹จํ•œ ์„ค๋ช…์„ ํ†ตํ•ด ํ•™์Šตํ•˜๊ณ  ํ’€์–ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค. Playground๋Š” ์ค€๋น„ ์ค‘์ด๋‹ค.

    Using WebAssembly (created in Rust) for Fast React Components

    ๋ณด๋‹ค ๋น ๋ฅธ React ์ปดํฌ๋„ŒํŠธ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด wasm(Rust๋กœ ์ž‘์„ฑ๋œ)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋ฉฐ, Rust๋ฅผ ์‚ฌ์šฉํ•ด wasm ์ปดํŒŒ์ผ ๋ฐฉ๋ฒ•๊ณผ ์ดํ›„ ํ”„๋กœ์ ํŠธ์—์„œ wasm์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ์„ค์ • ๋ฐฉ๋ฒ• ๋“ฑ ๊ฐ ๋‹จ๊ณ„๋ณ„ ํ•„์š”ํ•œ ์ž‘์—…๋“ค์„ ์†Œ๊ฐœํ•œ๋‹ค.

    ์˜ˆ์ œ ์ฝ”๋“œ ์ €์žฅ์†Œ

    import React, { useState } from "react";
    import ReactDOM from "react-dom";
    
    const wasm = import("../build/rusty_react");
    
    wasm.then(m => {
      const App = () => {
        const [name, setName] = useState("");
        ...
        return (
          <> ...  </>
      };
    
      ReactDOM.render(<App />, document.getElementById("root"));
    });
    

    ์ฝ”๋“œ์™€ ๋„๊ตฌ

    Hasty: A JavaScript Snippet Perfomance Comparison Tool

    JavaScript์˜ ํŠน์ • ํ•จ์ˆ˜์— ๋Œ€ํ•ด ๊ฐ„๋‹จํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ์„ฑ๋Šฅ์„ ์ธก์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์›น์‚ฌ์ดํŠธ๋‹ค. ๋น„์Šทํ•œ ๋„๊ตฌ๋กœ๋Š” perf.link์™€ jsBench๊ฐ€ ์žˆ๋‹ค.

    FxTS

    ๊ตญ๋‚ด ํšŒ์‚ฌ์ธ Marpple์—์„œ ๊ณต๊ฐœํ•œ TypeScript ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. ์•„์ง Beta ๋ฒ„์ „์ด๊ธด ํ•˜์ง€๋งŒ ์ง€์—ฐ ํ‰๊ฐ€, ๋™์‹œ์„ฑ ์ œ์–ด, ํƒ€์ž… ์ถ”๋ก , ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋“ฑ์—์„œ ๊ฐ•์ ์„ ๊ฐ€์ง„๋‹ค๊ณ  ํ•œ๋‹ค.

    React Spectrum Libraries

    Adobe์—์„œ ๋งŒ๋“  React UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

    Netlify Drop

    ์ •์  ์›น ์‚ฌ์ดํŠธ ๋ฐฐํฌ๋กœ ์œ ๋ช…ํ•œ Netlify์—์„œ Netlify Drop์ด๋ž€ ์„œ๋น„์Šค๋ฅผ ๊ณต๊ฐœํ–ˆ๋‹ค.

    ์ด๋ฅผ ํ†ตํ•ด HTML, CSS, JavaScript๋กœ ๊ตฌ์„ฑ๋œ ํด๋”๋ฅผ drag and dropํ•˜์—ฌ ์˜ฌ๋ฆฌ๋ฉด ๊ฐ„๋‹จํžˆ ๋ฐฐํฌ๊ฐ€ ์ง„ํ–‰๋˜๊ณ  URL์„ ํ†ตํ•ด ์ ‘๊ทผํ•ด ํ™•์ธํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

    Remix

    Remix๋Š” ์ง€๋‚œ 1๋…„์—ฌ ์ „ "sponsorware" ํ˜•ํƒœ๋กœ ์‹œ์ž‘ํ•ด ์Šคํฐ์„œ์‹ญ ์ฐธ์—ฌ์ž๋“ค๋งŒ ์ œํ•œ์  ์‚ฌ์šฉ ๋ผ์ด์„ ์Šค๊ฐ€ ๋ถ€์—ฌ๋˜์—ˆ๋˜ SSR์„ ์ง€์›ํ•˜๋Š” ์ƒˆ๋กœ์šด React ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ๋‹ค. React ์ƒํƒœ๊ณ„์—์„œ ๋ผ์šฐํŒ… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์œ ๋ช…ํ•œ React Router๋ฅผ ๊ฐœ๋ฐœํ•œ Michael Jackson์ด ์ฐธ์—ฌํ•˜๊ณ  ์žˆ์–ด, ์ƒํƒœ๊ณ„์—์„œ ๋†’์€ ๊ด€์‹ฌ๊ณผ ์ฃผ๋ชฉ์„ ๋ฐ›๊ณ  ์žˆ์—ˆ๊ณ  ์ตœ๊ทผ์˜ 3๋ฐฑ๋งŒ ๋‹ฌ๋Ÿฌ์˜ ์‹œ๋“œ ํŽ€๋”ฉ ํˆฌ์ž๋ฅผ ํ†ตํ•ด ๋ชจ๋“  ์ด๋“ค์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก MIT ๋ผ์ด์„ ์Šค๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค.

    Remix์— ๋Œ€ํ•œ ๋ณด๋‹ค ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜๋ผ.

    puppeteer-extra

    puppeteer-extra๋Š” Puppeteer์˜ drop-in replacement ๋ž˜ํผ๋กœ ๋‹ค์–‘ํ•˜๊ณ  ์œ ์šฉํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    const puppeteer = require("puppeteer-extra");
    
    // puppeteer-extra-plugin-stealth ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ๋‹ค์–‘ํ•œ ํšŒํ”ผ ๊ธฐ์ˆ ์„ ํ†ตํ•ด puppeteer(headless)์˜ ํƒ์ง€๋ฅผ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ ๋‹ค.
    const StealthPlugin = require("puppeteer-extra-plugin-stealth");
    
    puppeteer.use(StealthPlugin());
    

    Doom Nukem CSS

    ์ผ๋ฐ˜์ ์œผ๋กœ ์›น์—์„œ์˜ ๊ฒŒ์ž„์€ Canvas๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” 4๋…„ ์ „ ์‹œ์ž‘๋˜์–ด FPS ๊ฒŒ์ž„์˜ ์‹œ์ดˆ๋ผ ํ•  ์ˆ˜ ์žˆ๋Š” Doom์„ Canvas๊ฐ€ ์•„๋‹Œ HTML/CSS/TypeScript๋งŒ์„ ํ™œ์šฉํ•ด ๊ตฌํ˜„ํ•œ ๊ฒƒ์ด ํŠน์ง•์ด๋‹ค. ์ง์ ‘ ๊ฐœ๋ฐœํ•œ ReactCasting HTML ๊ด‘์„  ํˆฌ์‚ฌ(Ray Casting) ์—”์ง„์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

    Live demo

    Type<Challenge[]>

    TypeScript์— ์ต์ˆ™ํ•ด์ง€๊ณ  ์‹ถ์€ ๋ถ„๋“ค์„ ์œ„ํ•œ ์‚ฌ์ดํŠธ. ํ•ด๊ฒฐํ•ด์•ผ ํ•  ํƒ€์ž… ๋ฌธ์ œ๋ฅผ ์ฃผ๊ณ  TypeScript Playground์—์„œ ๋„์ „ํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค. TypeScript๋ฅผ ์ตํžˆ๋Š”๋ฐ ๋งŽ์€ ๋„์›€์ด ๋˜๋Š” ์‚ฌ์ดํŠธ์ด๋‹ค.