Node.js v20 LTSに向けて

# 背景
- Node.js v20が10/24にLTSになる為

# 目次
1. そもそもNode.jsとは
2. Node.jsのMajor番号とリリーススケジュール
3. Node.js v20の主なChangeLog
4. その他参考
5. 感想

# 1. そもそもNode.jsとは
https://nodejs.org/en
>Node.js® is an open-source, cross-platform JavaScript runtime environment.

[クロスプラットフォーム](https://it-trend.jp/development_tools/article/32-0027#:~:text=%E5%8A%B9%E7%8E%87%E5%8C%96%E3%81%97%E3%82%88%E3%81%86-,%E3%82%AF%E3%83%AD%E3%82%B9%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%A8%E3%81%AF,-%E3%82%AF%E3%83%AD%E3%82%B9%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%A8)な非同期イベント駆動なJavaScript実行環境

- 非同期イベント駆動 = 非同期駆動 + イベント駆動　とは
    >As an asynchronous event-driven
    
    非同期：コードを書くときに、すべての行が実行される正確な順序を予測しようとしないこと
    イベント駆動:ネットワークリクエストのような特定のイベントに反応して呼び出される小さな関数の集まりとしてコードを記述
    [Introduction: What is NodeJS?](https://www.theodinproject.com/lessons/nodejs-introduction-what-is-nodejs)

    以下ソースで動作確認します。
    https://github.com/yamatai12/node-asynchronous-event-driven-sample

    # 環境構築
    ローカル環境を汚さないし、環境構築なしですぐに検証できるのでDockerコンテナ内で開発します
    [【図解】Dockerの全体像を理解する -前編-](https://qiita.com/etaroid/items/b1024c7d200a75b992fc)
    # Dockerfile
    https://hub.docker.com/_/node/

    - node image
    node imageには様々な種類があり、それぞれが特定の用途向けに設計されています。
        >Image Variants
        The node images come in many flavors, each designed for a specific use case.

        - image verions
        ltsを使う
        ```node:<version>```

        - image tags
        Debian DistributionのCurrent LTSのbusterを採用
        ```node:lts-<tags>```
        [debian LTS time table from June 17, 2023](https://wiki.debian.org/LTS#:~:text=LTS%20time%20table%20from%20June%2017%2C%202023)
        [Choosing the best Node.js Docker image](https://snyk.io/blog/choosing-the-best-node-js-docker-image/)
        [How to Use the Node Docker Official Image](https://www.docker.com/blog/how-to-use-the-node-docker-official-image/)
            - bookworm,buster,bullseye
                - Debianのversionのコードネーム
            - alpine
                - Node.jsの公式サポートではない
                - 超軽量、主要なパッケージが不足している場合がある
            >The Node.js Docker team doesn’t officially support container image builds based on Alpine. 
            - hydrogen
                LTSのコードネーム([Nodejsのリリース一覧のLTSにHydrogenとありますが、これはなんでしょうか？](https://jp.quora.com/Nodejs%E3%81%AE%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E4%B8%80%E8%A6%A7%E3%81%AELTS%E3%81%ABHydrogen%E3%81%A8%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8C-%E3%81%93%E3%82%8C%E3%81%AF%E3%81%AA%E3%82%93%E3%81%A7))
                LTSとHydrogenがNodeのimageで別で書かれてるのが分からないので次回調べたいと思います。。
                

        - image variant
        ```node:lts-buster-<variant>```
            slimを採用
            - Docker image上のソフトウェアの[フットプリント](https://e-words.jp/w/%E3%83%95%E3%83%83%E3%83%88%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88.html)を小さくし、潜在的な脆弱性のベクトルを減らし、サイズを小さくすることで、イメージのビルドプロセスを高速化する([10-best-practices-to-containerize-nodejs-web-applications-with-docker](https://snyk.io/blog/10-best-practices-to-containerize-nodejs-web-applications-with-docker/))
            - slimが用意されているのは、公式バージョンとDebian系(3-slim, 3.0-slim, 3.0.1-slim, bullseye-slim, buster-slim)

        ```Dockerfile:Dockerfile
        FROM node:lts-buster-slim
            
        WORKDIR /app
        ```
    
        # docker-compose.yml
        ```docker-compose.yml
        services:
          app:
            build:
              context: .
              dockerfile: Dockerfile
            volumes:
              - ./app:/app
            command: sh -c "node --version"
        ```
- [Docker Composeについてざっくり理解する【概要】【ymlファイル書き方】【コマンド操作】](https://qiita.com/gon0821/items/77369def082745d19c38)
- [docker-composeでvolumesを設定する](https://zenn.dev/ajapa/articles/1369a3c0e8085d)
- [Docker image(イメージ)の違い:alpine,bullseye, buster, slim, stretch, jessie, slim-buster, windowsservercore, latestどれを選ぶべきか？](https://prograshi.com/platform/docker/docker-image-tags-difference/)

    # asynchronous-event-driven.js
    ```index.js
    console.log("start asynchronous-event-driven");
    const fs = require('fs');
    fs.readFile("sample.txt", "utf-8", function(err, data){
      if (err) throw err;
      console.log("File Read Successful!!");
      console.log(data);
    });
    console.log("end asynchronous-event-driven");
    ```

    # sample.txt
    ```sample.txt
    File contents
    ```

    # index.jsの実行
    ```:terminal
        docker-compose run --rm app /bin/sh -c "node asynchronous-event-driven.js"
        start asynchronous-event-driven
        end asynchronous-event-driven
        File Read Successful!!
        File contents
    ```
    コンソールへの出力を確認すると，ファイル読み込みが飛ばされている。
    これは「ファイルの読み出しが可能になった」というイベントの発生をトリガーにコールバック関数が実行される為、出力が前後している。
    一見すると複雑にしているように見えるが，このおかげで，大量のアクセスを処理することができる。
    非同期的/ノンブロッキング的な動きをしている。
    - ブロッキング
        Node.js プロセス内の後続のJavaScriptの実行が、JavaScript以外の操作(I/O:入出力処理,c言語で書かれてる[libuv](https://libuv.org/))が完了するまで待たなればならないこと([ブロッキングとノンブロッキングの概要](https://nodejs.org/ja/docs/guides/blocking-vs-non-blocking))
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/8d0faf87-1069-2225-a138-412e7919a0c1.png)
(https://tamotech.blog/wp-content/uploads/2020/07/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2020-07-14-16.58.39-1024x866.png)
こちら参考に厳密な仕組みについて勉強しておきます。。
[Node.jsでのイベントループの仕組みとタイマーについて](https://hiroppy.me/blog/nodejs-event-loop#%E3%82%BF%E3%82%B9%E3%82%AF)


- フロントエンドのイベント
    window,documentが対象
    例）JavaScriptでaddEventListenerを使って、マウスクリックやキーボード押下などのユーザーアクションを待つ等
- Node.jsのイベント ネットワーク・リクエストやデータベース・クエリ

参考
- [非同期型イベント駆動とは 〜 JSおくのほそ道 #001](https://qiita.com/hosomichi/items/16597eaabb1226975c51)
- [Node.jsの実行環境の基本は抑えとけ！](https://tamotech.blog/2020/07/14/nodejs-asynchronouse-event-driven/)

# 2. Node.jsのMajor番号とリリーススケジュール
[そもそもSemantic Versioningとは](https://semver.org/)

本番アプリケーションのMajor番号は偶数にするべき
```
奇数:半年後→サポートされない
偶数:半年後→Active LTS
    （long-term support　長期サポート、重大なバグ修正）ステータスに移行
```

[Releases](https://nodejs.dev/en/about/releases/#:~:text=Previous%20Releases-,Releases,-Major%20Node.js)
>Major Node.js versions enter Current release status for six months, which gives library authors time to add support for them. After six months, odd-numbered releases (9, 11, etc.) become unsupported, and even-numbered releases (10, 12, etc.) move to Active LTS status and are ready for general use.


>LTS release status is "long-term support", which typically guarantees that critical bugs will be fixed for a total of 30 months. Production applications should only use Active LTS or Maintenance LTS releases.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/d2c9a453-ccd1-b52f-33a7-83b1473a4b9d.png)

# 3. Node.js v20の主なChangeLog
[ChangeLog](https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V20.md#20.6.1)

- Test Runner
  [jest](https://jestjs.io/)等のテスティングライブラリほどの機能はないが徐々に機能が追加されている

- V8 JavaScriptエンジンの新しいバージョン（バージョン11.3）
  - String.prototype.isWellFormedとtoWellFormed
    - JavaScriptの文字列はUTF-16でエンコードされている。
   カスタム実装の必要なく、文字列がUTF-16かどうかを調べることができる。
また、isWellFormed()はV8エンジン(Node.jsは内部的にGoogle V8 JavaScriptエンジンを使ってコードを実行)が文字列の内部表現に直接アクセスするのでより効率的。
[MDN String.prototype.isWellFormed()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/isWellFormed)
    
  - ArrayとTypedArrayのコピーメソッド
    - toSorted、toReversed、toSpliced、with メソッドにより、配列のデータを変更せずに、コピーを作成してそのコピーを変更
    [ES2023 introduces new array copying methods to JavaScript](https://www.sonarsource.com/blog/es2023-new-array-copying-methods-javascript/)
  - ArrayBufferとSharedArrayBufferがサイズ変更可能になった
    - [そもそもArrayBufferとは](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)
        >The ArrayBuffer object is used to represent a generic raw binary data buffer. It is an array of bytes, often referred to in other languages as a "byte array".

        [JavaScriptでバイナリデータを扱ってみる](https://qiita.com/megadreams14/items/dded3cf770010bb8ff08)
        用途について理解したいと思った。。勉強します。
  - set記法+文字列プロパティを持つRegExp vフラグ
    以下にまとめました。
    [正規表現　vフラグ](https://qiita.com/yamatai12/items/28d5ed6fa8ea8ebc81d7)
  - WebAssembly Tail Call
      [WebAssemblyとは](https://webassembly.org/)
    >WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.

    いまいち分からないのでこちらを見てみると
    [WebAssemblyとは？できること・できないこと・使い方をわかりやすく解説](https://staff.persol-xtech.co.jp/hatalabo/it_engineer/641.html#_1)
    Webブラウザ、サーパアプリケーションでコンパイルされたC/C++やRustを実行する仕組み（アセンブラ）を指すもの
こちらも勉強しておきます。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/78b0a728-a840-04a2-700e-f2d062e5e3cc.png)
(https://staff.persol-xtech.co.jp/hatalabo/wp-content/uploads/2023/02/it641_01.webp)

参考
- [Node.js 20: New Features, Updates, and Improvements](https://www.itmagination.com/blog/introducing-node-js-20-new-features-updates-and-improvements)
- [Node.js v20の新機能（テストランナー、Permission Model、SEA、V8 JS Engine 11.3）](https://kinsta.com/jp/blog/node-js-20/)
- [別にしんどくないブログ](https://shisama.hatenablog.com/entry/2023/04/24/083000#V8-113-%E3%81%AB%E3%82%88%E3%82%8B%E6%96%B0%E3%81%97%E3%81%84-JavaScript-%E3%81%AE%E6%A9%9F%E8%83%BD)
- [Node.js v20 から使える ECMAScript の新機能](https://zenn.dev/sosukesuzuki/articles/ad3b2bca5f9259)

# 4.その他参考
- [Qiita Markdown 書き方 まとめ](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)
- [Google社のテクニカルライティングの基礎教育資料がとても良かったので紹介したい](https://qiita.com/yasuoyasuo/items/c43783316a4d141a140f)

# 5.感想
- まだNode.jsの仕組みがわかってない（イベントループ等）ので勉強しないといけない。
- Node.jsのソースを見るとcだったり、pythonだったり色んな言語で書かれていて興味深かった。いつかissue起票したり、discussionに参加したい。
https://github.com/nodejs/node#:~:text=%2B%203%2C275%20contributors-,Languages,-JavaScript
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/3e1862dc-bd27-f0f5-de70-cb3c7b911449.png)
- WebAssembyについても勉強したい。

## 参考になる記事を書いてくださった皆様ありがとうございました！

# 宣伝させてください！
https://recruit.iimon.co.jp/