お金をかけずにサーバーの勉強をしよう

Node.js + Expressで WEBサーバープログラム作成

2025年5月2日

メニューへ戻る

Node.jsを使って WEBサーバープログラムを作ってみましょう。

Node.jsインストール」で Ubuntu Serverにサーバーサイドの JavaScript実行環境を作りました。

ここでは Node.jsが得意とする軽量の WEBサーバープログラムを作ってみます。

Node.jsが提供するライブラリだけでもその機能を有していますが、1から全て作るよりは既に出回っているフレームワークを使った方が断然楽ですので、ここでは有名所のうち IBM製の Expressを使ってみます。

以下が Expressのサイトです。
Express


1.環境

以下のセットでやります。
全て 2025年5月2日時点での最新版になります。


2.インストール前に

上の Expressのサイトに行ってもらうとトップページにいきなり

npm install express --save

と導入コマンドがズバリ書いてあるのですが、これは実行しないで下さい。

代りに Expressジェネレーターという「開発用ディレクトリ階層&初期ファイルの雛形作成ツール」とでも呼ぶべきものがありますので、それをインストールします。

Expressのホームページの一番上のメニューから [概説] - [Express ジェネレーター] を選んで下さい。
Express インストール方法

しますとこのような導入コマンドがズバリ書いてあるのですが、まだちょっと待って頂きたい。(またか)

npm install express-generator -g

[npm install]コマンドの [-g]オプションは「グローバル」オプションと言って、このサーバーにインストールした Node.jsを使うユーザーに共有させる場合に使います。
([-g]オプションを付けなければカレントディレクトリ以下にインストールしにいきます。)

ただ、snapパッケージの Node.jsの場合、いくつかハマりポイントがあります

私がここでご紹介している Node.jsのインストールは snapパッケージを使っているため [/snap/node/current] がインストールディレクトリです。
(このディレクトリの実体は snapパッケージのバージョン毎に異なるディレクトリへのシンボリックリンクなので [ls]コマンドでリンク先を示すために [-L]オプションを使っています。)

subro@UbuntuServer2404-1:~$ ls -Ll /snap/node/current
合計 9
-rw-r--r-- 1 root root 1355  3月 10  2024 LICENSE
-rw-r--r-- 1 root root 3353  3月 10  2024 README.md
drwxr-xr-x 2 root root  142  4月 23 17:55 bin
drwxr-xr-x 2 root root   28  4月 23 17:55 etc
drwxr-xr-x 3 root root   27  4月 23 17:55 include
drwxr-xr-x 3 root root   88  4月 23 17:55 lib
drwxr-xr-x 3 root root   43  4月 23 17:55 meta
-rw-r--r-- 1 root root  634  3月 10  2024 package.json
-rw-r--r-- 1 root root 2342  3月 10  2024 preinstall.js
drwxr-xr-x 4 root root   37  4月 23 17:55 share
drwxr-xr-x 2 root root   58  4月 23 17:55 snap

snapパッケージのサンドボックス的な特性なんでしょうけど、後からこのパッケージ内のファイルをイジらせないのが普通です。

しかし Node.jsでの開発と言えば [npm install]コマンドを使って外部モジュールを組み込んでいくのが普通ですよね。

では後から追加されていく外部モジュールのうち [npm install -g]コマンドでインストールされる共有モジュールはどこに入るのか。

これは後の作業で分かるんですが [/usr/local]ディレクトリ以下になります。

[node]コマンドというプログラムファイルと基本的なモジュールファイルは snapの
[/snap/node/current]ディレクトリにあり、
追加した外部モジュールは [/usr/local]ディレクトリ以下に入っていくという泣き別れ状態になります。

これを知っておかないと「追加インストールしたあのモジュールはどこ?」ってことになりかねません。

次に [npm]コマンド自体も実はモジュールなんだってのがハマりポイントになっています。

Expressジェネレーターをインストールする前に、以下の通り [npm]コマンド自体を最新版にアップデートします。

subro@UbuntuServer2404-1:~$ which npm ←アップデート前の[ npm]コマンドの場所
/snap/bin/npm

subro@UbuntuServer2404-1:~$ npm --version ←アップデート前の[ npm]コマンドのバージョン
10.9.2

subro@UbuntuServer2404-1:~$ sudo npm install -g npm ←アップデート

added 1 package in 4s

25 packages are looking for funding
  run `npm fund` for details

subro@UbuntuServer2404-1:~$ which npm ←アップデート後の[npm]コマンドの場所
/usr/local/bin/npm
↑↑↑[PATH]環境変数で[/usr/local/bin]が[/snap/bin]より前だから。

subro@UbuntuServer2404-1:~$ npm --version ←アップデート後の[npm]コマンドのバージョン
10.9.2
↑↑↑[/usr/local/bin/npm]を実行しているはずなのいバージョンが変わってない
   これはBashが[npm]コマンドの場所をキャッシュしちゃってるからです。

subro@UbuntuServer2404-1:~$ hash -r ←キャッシュクリア

subro@UbuntuServer2404-1:~$ npm --version ←改めてアップデート後の[npm]コマンドのバージョン
11.3.0

最初の [npm]コマンドと 2回目以降に使う [npm]コマンドの場所が違うのでした。

分かってしまえば何ということは無いですが、こんなに分かり難くしてまで snapパッケージを使う必要があろうか?と考えてしまいます。


3.Expressジェネレーターインストール

では満を持してExpressジェネレーターを共有モジュールとしてインストールします。

subro@UbuntuServer2404-1:~$ sudo npm install -g express-generator
npm warn deprecated mkdirp@0.5.1: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)

added 10 packages in 2s

インストールできました。
mkdirpモジュールの Ver.0.5.1が Deprecated(非推奨)だと言われていますが、これは無視。
(Expressジェネレーターのメンテナーに頑張ってもらいたい。)

Expressジェネレーターのコマンドは [express] なんですが、どこにあるのか。

subro@UbuntuServer2404-1:~$ which express
/usr/local/bin/express

subro@UbuntuServer2404-1:~$ ls -l /usr/local/bin
合計 0
lrwxrwxrwx 1 root root 56  5月  2 23:11 express -> ../lib/node_modules/express-generator/bin/express-cli.js
lrwxrwxrwx 1 root root 38  5月  2 22:12 npm -> ../lib/node_modules/npm/bin/npm-cli.js
lrwxrwxrwx 1 root root 38  5月  2 22:12 npx -> ../lib/node_modules/npm/bin/npx-cli.js

[express]コマンドの実体は JavaScriptのスクリプトでした。
[npm]コマンドも実はスクリプトなんですね。
やっぱり一通り [/usr/local]ディレクトリ以下に入ったようです。


4.プロジェクト作成

Expressジェネレーターの導入により念願の開発プロジェクトの雛形を作れるようになりました。

[express]コマンドはオプション無しだとカレントディレクトリ直下にプロジェクト名のディクトリが作成されますので、作業用のディレクトリを作ってそこに移動しておいて下さい。

私は [/home/subro/work] ディレクトリを作って、そこに移動しました。

[subrotest]プロジェクトを作成します。

subro@UbuntuServer2404-1:~/work$ express --view=ejs subrotest

   create : subrotest/
   create : subrotest/public/
   create : subrotest/public/javascripts/
   create : subrotest/public/images/
   create : subrotest/public/stylesheets/
   create : subrotest/public/stylesheets/style.css
   create : subrotest/routes/
   create : subrotest/routes/index.js
   create : subrotest/routes/users.js
   create : subrotest/views/
   create : subrotest/views/error.ejs
   create : subrotest/views/index.ejs
   create : subrotest/app.js
   create : subrotest/package.json
   create : subrotest/bin/
   create : subrotest/bin/www

   change directory:
     $ cd subrotest

   install dependencies:
     $ npm install

   run the app:
     $ DEBUG=subrotest:* npm start

[--view=ejs]オプションは Web画面のテンプレートエンジンに ejs を使うことを意味しています。
ejsを使うのは私の趣味です。
(デフォルトは Jadeなんですが長らくメンテナンスされてませんね…。)

下の方に 3つのコマンドが書かれていますので、それをやりましょう。

[subrotest]プロジェクトディレクトリに移ります。

subro@UbuntuServer2404:~/work$ cd subrotest

移動しました。

必要なモジュールをダウンロードします。
この中に Expressフレームワークを構成するモジュールが入ってきます。

[npm install]コマンドに [-g]オプションを付けていないので、このディレクトリの下に [node_modules]ディレクトリが作成されます。

subro@UbuntuServer2404-1:~/work/subrotest$ npm install

added 54 packages, and audited 55 packages in 2s

8 vulnerabilities (3 low, 4 high, 1 critical)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

モジュールのダウンロードできました。

プロジェクトディレクトリの中はこんな風になりました。

subro@UbuntuServer2404-1:~/work/subrotest$ ls -l
合計 76
-rw-rw-r--  1 subro subro  1074  5月  2 23:29 app.js
drwxr-xr-x  2 subro subro  4096  5月  2 23:29 bin
drwxrwxr-x 88 subro subro  4096  5月  2 23:35 node_modules
-rw-rw-r--  1 subro subro 48551  5月  2 23:35 package-lock.json
-rw-rw-r--  1 subro subro   296  5月  2 23:35 package.json
drwxr-xr-x  5 subro subro  4096  5月  2 23:29 public
drwxr-xr-x  2 subro subro  4096  5月  2 23:29 routes
drwxr-xr-x  2 subro subro  4096  5月  2 23:29 views

ピンクのところが [npm install]コマンドにより増えたところですね。

最新版で固めても 8つの脆弱性(うち 1つは致命的)があると言ってますねぇ…。

対応しましょう。
(と言いつつ、これをやっちまって良いのかよく分からんのですが…)

subro@UbuntuServer2404-1:~/work/subrotest$ npm audit fix --force
npm warn using --force Recommended protections disabled.
npm warn audit Updating ejs to 3.1.10, which is a SemVer major change.
npm warn audit Updating express to 4.21.2, which is outside your stated dependency range.

added 63 packages, changed 17 packages, and audited 118 packages in 2s

16 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

「found 0 vulnerabilities」と書いてあるので良いのではないかと。

プロジェクトを実行します。

subro@UbuntuServer2404-1:~/work/subrotest$ DEBUG=subrotest:* npm start

> subrotest@0.0.0 start
> node ./bin/www

  subrotest:server Listening on port 3000 +0ms

これで待機状態となりました。

[3000/tcp] で待ち受けているようなので、WEBブラウザでアクセスしてみましょう。
私の環境だと [http://UbuntuServer2404-1:3000] です。

express-generator により作成された雛形のトップページが表示されました。
\(^o^)/
Express 雛形画面


==========
プロジェクト内の JavaScriptファイルを Visual Studio Codeなどでガリガリ書いていけば、お好みの WEBアプリケーションを作れるはずです。
(これでやっと開発の取っ掛かりに辿り着いた…ということです)

Q. この後はどうすればいいの?

A. 書籍などでの自己学習をお願いします!


Expressを扱っているものでは 2024年11月25日刊の最新本ですね。