1. ホーム
  2. node.js

[解決済み】Node.js / Express.js - app.routerはどのように動作するのですか?

2022-03-29 16:06:57

質問

についてお聞きする前に app.router 少なくとも、ミドルウェアを扱うとどうなるのか、説明しておく必要があると思います。ミドルウェアを使うために、使うべき関数は app.use() . ミドルウェアが実行されるとき、次のミドルウェアを呼び出すために next() または、それ以上のミドルウェアが呼ばれないようにする。つまり、ミドルウェアの呼び出しの順番が重要なんだ。あるミドルウェアは他のミドルウェアに依存しているし、末端にあるミドルウェアは呼び出されないかもしれないからね。

今日、私は自分のアプリケーションで作業をしていて、バックグラウンドでサーバーを動かしていました。私はいくつかの変更を加え、ページを更新してすぐに変更を確認したいと思いました。具体的には、レイアウトに変更を加えていました。私はそれを動作させることができませんでしたので、私は答えを得るためにスタックオーバーフローを検索し、見つけました。 この質問 . を確認するように書かれています。 express.static() の下にある require('stylus') . しかし、そのOPのコードを見ていたら、そのOPは、自分の app.router の呼び出しがミドルウェアの呼び出しの一番最後にあるので、それがなぜなのかを考えてみました。

Express.js アプリケーション (バージョン 3.0.0rc4) を作成したとき、私はコマンド express app --sessions --css stylus で、app.js ファイルには、私の app.router の両方の上にある express.static()require('stylus') を呼び出します。ですから、すでにそのように設定されているのであれば、そのままでいいような気がします。

Stylus の変更を確認できるようにコードを整理すると、次のようになります。

app.configure(function(){
  //app.set() calls
  //app.use() calls
  //...
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.static(__dirname + '/public', {maxAge: 31557600000}));
});

app.get('/', routes.index);

app.get('/test', function(req, res){
  res.send('Test');
});

そこで、まず最初に、なぜ app.router をコードに追加しました。そこで、コメントアウトし、アプリを起動して / . インデックスページが正常に表示されました。うーん、多分ルーティングをルートファイル(routes.index)からエクスポートしていたからうまくいったのでしょう。そこで、次に /test と表示され、画面にTestが表示されました。ははは、OK、何が何だかさっぱりわからない。 app.router が行います。私のコードに含まれていようがいまいが、私のルーティングは問題ないのです。だから、私は間違いなく何かを見逃しているのです。

そこで質問です。

を説明してください。 app.router は何をするのか、その重要性、ミドルウェアの呼び出しのどこに配置すればいいのか?また、以下の点についても簡単に説明してもらえると助かります。 express.static() . 私が知る限りでは express.static() は私の情報のキャッシュであり、アプリケーションが要求されたページを見つけられない場合、キャッシュが存在するかどうかを確認します。

どのように解決するのですか?

注意事項 ここでは、バージョン 2 および 3 での Express の動作について説明します。 Express 4 についての情報は、この記事の最後を参照してください。


static は単にファイル( 静的 リソース) をディスクから取得します。 パス(マウントポイントと呼ばれることもある)を与えると、そのフォルダーにあるファイルを提供する。

例えば express.static('/var/www') は、そのフォルダー内のファイルを提供します。 ですから、Node サーバに http://server/file.html/var/www/file.html .

router は、ルートを実行するためのコードです。 を実行すると app.get('/user', function(req, res) { ... }); を使用すると、それは router は、実際にコールバック関数を呼び出して、リクエストを処理します。

に渡す順番は app.use は、各ミドルウェアにリクエストを処理する機会を与える順序を決定します。 例えば test.html を静的フォルダーに、ルートを

app.get('/test.html', function(req, res) {
    res.send('Hello from route handler');
});

を要求するクライアントに送信されるのはどれですか? http://server/test.html ? どちらのミドルウェアが use を最初に指定します。

こうすれば

app.use(express.static(__dirname + '/public'));
app.use(app.router);

そして、ディスク上のファイルが提供される。

他の方法でやる場合

app.use(app.router);
app.use(express.static(__dirname + '/public'));

そしてルートハンドラがリクエストを取得し、"Hello from route handler"がブラウザに送信されます。

通常は、ルータに 上記 という静的ミドルウェアを使用することで、誤って命名されたファイルがルートの一つを上書きすることを防ぎます。

なお、明示的に use その router をコメントアウトしてもルートが動作するのはそのためです。 app.use(app.router) ).


あるコメンテーターが 育てた の順番について、もうひとつ指摘があります。 staticrouter アプリの全体的なパフォーマンスへの影響です。

もう一つの理由は use router 上記 static は、パフォーマンスを最適化するためのものです。 もしあなたが static を先にすると、ファイルが存在するかどうかを確認するために、リクエストのたびにハードディスクを叩くことになります。 そのため クイックテスト このオーバーヘッドは、負荷のかかっていないサーバーでは、1ms程度になります。 (負荷がかかると、ディスクアクセスのためにリクエストが競合するため、この数字はもっと大きくなる可能性があります)。

とは router を使うと、ルートにマッチするリクエストがディスクにヒットすることはなく、貴重なミリ秒を節約できます。

を軽減する方法はあります。 static のオーバーヘッドが発生します。

最良の選択肢は、すべての静的リソースを特定のフォルダの下に置くことです。 (IE /static をマウントすることができます。 static で始まるパスのときだけ実行されるようにします。 /static :

app.use('/static', express.static(__dirname + '/static'));

このような場合、上記のように配置します。 router . これにより、ファイルが存在する場合に他のミドルウェア/ルーターの処理を回避することができますが、正直なところ、それほど大きな収穫はないでしょう。

を使用することもできます。 staticCache これは、静的なリソースをメモリ内にキャッシュし、よく要求されるファイルに対してディスクをヒットさせる必要がないようにするものです。 ( 警告 staticCache は削除されるようです を追加しました)。

しかし、私は staticCache は否定応答 (ファイルが存在しない場合) をキャッシュするので、もし staticCache 上記 router パスにマウントすることなく

パフォーマンスに関するすべての質問と同様です。 実際のアプリを測定し、ベンチマークする (負荷がかかった状態で)ボトルネックが本当にどこにあるのかを確認することができます。


エクスプレス4

エクスプレス4.0 リムーブ app.router . すべてのミドルウェア( app.use ) とルート ( app.get など)は、正確に追加された順番に処理されるようになりました。

言い換えれば

すべてのルーティングメソッドは、表示される順番に追加されます。あなたは ではなく する app.use(app.router) . これにより、Expressで最も多い問題が解消されます。

つまり app.use()app[VERB]() が動作します。 まさに の順番で呼び出されます。

app.get('/', home);
app.use('/public', require('st')(process.cwd()));
app.get('/users', users.list);
app.post('/users', users.create);

Express 4の変更点についてはこちらをご覧ください。