初心者向け!Node.jsとJavaScriptで簡単に学ぶWebサーバーの作成方法

初心者向け!Node.jsとJavaScriptで簡単に学ぶWebサーバーの作成方法

この記事では、フレームワークを使用せずに純粋なNode.jsで構築された単純な静的ファイルサーバーを提供します。

Node.jsの現在の状態では、組み込みのAPIとわずか数行のコードによって、必要なほとんどすべてが提供されています。

Node.jsとは

Node.jsは、V8エンジンを使用して Webブラウザの外部でJavaScriptコードを実行するクロスプラットフォームオープンソースバックエンドのJavaScriptランタイム環境です。

Node.jsを使用すると、開発者はJavaScriptを利用してコマンドラインツールとサーバー側スクリプトを作成できます。

これには、ユーザーのブラウザにページを送信する前にサーバー上でスクリプトを実行することが含まれます。

Node.jsのインストール

Node.jsのインストールする方法はいくつかあります。

Node.jsの公式の日本語版ウェブサイトから、Node.js最新バージョンのインストーラーをダウンロードする

Node.jsのバージョン管理ツールでインストールする

公式サイトからNode.jsをZIPファイルからインストールし解凍する

Node.jsをパッケージマネージャーを使ってインストールする方法

Node.jsをオンラインのサービスを使用して実行する

まず、Node.jsをZIPファイルからインストールし解凍した場合、Node.jsのバイナリファイルが含まれるディレクトリを任意の場所に配置することができます。

ただし、使用する際には、Node.jsのパスをシステムの環境変数に追加する必要があります。

これは、Node.jsアップデートやバージョン管理を手動で行っていく必要があります。

また、ZIPファイルからインストールする場合、Node.js本体のセキュリティアップデートを自動的に適用できないため、セキュリティリスクがあります。

これらの理由のため、基本的にNode.jsをZIPファイルからインストールし解凍する方法は、推奨されていません。

Node.jsをオンラインのサービスを使用することもできます。

例えば、Glitch、Heroku、AWS Lambdaなどのクラウドサービスを使用することで、Node.jsを簡単に実行できます。

オンラインのサービスを使用してNode.jsを実行する場合、使用できるNode.jsのバージョンが制限されている場合や、Node.jsの設定ファイルを変更することができない場合があります。

それだけでなく、制限されたストレージ容量やファイルアップロードの制限などがある場合があります。

また、こちらもZIPファイル同様にセキュリティ上のリスクがあります。

それは、サービスによっては、利用者のアプリケーションのデータが他のユーザーと共有される可能性があるためです。

これらの方法は必ずしも最適な方法ではない場合があります。

そのため、あなたやチームの環境に応じて適切な方法を選択する必要があります

通常の開発者はNode.jsのバージョン管理ツールを使用して、Node.jsのバージョンを管理し、プロジェクトごとに異なるバージョンのNode.jsを使用することが一般的です。

Node.jsのバージョン管理ツールには、主に以下のようなものがあります。

nvm (Node Version Manager)

n

nodenv

nvs

これらのツールは、複数のバージョンのNode.jsを簡単に切り替えることができ、異なるプロジェクトで異なるバージョンのNode.jsを使用することができます。

また、これらのツールを使用することで、Node.jsのバージョンをアップグレードする際にも、既存のプロジェクトに影響を与えずに、新しいバージョンを試すことができます。

したがって、通常の開発者はNode.jsのバージョン管理ツールを使用して、プロジェクトごとに異なるバージョンのNode.jsを使用し、簡単かつ効果的なバージョン管理を行います。

初心者には、どれを選択すれば良いのか疑問に思われるはずです。

Node.jsのバージョン管理ツールを使用したい場合、2023年の現在、Node.jsのバージョン管理ツールとして、nvm (Node Version Manager) が最も人気で、広く使用されています。

nvmは、Node.jsのバージョンを管理するための簡単なツールで、コマンドラインから複数のNode.jsバージョンをインストール、切り替え、アンインストールすることができます。

また、nvmはLinux, macOS, Windowsなど、さまざまなオペレーティングシステムで使用できます。

他のバージョン管理ツールであるn、nodenv、nvsも人気がありますが、nはMacOSLinuxのみで使えるため、Windows環境では使用できません。

nodenvは、nvmと同様の機能を提供していますが、nvmよりも使用頻度が少なく、nvsは比較的新しいツールであるため、まだあまり広く普及していません。

まず、Node.js初めての初心者の方は、公式ウェブサイトからのインストールが最も簡単で安全な方法です。

公式ウェブサイトでは、各オペレーティングシステム向けのインストーラーが提供されており、ダウンロードしてインストールするだけで簡単にNode.jsをインストールすることができます。

公式ウェブサイトからのインストールには、Node.jsを使用するために必要なすべてのコンポーネントが含まれており、手順も明確に説明されているため、初心者の方でも簡単にインストールすることができます。

また、公式ウェブサイトからのインストールでは、Node.js自体に組み込まれたnpxを使用することで、異なるバージョンのNode.jsを使用しながら、グローバルパッケージを実行することができます。

このため、nvmなどのバージョン管理ツールを使わずに、npxを使用することで、よりシンプルな開発環境を構築することもできます。

Windowsおよび、macOSの場合、初心者であれば最も簡単な方法は、以下のNode.jsの公式の日本語版ウェブサイトから、Node.js最新バージョンのインストーラーをダウンロードします。

nodejs.org

Node.jsには、推奨版LTS(Long Term Support)と最新版の2つのリリースラインがございます。

推奨版LTSは、安定した機能を提供することを目的としたリリースであり、一般的なビジネスアプリケーションやウェブアプリケーションに最適です。

推奨版LTSは、開発者がビジネスで使用する場合に特に役立ちます。

一方、最新版は、最新の機能やパフォーマンスの改善を提供することを目的としています。

最新版には、最新の機能や改善点が追加されるため、開発者が試したり、最新技術を使用するために適しています。

初心者の開発者が学習目的でNode.jsを利用する場合、推奨されるのはLTSリリースです。

最新版は、まだ新しい機能やAPIが追加されたばかりで、バグ修正が行われていない場合があるため、安定性に問題が生じる可能性があります。

また、最新版を使用する際には、ドキュメントや質問・回答が不十分である場合があるため、初心者の開発者には向かない場合があります。

LTSリリースは、安定性が高く、長期的なサポートが提供されるため、初心者の開発者がNode.jsを学び、アプリケーションを開発するのに適しています。

また、LTSリリースにはドキュメントやチュートリアルが多数あり、質問や問題が発生した場合にはコミュニティサポートが充実しています。

LTSでのNode.js最新バージョンをインストールする手順は、オペレーティングシステム(OS)によって異なります。

Windows

1. Node.jsの公式サイトにアクセスします。

2. ページ上部にある「LTS」の項目をクリックします。

3. 現在のLTS版を選択して、Windows用のインストーラーをダウンロードします。

4. ダウンロードしたインストーラーを実行します。インストーラーに従って、Node.jsをインストールします。

5. コマンドプロンプトを「管理者として実行」で開き、node -vコマンドを入力しバージョンの確認がとれたら、WindowsでのNode.jsのインストールが完了しています。

また、同梱されているnpmもnpm -vで確認しときましょう。

macOS

macOSでも公式ウェブサイトからNode.jsをダウンロードしてインストールすることが可能ですが、Homebrewを使ってインストールする方が一般的であり、コマンドラインでのインストールが簡単に行えるためそちらの手順を説明します。

Homebrewは、macOSコマンドラインからパッケージを管理するためのツールです。

先述した、Node.jsインストール方法リストの「Node.jsをパッケージマネージャーを使ってインストールする方法」となります。

正確には、macOS用ではなく、アップル(またはLinuxシステム)が提供していない、あなたの必要なものをインストールできる便利なツールです。

ですが、Homebrewをインストールする前に、使用しているOSのバージョンやセキュリティポリシーを確認してください。

Homebrewをインストールするには以下のコマンドを必要とします。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

しかし、一部のOSのバージョンでは上記のコマンドを実行するとエラーが発生する可能性があります。

具体的には、古いバージョンのmacOSLinuxなどでは、デフォルトのシェルがbashではなく、zshdashなどの別のシェルになっている場合があります。

そのため、/bin/bashパスが存在しない場合や、bashがサポートされていない場合には、エラーが発生する可能性があります。

また、セキュリティ上の理由から、一部のOSでは、curlコマンドによるリモートスクリプトの実行が制限されている場合があります。

その場合は、他の代替手段を使用する必要があることをご了承ください。

公式のHomebrewウェブサイトには、サポートされているOSとバージョンについての情報が掲載されていますので、以下の日本語版を参考にしてください。

brew.sh

それでは、Homebrewをインストールしていきます。

1. Macの「Finder」を開き、「アプリケーション」フォルダを選択します。

2. 「ユーティリティ」フォルダを開き、「ターミナル」アプリケーションを開きます。

3. ターミナルアプリケーションが開いたら、以下のコマンドを入力してHomebrewをインストールします。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

インストールが完了したら、brewコマンドを使ってパッケージをインストール、アップグレード、アンインストールすることができます。

つまり、MacTerminal.appから、brewコマンドを使ってHomebrewを操作することができます。

注意点として、コマンドを実行する前に、インターネットに接続されていることを確認してください。

また、コマンドを実行する前に、コマンドに含まれる内容を理解し、実行に必要な権限を持っていることを確認してください。

4. Terminal.appを開き、以下のコマンドを実行して、Node.jsをインストールします。

brew install node@18.16.0

上記では、現在の最新である18.16.0を指定してLTS版をインストールしています。

Node.jsのバージョンを変更する場合は、@...の部分を変更してください。

brew install node@18とした場合、自動的に最新の18.x.xのLTS版がインストールされます。

ただし、LTS版が更新された場合でも、自動的に最新のLTS版にアップデートされるわけではありません。

Node.jsのLTS版のアップグレードは、Homebrewのアップグレードコマンドを使って行う必要があります。

以上で、macOSでのNode.jsのインストールが完了します。

Linux OS

LinuxでNode.jsをインストールするには、各ディストリビューションごとにインストール手順が異なります。

ここでは、Ubuntuを例に説明しますのでご了承ください。

1. Terminalを開き、以下のコマンドを実行して、aptのパッケージリストを更新します。

sudo apt update

2. 以下のコマンドを実行して、Node.jsのLTS版をインストールします。

sudo apt install nodejs

npmというパッケージマネージャーも同梱されていますので、同時にインストールされます。

以上で、UbuntuでのNode.jsのインストールが完了します。

なお、他のLinuxディストリビューションの場合は、パッケージマネージャーの種類やコマンドが異なる場合があります。

公式サイトにて各ディストリビューションにおけるNode.jsのインストール方法を確認し、適切な手順に従ってください。

Node.jsのインストールが完了しましたら、次のステップからWebサーバーの作成方法を学習していきます。

この記事での、Node.jsコードはNode.jsのバージョンがv8.0.0以降であれば正常に実行できます。

2023年05月時点でLTS推奨版のNode.js最新バージョンは、18.16.0 (同梱 npm 9.5.1)となっていますが、Node.js v8.0.0以降で動作するため、2023年から学ぶ初心者であれば、ほとんどの方が問題なく学ぶことができますのでご安心ください。

Common JSモジュールとES6 モジュール

Comon JSモジュールとES6 モジュールは、JavaScriptのモジュールシステムの2つの主要な形式です。

Common JSモジュールは、Node.jsで使用されるモジュールシステムであり、require()関数を使用して他のモジュールをインポートし、module.exportsオブジェクトを使用して自分自身をエクスポートします。これは、Node.jsの初期のバージョンで広く使用されていました。

ES6モジュールは、ECMAScript 6で導入されたモジュールシステムであり、import文を使用して他のモジュールをインポートし、export文を使用して自分自身をエクスポートします。

これは、ブラウザやNode.jsの最新バージョンで広く使用されています。

ES6モジュールは、Common JSモジュールよりも静的であり、モジュールの依存関係が宣言時に解決されるため、より高速で信頼性が高いとされています。また、ES6モジュールは、Common JSモジュールよりも構文が簡潔で、より直感的に使用できます。

ただし、ES6モジュールは、ブラウザでのサポートがまだ不完全であり、一部の環境では使用できない場合があります。そのため、Node.jsでは、Common JSモジュールが引き続き広く使用されています。

Node.jsでは、Common JSモジュールとES6モジュールのファイルを区別する方法は、ファイル拡張子によってCommon JSモジュールとESモジュールを区別するため、.jsの拡張子はCommon JSモジュールとして扱われ、.mjsの拡張子はESモジュールとして扱われます。

ただし、Node.jsのバージョンによっては、.mjsの拡張子を使用することができない場合があります。

その場合での解決策は後ほど解説致します。

以上が、Common JSモジュールとES6モジュールの概要です。

以下では、ES6モジュールをここよりも詳しく解説しているので参照ください。

dev-k.hatenablog.com

では、以下の学習からはまずCommon JSモジュールでWebサーバーの作成をしていき、そのNodeコードを最終的にES6モジュールとして書き換えていきます。

Comon JSモジュールでのファイル作成

次に、テキストエディターを使用して、server.jsという名前の新しいファイルを作成し、以下のコードをファイルに貼り付けて保存します。

//  server.js 
const http = require('http'); // httpモジュールを読み込む
const util = require('util'); // utilモジュールを読み込む

const hostname = 'localhost'; // サーバーのホスト名
const port = 8000; // サーバーのポート番号

// リクエストを処理する関数
const server = http.createServer((req, res) => {
  res.statusCode = 200; // ステータスコードを設定する
  res.setHeader('Content-Type', 'text/html'); // レスポンスヘッダーを設定する
  res.write('Welcome to the world of Node.js!!'); // レスポンスを送信する
  res.end(); // レスポンスの送信を完了する
});

// サーバーを起動する
server.listen(port, hostname, () => {
  util.log(`Server running at http://${hostname}:${port}/`);
});

server.jsファイルを作成したフォルダ内で、コマンドプロンプトWindows)またはターミナル(MacLinux)を開きます。。

WindowsVS Codeを使用している場合は、VS Codeで「Ctrl + Shift + @ 」を押すか、 ターミナル → 新しいターミナルを選択します。

次に、Node.jsコマンドを使用してファイルを実行します。

コマンドプロンプトまたはターミナルで以下のコマンドを入力し、server.jsファイルを実行してください。

node server.js

最後に、アプリの動作確認をします。

ウェブブラウザでhttp://localhost: 8000にアクセスして、「"Welcome to the world of Node.js!!" 」が表示されることを確認してください。

さて、それではこのコードを細かく解説いたします。

httpモジュールの読み込み

const http = require('http');

この行は、Node.jsのhttpモジュールを読み込んでいます。

httpモジュールは、Node.jsでHTTPリクエストとレスポンスを処理するための機能を提供します。

utilモジュールの読み込み

const util = require('util');

Node.jsのutilモジュールを読み込んでいます。

utilモジュールは、Node.jsの標準モジュールの1つで、様々なユーティリティ関数を提供するためのものです。

具体的には、デバッグやログ出力、オブジェクトの型判定、非同期処理の制御などに利用されます。

このコードでは、util.log()関数を使用して、サーバーが起動した旨をログに出力するために、このモジュールを必要としています。

このように、utilモジュールを使用することで、ログ出力を簡単に行うことができます。

サーバーの設定

const hostname = 'localhost';
const port = 8000;

サーバーを起動する際のホスト名とポート番号を定義しています。

この例では、localhostをホスト名とし、8000をポート番号としています。

サーバーの作成

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/html');
  res.write('Welcome to the world of Node.js!!');
  res.end();
});

http.createServer()関数を使用して、サーバーオブジェクトを作成します。

この関数は、リクエストを処理するためのコールバック関数を引数に取ります。

このコールバック関数には、リクエストオブジェクトとレスポンスオブジェクトが渡されます。

ここでは、ステータスコード200とテキスト形式のHTMLコンテンツを返すレスポンスを送信しています。

つまり、上記の例では、受信したリクエストに対して以下のレスポンスを返すように設定されています。

ステータスコード200

Content-Type ヘッダーにtext/htmlを設定

メッセージとしてWelcome to the world of Node.js!!を返す

res.end()でレスポンスの送信を完了

4.サーバーの起動

server.listen(port, hostname, () => {
  util.log(`Server running at http://${hostname}:${port}/`);
});

この行では、server.listen()関数を使用して、サーバーを起動します。

この関数は、ポート番号とホスト名を引数に取り、指定されたポート番号でサーバーをリッスンするように設定します。

起動時には、util.log()関数を使用して、サーバーが起動したことを確認するためにコンソールにメッセージを出力します。

以上が、このサーバー側コードの解説となります。

これであなたは、JavaScriptでバックエンド側のサーバーコードを書いたことになります。

Node.jsを使用して、Webサーバーを実装しています。

Webブラウザから送信されるHTTPリクエストに応じて、適切なレスポンスを返すために、サーバーサイドでJavaScriptを実行しています。

このように、Node.jsはJavaScriptのランタイム環境であり、サーバーサイドでJavaScriptを実行するための多くの機能を提供しています。

当記事の、このサンプルコードをベースに、より複雑なサーバーアプリケーションを構築することができます。

しかし、上記のコードでは、どのURLにアクセスしても、「"Welcome to the world of Node.js!!"」以外は何も送信されることはありません。

このHTTPサーバーで、HTMLファイル、CSSファイル、画像、その他のファイルなどの静的ファイルを送信できる必要があります。

静的ファイルサーバー

静的ファイルを送信するためには、httpモジュールにはfsファイルシステム)モジュールを組み合わせて利用する方法があります。

Node.jsのfsモジュールは、ファイルシステムにアクセスするためのモジュールです。

ファイルの読み書き、ディレクトリの作成や削除、ファイルの監視など、ファイルシステムに関する様々な操作を行うことができます。

fsモジュールは、Node.jsが提供する標準のモジュールの一つであり、Node.jsのコアモジュールの一部です。

そのため、Node.jsをインストールすると自動的に利用可能となっています。

fsモジュールには、同期的に操作を行うメソッドと非同期的に操作を行うメソッドがあります。

同期的なメソッドは、処理が完了するまでプログラムの実行が停止するため、I/O処理が多くなる場合には非推奨です。

一方、非同期的なメソッドは、コールバック関数やPromiseを用いて非同期的に処理を行うため、I/O処理が多い場合でも処理をブロックすることなく実行することができます。

fsモジュールは、Node.jsを使ったWebアプリケーションやサーバーサイドアプリケーションで頻繁に利用されますので、なるべく扱えるようになっておくのをお勧めします。

Node.jsの公式ドキュメントには、fsモジュールのドキュメントがありますので、参照ください。

Node.js公式ドキュメント/fsモジュール

様々なメソッドが提供されていますが、この記事ではfs.readFile()メソッドを使用します。

ファイルを非同期的に読み込むためのメソッドとなります。

以下に、簡単な例を例を示します。

// httpモジュールを読み込む
const http = require('http');
// ファイルシステムモジュールを読み込む
const fs = require('fs');

// サーバーのホスト名とポートを設定
const hostname = 'localhost';
const port = 8000;

// サーバーオブジェクトを作成する
const server = http.createServer((req, res) => {
  // index.htmlファイルを読み込む
  fs.readFile('index.html', (err, data) => {
    if (err) {
      // エラーが発生した場合は404エラーを返す
      res.statusCode = 404;
      res.setHeader('Content-Type', 'text/plain');
      res.end('File not found');
    } else {
      // 成功した場合は200ステータスコードとHTMLデータを返す
      res.statusCode = 200;
      res.setHeader('Content-Type', 'text/html');
      res.write(data);
      res.end();
    }
  });
});

// サーバーを起動する
server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

以下に各行の機能を説明致します。

const http = require('http');

httpモジュールをインポートします。

これは、HTTPリクエストとレスポンスの処理を提供するために使用されるNode.jsの標準モジュールです。

const fs = require('fs');

fsモジュールをインポートします。

これは、ファイルシステムにアクセスするために使用されるNode.jsの標準モジュールです。

const hostname = 'localhost';

サーバーがリッスンするホスト名を定義します。

ここの例では、ローカルマシンを表す'localhost'を使用しています。

const port = 8000;

サーバーがリッスンするポート番号を定義します。

この例では、8000番ポートを使用しています。

const server = http.createServer((req, res) => {
  fs.readFile('index.html', (err, data) => {
    if (err) {
      res.statusCode = 404;
      res.setHeader('Content-Type', 'text/plain');
      res.end('File not found');
    } else {
      res.statusCode = 200;
      res.setHeader('Content-Type', 'text/html');
      res.write(data);
      res.end();
    }
  });
});

上記では、createServerメソッドを使用して、サーバーオブジェクトを作成します。

このメソッドには、リクエストとレスポンスを処理するコールバック関数が渡されます。

このコードでは、リクエストが発生すると、'index.html'ファイルを読み込み、そのファイルをレスポンスとして返します。

ファイルが見つからない場合は、404エラーを返します。

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

サーバーをリッスンするためのlistenメソッドを呼び出します。

このメソッドは、ポート番号とホスト名を受け取り、サーバーを開始します。

listenメソッドには、開始されたときに実行されるコールバック関数が渡されます。

そして、サーバーが開始されたら、コンソールにメッセージを出力します。

このコードは、HTTPリクエストを受け取った場合、index.htmlファイルを読み込み、そのファイルをHTTPレスポンスとして送信するように設計しています。

したがって、このサーバーは静的HTMLファイルを提供するために使用できます。

ただし、このコードではindex.htmlファイルが存在しない場合、404エラーを返しますので注意してください。

では、index.htmlというファイル名を作成し以下のコードを保存してください。

Node.jsコードと同じディレクトリに置いても構いません。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width" />
  <title>Node.js Project</title>
</head>
<body>
    <h1>Hello, world!</h1>
    <p>Welcome to my website.</p>
</body>
</html>

これにより、サーバーがリクエストを受けると、このHTMLファイルが返されます。

また、CSSファイルをNode.jsサーバーから送信するには、HTTPレスポンスにCSSファイルの内容を含める必要があります。

その、手順はまず、サーバーでfs.readFile()メソッドを使用して、CSSファイルを読み込みます。

その後、レスポンスのヘッダーに、Content-Typeをtext/cssに設定してあげます。

そして、レスポンスの本文にCSSファイルの内容を書き込みます。

以下は、CSSファイルとHTMLファイルを含んだ、Node.jsサーバーの例となります。

const http = require('http');
const fs = require('fs');

const hostname = 'localhost';
const port = 8000;

const server = http.createServer((req, res) => {
  // リクエストされたファイルの拡張子を取得
  const extension = req.url.split('.').pop();

  // CSSファイルを読み込みんで、レスポンスを返す
  if (extension === 'css') {
    fs.readFile('styles.css', (err, data) => {
      if (err) {
        res.statusCode = 404;
        res.setHeader('Content-Type', 'text/plain');
        res.end('File not found');
      } else {
        res.statusCode = 200;
        res.setHeader('Content-Type', 'text/css');
        res.write(data);
        res.end();
      }
    });
  } else {
    // HTMLファイルを読み込みんで、レスポンスを返す
    fs.readFile('index.html', (err, data) => {
      if (err) {
        res.statusCode = 404;
        res.setHeader('Content-Type', 'text/plain');
        res.end('File not found');
      } else {
        res.statusCode = 200;
        res.setHeader('Content-Type', 'text/html');
        res.write(data);
        res.end();
      }
    });
  }
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

上記の例では、リクエストされたファイルの拡張子を確認して、それが.cssである場合は、styles.cssファイルを読み込み、それ以外の場合はindex.htmlファイルを読み込みます。

fs.readFile()メソッドは、引数として指定されたファイルのパスを非同期で読み込みます。

上記のコードでは、extension変数がCSSである場合、fs.readFile()メソッドを使用してstyles.cssファイルを非同期で読み込み、コールバック関数を介して読み込み結果を受け取っています。

fs.readFile()メソッドは、コールバック関数を使用して非同期に読み込んだファイルの内容を処理するため、ファイルの読み込みが完了したら呼び出される関数を指定します。

CSSファイルを読み込む場合、Content-Typeヘッダーをtext/cssに設定し、CSSファイルの内容をレスポンスの本文に書き込みます。

つまり、リクエストされたファイルの拡張子を確認して、リクエストされたファイルが.html拡張子または.css拡張子である場合に、該当するファイルの内容を返してくれます。

したがって、HTMLファイルとCSSファイルが両方ともリクエストされた場合、両方のファイルが同時に読み込まれ、HTMLファイル内の<link>タグで参照されたCSSファイルが適用されます。

<head>
  <link rel="stylesheet" type="text/css" href="styles.css">
</head>

ただし、リクエストされたファイルがHTMLファイルではなく、CSSファイルのみの場合は、CSSファイルの内容のみがレスポンスとして送信されますので注意してください。

また、このコードでのCSSファイル名は、style.cssではなくstyles.cssなのも注意してください。

style.cssに変更する場合は、fs.readFile()メソッドの引数をstyle.cssに変更するだけです。

if (extension === 'css') {
  fs.readFile('style.css', (err, data) => { // ファイル名を'style.css'に変更
 // ...
}

ES6 モジュール

また、現在のコードではconst http = require('http');の行で「ファイルは CommonJS モジュールです。ES モジュールに変換される可能性があります。」という警告が出ている可能性があります。これは、Node.js v13.2.0以降で実行されている可能性があります。

Node.js v13.2.0以降では、デフォルトでESモジュールが有効になり、拡張子.jsファイルがCommonJSとして解釈されなくなりました。

そのため、ファイルがESモジュールとして解釈され、require()ステートメントが解釈されなくなったことが原因で、警告が表示されています。

これを、解決するには、ファイルの拡張子を.mjsに変更するか、package.jsonファイルに"type": "module"を追加し、ファイルがESモジュールとして解釈されるようにする必要があります。

ESモジュールでは、ファイルインポート時に常に拡張子を指定する必要があるため、これは重要です。

また、ES モジュールを使用する場合は、ファイル内でimportを使用する必要があります。

例えば、httpモジュールを使用するには、次のように書き換えます。

// httpモジュールを読み込む
import http from 'http';

const http = require('http');

しかし、Node.jsのバージョンがv16.0.0以降であれば、CommonJSでもモジュールを読み込めるようになっています。

"type": "module"が必須となることはありません。

ファイルの拡張子を.mjsの変更した場合は、以下の点に注意が必要です。

ロードされるモジュールは、CommonJSとして同期的に読み込まれます。

import()を使用して動的にモジュールを読み込む必要がある場合、async/await構文を使用する必要があります。

また、.mjs拡張子でNode.jsの一部のバージョンでは--experimental-modulesフラグを使用して、ESモジュールを有効にする必要があります。

i以下に、Common JSモジュールをES モジュールコードとして書き換えた例を示します。

//  server.mjs 

import { createServer } from 'http';
import { readFile } from 'fs/promises';

const hostname = 'localhost';
const port = 8000;

const server = createServer(async (req, res) => {
  try {
    const data = await readFile('index.html');
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/html');
    res.write(data);
    res.end();
  } catch (err) {
    res.statusCode = 404;
    res.setHeader('Content-Type', 'text/plain');
    res.end('File not found');
  }
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

上記のコードでは、Node.jsのES モジュールの機能を使って、httpモジュールとfs/promisesモジュールをimport文でインポートしています。

さらに、async/awaitを使ってfs.promises.readFileメソッドを呼び出して、非同期にファイルの読み込みを行い、その結果を使ってHTTP レスポンスを返しています。

Node.js v13以下の方は、上記のコードを実行するには、コマンドラインで以下のように実行する必要があります。

node --experimental-modules server.mjs

このように、--experimental-modulesフラグを付けて、.mjs拡張子を使ってモジュールを読み込むことができます。

なぜ、このように.mjs拡張子でnode.js v16以降では--experimental-modulesフラグを使用して、ESモジュールを有効にすることが推奨されるのか?

正確に言うと、Node.js v16以降ではES モジュールの機能が正式にサポートされるようになったため、.mjs拡張子で書かれたファイルを直接読み込むことができます。

ただし、Node.jsのES モジュールの実装はまだ完全ではないため、いくつかの制限や注意点があります。

例えば、Node.jsでは、Common JSモジュールとES モジュールを混在して使うことができますが、ESモジュール内からCommon JSモジュールを読み込む場合には、import文ではなくrequire文を使わなければなりません。

これらの注意点はJavaScript モジュールを学習して下さい。

また、ES モジュール内では、トップレベルのimport文やexport文の外側で、変数宣言や関数宣言を行うことができません。

さらに、.mjs拡張子で書かれたファイルを直接読み込むには、--experimental-modulesフラグを使用する必要があります。

このフラグを付けない場合には、.mjsファイルはCommon JS モジュールとして扱われます。

そのため、.mjs拡張子でES モジュールを書く場合には、Node.js v16以降を使って、--experimental-modulesフラグを付けて実行することが推奨されます。

つまり、このフラグを使用する方の対象は、Node.jsのバージョンによっては、.mjsの拡張子を使用することができない場合です。

Node.jsのバージョンがv13以下の方は、このフラグを使用してESモジュールを使用することができます。

Node.jsのバージョンがv16以上では、ESモジュールがデフォルトで有効になっており、--experimental-modulesフラグを使用する必要はありませんので以下の方法で実行されます。

// Node.js v16移行
node server.js

最後に

Node.jsは、非常にエキサイティングなテクノロジであり、高性能のリアルタイムアプリケーションを簡単に作成できることが特徴です。

このフレームワークは、オープンソースサードパーティライブラリを簡単に利用できる優れたモジュールシステムを備えています。これにより、開発者は自分のアプリケーションに必要な機能を簡単に追加できます。

また、Node.jsには、データベース接続レイヤーやテンプレートエンジン、メールクライアントなど、さまざまなモジュールがあります。これらのモジュールを使用することで、開発者はアプリケーションの機能性を向上させることができます。

さらに、これらのモジュールは、フレームワーク全体を接続するためのツールとしても利用できます。これにより、開発者はアプリケーション全体を効率的かつシームレスに管理できます。

以上のように、Node.jsは非常に柔軟で高機能なフレームワークであり、開発者にとって非常に魅力的な選択肢となっています。

最後まで読んで頂きありがとうございます。

この記事が役に立ったら、ブックマークと共有をしていただけると幸いです。

プライバシーポリシー

© 2023 Icons8 LLC. All rights reserved.

© [deve.K], 2023. React logo is a trademark of Facebook, Inc. JavaScript is a trademark of Oracle Corporation and/or its affiliates. jQuery and the jQuery logo are trademarks of the JS Foundation. TypeScript and the TypeScript logo are trademarks of the Microsoft Corporation. Next.js and the Next.js logo are trademarks of Vercel, Inc. Firebase and the Firebase logo are trademarks of Google LLC. All logos edited by [deve.K].