0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Express の静的ファイルの扱いがわからなくて困ったので整理する

Posted at

困ったこと

Express の静的ファイルの扱いについてあまり理解していなくても、試行錯誤すれば何とか問題は解決できてしまっていました。

そのせいで、同じ問題が発生したときに、そのたびに毎回試行錯誤しないといけなくて、かなり効率が悪いと感じていたので、ちゃんとおさらいしてみようと思います。

解説

以下のようにサンプルアプリを作ってみます。

2024-05-04-14-58-40.png

const express = require("express");
const app = express();

app.use(express.static("./public"));
app.use("/static/images", express.static("./assets/images"));

app.listen(3000);

ソースコードを分解すると次の 3 つになります。(app.listen()は除く)

  • express
  • app.use()
  • express.static()

そもそも Express って何だっけ?

公式サイトには以下のように記述されています。

Express は、それ自体では最小限の機能を備えたルーティングとミドルウェアの Web フレームワークです。Express アプリケーションは基本的に一連のミドルウェア関数呼び出しです。

Express 公式サイトより

どうやら Express の正体は基本的にはミドルウェア関数の呼び出しのようです。

ただし、必ずしもミドルウェア関数の呼び出ししかしていないわけではなく

app.listen(3000);

など、ミドルウェア関数の呼び出し以外の機能もあります。
が、メインの機能はミドルウェア関数の呼び出しと考えて大丈夫そうです。

ミドルウェア関数とは

ミドルウェア関数とはリクエストとレスポンスの処理の間に実行される関数のこと。

2024-05-03-23-50-46.png

Express を使ってこのリクエストとレスポンスの間でどのミドルウェア関数を呼び出すかを定義します。

例えば、ルーティングもミドルウェア関数の呼び出しの一つです。

app.get("/hello", (req, res, next) => {
  res.render("hello.ejs");
});

ここでは、localhost:3000/helloにアクセスする(GETリクエストを送る)と、
(req, res, next) => {
  res.render("hello.ejs");
};

というミドルウェア関数を呼び出すよ、ということを定義しています。

app.use()は何をしている?

app.use()の書き方は大きく別けて次の 4 パターンがあります。

ミドルウェア関数が一つ ミドルウェア関数が複数
引数にパスがない 1 2
引数にパスがある 3 4
// 1:引数がパスがない、ミドルウェア関数が一つ
// 全てのリクエストに対し実行される
app.use((req, res, next) => {
  console.log("hi");
  next();
});

// 2:引数がパスがない、ミドルウェア関数が複数
// 全てのリクエストに対し実行される
app.use(
  (req, res, next) => {
    console.log("hi");
    next();
  },
  (req, res, next) => {
    console.log("bye");
    next();
  }
);

// 3:引数がパスがある、ミドルウェア関数が一つ
// 特定のパスにのみ実行される
app.use("/hello", (req, res, next) => {
  console.log("hello");
  next();
});

// 4:引数がパスがある、ミドルウェア関数が複数
// 特定のパスにのみ実行される
app.use(
  "/world",
  (req, res, next) => {
    console.log("hello");
    next();
  },
  (req, res, next) => {
    console.log("world");
    next();
  }
);

すべてに共通しているのはミドルウェアがあることで、app.use()の役割はそのミドルウェアを登録して使えるようにすることです。

引数にパスがなければ全てのリクエストに対して登録したミドルウェアを実行し、
パスがあればそのパスのみに対して登録したミドルウェアを実行します。

express.static()とは

express.static()とは、静的ファイル(画像、CSS ファイル、JavaScript ファイルなど)を提供するためのミドルウェア関数のこと。

逆に言うと、express.static()がないとプロジェクトの静的ファイルは利用できません。

実際にアクセスしてみる

const express = require("express");
const app = express();

app.use(express.static("./public"));
app.use("/static/images", express.static("./assets/images"));

app.listen(3000);

サーバーを起動して、URL でアクセスしてみます。

http://localhost:3000/luffy.png

2024-05-04-14-31-35.png

http://localhost:3000/static/images/zoro.png

2024-05-04-14-32-26.png

http://localhost:3000/static/images-2/nami.png

2024-05-04-16-04-59.png

① と ② はアクセスできましたが、③ はアクセスできませんでした。

③ にアクセスできなかったのは、/static/images-2 のリクエストに対するミドルウェアの呼び出しが app.use()で定義されていないからですね。

const express = require("express");
const app = express();

app.use(express.static("./public"));
app.use("/static/images", express.static("./assets/images"));
// 追加
app.use("/static/images-2", express.static("./assets/images-2"));

app.listen(3000);

このように定義すれば、アクセスできるようになります。

http://localhost:3000/static/images-2/nami.png

2024-05-04-16-12-51.png

まとめ

  • Express
  • app.use()
  • express.static()

について整理しました。

実際のプロダクトのコードはこんなにシンプルではないので、応用する必要がありますが、今回は基本的なことだけをおさらいしてみました。

備考

express.static()は app.use()を使わなくても技術的には

app.get("/*", express.static("public"));

のように書けば可能ですが、app.use()を使うのが一般的なようです。

違いは、app.use()の場合はすべての HTTP メソッド(GET, POST など)に対して適用されるが、
上のコードの場合は GET メソッドのみにしか適用されない、という違いがあります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?