ゼネットの西村です。
業務でNode.jsのバージョンアップ対応を行ったので、
その際に役立った知識を紹介したいと思います!
はじめに
Node.jsのバージョンアップを行った際に役に立ったNode.js関連の知識や
「どこかにまとまっていれば良いのになぁ」と感じた内容を備忘録的に紹介していこうと思います。
間違ったことが記載されておりましたら、
コメントで指摘いただけますと幸いですm(_ _)m
Node.jsについて知る前に
Node.jsについて知る前にJavaScript(以下:JS)について知っておくべきことがあります。
本来、JSはSafariやChromeなどといったブラウザ上でのみ動作する言語になります。
ブラウザ上で動作する言語であるため、もちろんサーバサイドにアクセスすることはできません。
そんなJSのブラウザ上のみでしか使えないという制限を解消し、
サーバサイドでも動作できるようにしてくれるのがNode.jsなのです。
Node.jsについて
Node.jsの概要
Node.jsはサーバサイドでJSを動作させるための実行環境と呼ばれることが多いです。
重要なのが実行環境であるというところです。
ここで言う実行環境を簡単に説明すると、
「プログラミングを動作させるために必要な要素が用意されている環境」のことを指します。
ですので、フレームワークのようにプログラムの雛形が用意されているものとは、
全くの別物であるということを認識しておく必要があります。
Node.jsのライフサイクル
2024年6月現在に公開されているリリーススケジュールです。
EOLは偶数系はリリースから3年後に、奇数系はリリースから8ヶ月後に迎えます。
偶数系と奇数系でのライフサイクルに違いがあるのは、その用途が異なるためです。
偶数系について
偶数系は安定版として提供されています。
また、長期サポートの対象になっているのも特徴として挙げられます。
通常の開発では一般的に偶数系を使用してプロダクト構築が行われます。
奇数系について
奇数系は最新機能が取り込まれていることが特徴になります。
ただし、長期サポートの対象外になっていることから不具合の原因にもなりやすいため、
用途としてはNode.jsの最新機能を試したい場合に限り実験的に使用するのが望ましいと考えられます。
開発小話①
開発小話では私が対応している際に感じたことや学んだことを記載しております。
Node.jsのバージョンアップ時に「どのバージョンを使用するか」というお話しがありました。
その際に「そもそも偶数系と奇数系でライフサイクルが異なる」ことに気づきました。
調査したところ先述の違いが判明し、結果的に偶数系の当時の最新バージョンに上げることになりました。
何かしらのバージョンを上げる際にバージョンの違いによる変更内容はチェンジログなどで確認すると思いますが、バージョンの違いで用途が異なるなど思わぬ違いがあるかもしれません。この対応で調査は一層慎重に作業する必要があるなと再認識しました。
パッケージの管理とビルド工程の処理の流れ
ここからはNode.jsを実行環境にしたビルドなどの処理について解説していきます。
Node.jsを実行環境とする処理の例
上図の様にパッケージ管理もビルド工程もNode.jsを実行環境に使用します。
また、npmはNode.jsを入れると、インストールしたNode.jsのバージョンに
対応したnpmがインストールされます。
続いてパッケージ管理とビルド工程それぞれについて詳しく見ていきましょう。
npmでのパッケージ管理処理
npmを利用した処理の流れは以下になります。
図では赤の枠線で囲まれている箇所がnpmでの処理になります。
- package.jsonにパッケージを定義
npm install
の実行でpackage.jsonの内容を元に
node_modulesにパッケージがインストールされる- node_modulesに実際にインストールされたパッケージのバージョン情報がpackage-lock.jsonに記述される
yarnでのパッケージ管理処理
yarnを使用した場合のパッケージ管理処理もnpmでの管理と同様になりますが、lockファイルの名称が異なります。
- package.jsonにNode.jsのパッケージを定義
yarn install
(またはyarn
)の実行により、
package.jsonの内容を元にnode_modulesにパッケージがインストールされる- node_modulesに実際にインストールされたパッケージのバージョン情報がyarn.lockに記述される
ビルド工程
続いてビルド工程について紹介していきます。
図の赤い枠線で囲まれている箇所がビルド工程になります。
- npm(またはyarn)によりインストールした
コンパイラ・トランスパイラ(file-loader
、babel
)をwebpack.config.jsのloaderに設定 - package.jsonに定義されている
buildコマンド
を使用してbuildを実行 - webpack.config.jsに設定したloaderにより、画像やReactがコンパイル・トランスパイルされる
- コンパイル・トランスパイルされた内容をwebpackがバンドルして、
ブラウザで実行可能なJSファイルを出力する
開発小話②
npmとyarnは同様にパッケージ管理ツールではありますが、ひと昔前のバージョンでは以下の性能面・機能面での違いからyarnを利用するケースがありました。
- 機能面での違いはnpmは以前は「lockファイル」が存在しておりませんでした。
ですがyarnには「lockファイル」が存在したことから、npmよりもyarnの方がパッケージ管理をより厳密に行える状況でした。
(*npmにもver 5から「lockファイル」が追加されました。参考:npm Blog Archive: v5.0.0) - 性能面での違いはyarnの方がnpmよりも処理が速いなどありました。(参考:GitHub - appleboy/npm-vs-yarn: npm vs yarn install speed testing.)
(*現行に近いバージョンでもyarnの方が少し処理速度が速いようです。参考:npmとyarnのどちらが速いの?(2023/11/26))
同じパッケージ管理ツールでも性能に差があったりするので、ミドルウェアを選ぶ際に同様の機能を持った物が複数ある場合は、その性能の差などをしっかりと吟味する必要があると痛感しました。
Bebelについて
ここまでNode.jsについて話してきましたが、続いてはReactなどを使用する場合に多く利用されるBabelについて紹介していこうと思います!
Babelとは
Babel公式での紹介がこちらになります。
Babel は、ECMAScript 2015 以降のコードを、現在のブラウザーや環境、古いブラウザーや環境で下位互換性のあるバージョンの JavaScript に変換するために主に使用されるツールチェーンです。
何だか難しいことを言ってますね。。。
ざっくりとですがBabelは
「JavaScriptの新しい書き方を古い環境でも使用できる形式にしてくれる」
ということです!
Babel 6系以前と7系での変更について
Babel 7系からBabel公式が出しているパッケージの名前に変更が入りました。
具体的にはBabel 7系以降では公式のパッケージ名に@babelが先頭につくようになりました。
@babelが先頭につくパッケージのことをscoped packageと呼びます。
この命名変更により公式パッケージとサードパーティー製のパッケージを名前から区別できる様になりました。
上記に記載したのはBabel 7系で変更が入ったパッケージの一例です。
その他にも変更されたパッケージは存在するので、確認してみてください!
Babel 7系へのマイグレーションについて
Babel 7系へのマイグレーションにはbabel-upgradeというBabel公式から提供されているマイグレーションツールを使用します。
babel-upgradeの使用方法
babel-upgradeの使用方法は以下になります。
(*詳細なマイグレーション手順はbabel-upgradeを確認してください)
-
babel-upgradeをインストールする
-
Babel 6系のプロダクトの
package.json
が存在する階層でnpx babel-upgrade --write
を実行する
babel-upgradeでのマイグレーションの注意点
また、babel-upgradeを使用するにあたって以下の点に注意しなければなりません。
-
babel-upgradeを使用するにはNode.js 8系以降が必要
-
webpack.config.js
などの設定ファイルは更新されないため、
開発環境によってはbabel-upgradeを利用しても完全にアップグレードを行えない可能性もある
開発小話③
Babelの機能として「JavaScriptの新しい書き方を古い環境でも使用できる形式にしてくれる」という内容を紹介しました。
少し具体的な話をするとES6(ECMAScript2015)の記述がIE(Internet Explorer)では上手く動作しないので、Babelを利用して動作できるようにするなどです。
ですが、IEが2022年6月16日に開発が終了されたことを受け、Babelの必要性について再度考える必要が出てきました。
プロダクトをIEで動作させることがなくなったのであれば、Babelは不要ではないのかという疑問を解決しなければならなくなったのです。
この疑問の結論としては、詳細については省きますがReactなどのフレームワークを使用している場合はトランスパイラーとしての機能を担っているBabelを外すことは難しいという結果になります。
この対応では一見不要に思えるミドルウェアについても「本当に不要なのか」と問いを持って確認する必要があるということを学びました。
最後に
最後まで読んでいただきありがとうございます。
今回の記事には載せられなかった内容については、
機会があれば後日投稿するかもしれません。
その際はまた読んでいただけますと幸いです。
また、技術的に間違っていることが記載されておりましたら、
お手数ですがコメントで指摘いただけますと幸いです。
参考リンク
脚注
*1:図中に示したのパッケージには現在は非推奨のものも含まれておりますのでご注意ください。