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

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

    2022-06

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

    Web at IO 2022

    ๊ตฌ๊ธ€์˜ ๊ฐœ๋ฐœ์ž ์—ฐ๋ก€ ํ–‰์‚ฌ์ธ Google I/O 2022๊ฐ€ ์ง€๋‚œ 5์›” 11~12์ผ ์ง„ํ–‰๋˜์—ˆ์œผ๋ฉฐ, Web at IO 2022๋Š” ์ด๋“ค ์ค‘ 23๊ฐœ์˜ ์›น ์„ธ์…˜๋“ค์— ๋Œ€ํ•œ ์žฌ์ƒ ๋ชฉ๋ก์ด๋‹ค. ์›น ํ”Œ๋žซํผ, ๊ฐœ๋ฐœ์ž ๋„๊ตฌ, ๋ฐ˜์‘ํ˜• ํŽ˜์ด์ง€์˜ ํ˜„์ฃผ์†Œ, ์„ฑ๋Šฅ, PWA ๋“ฑ ๋‹ค์ฑ„๋กœ์šด ์ƒˆ๋กœ์šด ์†Œ์‹๋“ค๋กœ ๊ฐ€๋“ ์ฐจ ์žˆ๋‹ค. ์›น์˜ ์ตœ์‹  ๋™ํ–ฅ์„ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์‚ดํŽด๋ณด๊ธฐ๋ฅผ ์ถ”์ฒœํ•œ๋‹ค.

    [์ฐธ๊ณ ] ์žฌ์ƒ ๋ชฉ๋ก์—๋Š” ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ, ์ด์–ด์„œ State of CSS๋„ ํ•จ๊ป˜ ์‚ดํŽด๋ณด๋ฉด ์ข‹๋‹ค.

    Meta Open Source is transferring Jest to the OpenJS Foundation

    ์ง€๋‚œ FE News '22/3์›” ์†Œ์‹์„ ํ†ตํ•ด์„œ ์ˆ˜๋…„๊ฐ„ Jest์— ๊ธฐ์—ฌํ•˜๋Š” ๋ฉ”ํƒ€ ์†Œ์† ๊ฐœ๋ฐœ์ž๋“ค์ด ์—†์—ˆ๋‹ค๋Š” ์†Œ์‹์„ ๊ณต์œ ํ•œ ๋ฐ” ์žˆ์—ˆ๋Š”๋ฐ, ๊ทธ ์†Œ์‹์— ์ด์–ด ์ง€๋‚œ 5์›” 11์ผ, Meta๋Š” Jest ํ”„๋กœ์ ํŠธ๋ฅผ OpenJS ์žฌ๋‹จ์œผ๋กœ ์ด๊ด€์„ ์ง„ํ–‰ํ•œ๋‹ค๋Š” ์†Œ์‹์„ ๋ฐœํ‘œํ–ˆ๋‹ค.

    Jest์˜ ๊ฐœ๋ฐœ์€ ๊ธฐ์กด๊ณผ ๊ฐ™์ด ํ˜„์žฌ์˜ ์ฝ”์–ด ํŒ€์— ์˜ํ•ด ๋ฆฌ๋”ฉ ๋˜๋ฉฐ, ์ด๊ด€์— ๋”ฐ๋ผ ํฌ๊ฒŒ ๋‹ฌ๋ผ์ง€๋Š” ๊ฒƒ์€ ์—†์„ ๊ฒƒ์ด๋ผ๊ณ  ๋ฐํ˜”๋‹ค. ํ–ฅํ›„ ๋ช‡ ๋‹ฌ๊ฐ„ Jest์˜ ์ž์‚ฐ(๋„๋ฉ”์ธ, ์ €์žฅ์†Œ, ์›น์‚ฌ์ดํŠธ ๋“ฑ)์ด ์ด๊ด€๋˜๋ฉฐ, ์ด๊ด€์— ๋”ฐ๋ฅธ ์ƒˆ๋กœ์šด ์ •์ฑ… ๋“ฑ์„ ์ˆ˜๋ฆฝํ•  ๊ณ„ํš์ž„์„ ๋ฐํžˆ๊ณ  ์žˆ๋‹ค.

    New from Anaconda: Python in the Browser

    Anaconda๊ฐ€ PyCon US 2022์—์„œ PyScript ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐœํ‘œํ•˜์˜€๋‹ค.

    PyScript๋Š” Python ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์›น์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค. JS์—์„œ Python, Python์—์„œ JS๋กœ ์–‘๋ฐฉํ–ฅ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ•œ๋‹ค. ์ฆ‰, Python์ด DOM์„ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ ๋“ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

    ๋‹ค์Œ์€ ๊ฐ„๋‹จํžˆ Pi ๊ฐ’์„ ๊ณ„์‚ฐํ•ด ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๋Š” ์˜ˆ์‹œ์ด๋‹ค:

    <html>
      <head>
        <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
        <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
      </head>
      <body>
          <py-script>
    print("Let's compute ฯ€:")
    def compute_pi(n):
        pi = 2
        for i in range(1,n):
            pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
        return pi
    
    pi = compute_pi(100000)
    s = f"ฯ€ is approximately {pi:.3f}"
    print(s)
          </py-script>
      </body>
    </html>
    

    ๋” ๋งŽ์€ ์˜ˆ์‹œ๋Š” https://pyscript.net/examples/ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

    React may be getting a new hook โ€” useEvent

    ์ง€๋‚œ 5์›” 4์ผ, useEvent๋กœ ๋ช…๋ช…๋œ ์ƒˆ๋กœ์šด ํ›…์— ๋Œ€ํ•œ ์ œ์•ˆ์ด RFC๋กœ ์ œ์ถœ๋˜์—ˆ์œผ๋ฉฐ, ํ•ญ์ƒ ์•ˆ์ •์ (always-stable)์ธ ํ•จ์ˆ˜ ์•„์ด๋ดํ‹ฐํ‹ฐ๋ฅผ ๊ฐ–๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

    // ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ state/props๋ฅผ ์ฝ์œผ๋ฉด ์ตœ์ ํ™”๊ฐ€ ์ค‘๋‹จ๋œ๋‹ค.
    function Chat() {
      const [text, setText] = useState('');
    
      // 1) ์žฌ๋ Œ๋”๋ง์‹œ, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์˜ ์•„์ด๋ดํ‹ฐํ‹ฐ๋Š” ๋งค๋ฒˆ ๋‹ฌ๋ผ์ง„๋‹ค.
      const onClick = () => {
        sendMessage(text);
      };
    
      // 2) `text`์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์˜ ์•„์ด๋ดํ‹ฐํ‹ฐ๋„ ๋‹ฌ๋ผ์ง„๋‹ค.
      const onClick = useCallback(() => {
        sendMessage(text);
      }, [text]);
    
      return <SendButton onClick={onClick} />;
    }
    
    // useEvent Hook
    function Chat() {
      const [text, setText] = useState('');
    
      // ํ•ญ์ƒ ๋™์ผํ•œ ํ•จ์ˆ˜๊ฐ€ ์ œ๊ณต๋œ๋‹ค. (`text`๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ๊ทธ๋Ÿฌํ•˜๋‹ค)
      const onClick = useEvent(() => {
        sendMessage(text);
      });
    
      return <SendButton onClick={onClick} />;
    }
    

    How to use Decorators in JavaScript

    ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(@)๋ฅผ ์ ์šฉํ•œ JavaScript ์ฝ”๋“œ๋Š” ์–ด๋ ต์ง€ ์•Š๊ฒŒ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ, ๋ณดํ†ต์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค(e.g. core-decorators.js) ํ˜น์€ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋‚ด์žฅ๋œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ง์ ‘ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด ๋ณธ ๊ฒฝํ—˜์€ ์ƒ๊ฐ๋ณด๋‹ค ํ”์น˜ ์•Š์„ ๊ฒƒ์ด๋‹ค.

    ๋ณธ ๊ธ€์—์„œ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•œ ์„ค๋ช…๋ถ€ํ„ฐ ์–ด๋–ป๊ฒŒ ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€ ์„ค๋ช…ํ•œ๋‹ค.

    ๋‹ค์Œ์€ ํ•„๋“œ์˜ ์žฌํ• ๋‹น์„ ๋ง‰์•„์ฃผ๋Š” locked ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์˜ˆ์‹œ์ด๋‹ค:

    function locked(target, key, descriptor) {
      return {
        ...descriptor,
        writable: false,
      };
    }
    
    class Data {
      @locked
      password = 'mypwd';
    }
    

    ์ฐธ๊ณ ๋กœ, ํ˜„์žฌ JavaScript์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์€ babel๊ณผ ๊ฐ™์€ transpiler์˜ ํž˜์„ ๋นŒ๋ ธ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด๋‹ค. ์ฆ‰, ํ˜„์žฌ๋กœ์„œ๋Š” ํ‘œ์ค€์ด ์•„๋‹ˆ๋‹ค.

    ์ตœ๊ทผ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ‘œ์ค€์œผ๋กœ ์ง€์ •ํ•˜๊ณ ์ž ํ•˜๋Š” ํ”„๋Ÿฌํฌ์ ˆ์ด stage 3๊นŒ์ง€ ์˜ฌ๋ผ์™”๋‹ค. ๋ณธ ๊ธ€์€ ํ•ด๋‹น ํ”„๋Ÿฌํฌ์ ˆ๊ณผ ๋‹ค์†Œ ๊ตฌํ˜„์˜ ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜๊ธธ ๋ฐ”๋ž€๋‹ค.

    Announcement: Passing the torch

    Lerna ํ”„๋กœ์ ํŠธ์˜ ๋ฆฌ๋“œ ์—”์ง€๋‹ˆ์–ด์ธ Daniel Stockman์€ ํ”„๋กœ์ ํŠธ ๊ณต์ง€๋ฅผ ํ†ตํ•ด 5์›” 5์ผ๋ถ€๋กœ ๋ฒˆ์•„์›ƒ์œผ๋กœ ์ธํ•ด ๋ชจ๋“  ์ฑ…์ž„์—์„œ ๋ฌผ๋Ÿฌ๋‚  ๊ฒƒ์ด๋ผ๊ณ  ๋ฐํ˜”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ์ ํŠธ์˜ ์˜ค๋„ˆ์‹ญ์„ ๋˜ ๋‹ค๋ฅธ ์œ ๋ช…ํ•œ ๋ชจ๋…ธ๋ ˆํฌ ๋„๊ตฌ์ธ Nx์˜ ๊ฐœ๋ฐœ์‚ฌ์ด๊ธฐ๋„ ํ•œ Nrwl๋กœ ์ด์ „ํ•œ๋‹ค๊ณ  ๋ฐํ˜”๋‹ค.

    ํŠœํ† ๋ฆฌ์–ผ

    The DOM Challenge

    Front-end ๋ฌธ์ œ๋กœ ์ด๋ฃจ์–ด์ง„ ์ฑŒ๋ฆฐ์ง€์ด๋‹ค. HTML + CSS + Vanilla JS๋ฅผ ์ด์šฉํ•ด ํ’€์–ด์•ผ ํ•œ๋‹ค. Front-end ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ํ•œ๋ฒˆ ๋„์ „ํ•ด ๋ณด์•„๋„ ์ข‹์„ ๋“ฏํ•˜๋‹ค.

    Web Audio Modem

    Web Audio API๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๊ณ  ๋””์ฝ”๋”ฉ ํ•ด, ๊ฒฐ๊ณผ์ ์œผ๋กœ ์‹œ๊ทธ๋„์„ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ์ „์†ก์ด ๊ฐ€๋Šฅํ•œ ๋ชจ๋Ž€์˜ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•œ๋‹ค.

    ์ €์ž๋Š” ์ธํ„ฐ๋„ท์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์—…๋ฌด ํ™˜๊ฒฝ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์†์‰ฝ๊ฒŒ ์ „์†กํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๊ณ ์•ˆํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค๊ฒŒ ๋˜์—ˆ์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ ์ธ์ฝ”๋”ฉ์€ Web Audio API์˜ OscillatorNode๋ฅผ ํ†ตํ•ด, ๊ทธ๋ฆฌ๊ณ  ๋””์ฝ”๋”ฉ AnalyserNode๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„๋˜์—ˆ๋‹ค.

    ๋ชจ๋˜ JavaScript ํŠœํ† ๋ฆฌ์–ผ

    ๋ชจ๋˜ JavaScript(ES6 ์ดํ›„)๋ฅผ ๋ฐฐ์šฐ๊ณ  ์‹ถ๋‹ค๋ฉด ์ด ์‚ฌ์ดํŠธ๋ฅผ ์ถ”์ฒœํ•œ๋‹ค. ์ฒด๊ณ„์ ์œผ๋กœ ๋ถ„๋ฅ˜๋˜์–ด ์žˆ์œผ๋ฉฐ, ํ•œ๊ธ€ํ™”๋„ ์ž˜ ๋˜์–ด ์žˆ์–ด ๋”ฐ๋ผ ํ•˜๋ฉด์„œ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค.

    nodejs.dev Learn

    OpenJS ์žฌ๋‹จ์—์„œ ์ง์ ‘ ์šด์˜ํ•˜๊ณ  ์žˆ๋Š” nodejs ํŠœํ† ๋ฆฌ์–ผ ์‚ฌ์ดํŠธ์ด๋‹ค. nodejs์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•ด ์‰ฝ๊ฒŒ ๋”ฐ๋ผ๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ์ž˜ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

    Building an Animated Piano Keyboard with JavaScript and MIDI

    ์ด ๊ธ€์—์„œ๋Š” ์žฌ์ฆˆ ํ”ผ์•„๋…ธ ํŠœํ† ๋ฆฌ์–ผ ์‚ฌ์ดํŠธ์—์„œ JavaScript์™€ MIDI๋กœ ํ”ผ์•„๋…ธ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ฐœ๋ฐœํ•œ ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•œ๋‹ค.

    ํ”ผ์•„๋…ธ ํ‚ค๋ณด๋“œ๋ฅผ ๊ทธ๋ฆฌ๋Š” ๋ฐ์—๋Š” SVG๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , MIDI๋ฅผ JSON ํ˜•์‹์œผ๋กœ ๋ฐ”๊พธ๋Š” ๋ถ€๋ถ„์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒํ•œ ์Œ์•…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์›น ์˜ค๋””์˜ค ํ”„๋ ˆ์ž„์›Œํฌ์ธ Tone.js๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋ฉฐ, ์˜ค๋””์˜ค๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ถ€๋ถ„์€ Howler.js๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค.

    ํ•ด๋‹น CodeSandbox์—์„œ ๋ฐ๋ชจ์™€ ์ฝ”๋“œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

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

    wireit

    NPM ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋” ์Šค๋งˆํŠธํ•˜๊ณ  ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ํˆด์ด๋‹ค. ๋ˆˆ์— ๋„๋Š” ํŠน์ง•์œผ๋กœ๋Š” Cross-package dependencies, Parallelism, Incremental build ๋“ฑ์ด ์žˆ๋‹ค. package.json์˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์กฐ๊ธˆ๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๊ธฐ์กด npm run ์ปค๋งจ๋“œ๋„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    TypeScript Error Translator

    TypeScript ์—๋Ÿฌ๋ฅผ ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ๋ฌธ์žฅ์œผ๋กœ ๋ฐ”๊พธ์–ด ์ฃผ๋Š” VSCode extension์ด๋‹ค.

    lexical

    Meta์—์„œ ์ƒˆ๋กœ ๋งŒ๋“  ํ…์ŠคํŠธ ์—๋””ํ„ฐ์ด๋‹ค. ์ด์ „์— React๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์—ˆ๋˜ ์—๋””ํ„ฐ Draft.js์™€ ๋‹ฌ๋ฆฌ, ๋ฐ”๋‹๋ผ JS๋กœ ๋งŒ๋“ค์—ˆ๋‹ค.

    design-resources-for-developers

    ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ UI, ๋””์ž์ธ ๋ฆฌ์†Œ์Šค๋“ค์„ ํ๋ ˆ์ด์…˜ ํ•ด ๋‘” Github ์ €์žฅ์†Œ์ด๋‹ค. ํฐํŠธ, ์•„์ด์ฝ˜, ์Šคํ†ก ์‚ฌ์ง„, ์›น ํ…œํ”Œ๋ฆฟ, CSS ํ”„๋ ˆ์ž„์›Œํฌ, ํฌ๋กฌ ์ต์Šคํ…์…˜ ๋“ฑ ๋งŽ์€ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค.

    Stacks

    ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๋ˆ„๊ตฌ๋‚˜ ์•Œ๊ณ  ์žˆ๋Š” ์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์˜ ๋””์ž์ธ ์‹œ์Šคํ…œ์ด๋‹ค.