ホームページ > ウェブフロントエンド > jsチュートリアル > Express.js のマスタリング: ディープダイブ

Express.js のマスタリング: ディープダイブ

Susan Sarandon
リリース: 2025-01-05 06:46:40
オリジナル
381 人が閲覧しました

Mastering Express.js: A Deep Dive

Express は、Node.js で非常に一般的に使用される Web サーバー アプリケーション フレームワークです。基本的に、フレームワークは特定のルールに準拠したコード構造であり、次の 2 つの重要な特性があります。

  • API をカプセル化することで、開発者はビジネス コードの作成に集中できるようになります。
  • プロセスと標準仕様が確立されています。

Express フレームワークの中心的な機能は次のとおりです:

  • さまざまな HTTP リクエストに応答するようにミドルウェアを構成できます。
  • さまざまな種類の HTTP リクエスト アクションを実行するためのルート テーブルを定義します。
  • HTML ページの動的なレンダリングを実現するためにテンプレートにパラメータを渡すことをサポートします。

この記事では、シンプルな LikeExpress クラスを実装することで、Express がミドルウェアの登録、次のメカニズム、およびルート処理をどのように実装するかを分析します。

高速分析

まず、2 つの Express コード例を通じて、Express が提供する機能を調べてみましょう:

Express 公式ウェブサイト Hello World の例

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

エントリファイルapp.jsの分析

以下は、express-generator スキャフォールディングによって生成された Express プロジェクトのエントリ ファイル app.js のコードです。

// Handle errors caused by unmatched routes
const createError = require('http-errors');
const express = require('express');
const path = require('path');

const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');

// `app` is an Express instance
const app = express();

// View engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// Parse JSON format data in post requests and add the `body` field to the `req` object
app.use(express.json());
// Parse the urlencoded format data in post requests and add the `body` field to the `req` object
app.use(express.urlencoded({ extended: false }));

// Static file handling
app.use(express.static(path.join(__dirname, 'public')));

// Register top-level routes
app.use('/', indexRouter);
app.use('/users', usersRouter);

// Catch 404 errors and forward them to the error handler
app.use((req, res, next) => {
    next(createError(404));
});

// Error handling
app.use((err, req, res, next) => {
    // Set local variables to display error messages in the development environment
    res.locals.message = err.message;
    // Decide whether to display the full error according to the environment variable. Display in development, hide in production.
    res.locals.error = req.app.get('env') === 'development'? err : {};
    // Render the error page
    res.status(err.status || 500);
    res.render('error');
});

module.exports = app;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

上記の 2 つのコード セグメントから、Express インスタンス アプリには主に 3 つのコア メソッドがあることがわかります。

  1. app.use([path,] callback [, callback...]): ミドルウェアの登録に使用されます。リクエストパスが設定されたルールと一致すると、対応するミドルウェア機能が実行されます。
    • path: ミドルウェア機能を呼び出すためのパスを指定します。
    • callback: コールバック関数はさまざまな形式を取ることができます。単一のミドルウェア関数、カンマで区切られた一連のミドルウェア関数、ミドルウェア関数の配列、または上記すべての組み合わせを指定できます。
  2. app.get() および app.post(): これらのメソッドは us​​e() に似ており、ミドルウェアを登録するためのものでもあります。ただし、これらは HTTP リクエスト メソッドにバインドされています。対応する HTTP リクエスト メソッドが使用された場合にのみ、関連するミドルウェアの登録がトリガーされます。
  3. app.listen(): httpServer を作成し、server.listen() に必要なパラメータを渡す役割を果たします。

コードの実装

Express コードの機能の分析に基づいて、Express の実装は次の 3 つの点に焦点を当てていることがわかります。

  • ミドルウェア機能の登録プロセス。
  • ミドルウェア機能の中核となる次のメカニズム。
  • パスマッチングに重点を置いたルート処理。

これらの点に基づいて、以下の簡単な LikeExpress クラスを実装します。

1. クラスの基本構成

まず、このクラスが実装する必要がある主なメソッドを明確にします。

  • use(): 一般的なミドルウェアの登録を実装します。
  • get() と post(): HTTP リクエストに関連するミドルウェアの登録を実装します。
  • listen(): 基本的に、これは httpServer の listen() 関数です。このクラスの listen() 関数では、httpServer が作成され、パラメーターが渡され、リクエストがリッスンされ、コールバック関数 (req, res) => が実行されます。 {} が実行されます。

ネイティブ ノード httpServer の使用法を確認します:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

したがって、LikeExpress クラスの基本構造は次のとおりです。

// Handle errors caused by unmatched routes
const createError = require('http-errors');
const express = require('express');
const path = require('path');

const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');

// `app` is an Express instance
const app = express();

// View engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// Parse JSON format data in post requests and add the `body` field to the `req` object
app.use(express.json());
// Parse the urlencoded format data in post requests and add the `body` field to the `req` object
app.use(express.urlencoded({ extended: false }));

// Static file handling
app.use(express.static(path.join(__dirname, 'public')));

// Register top-level routes
app.use('/', indexRouter);
app.use('/users', usersRouter);

// Catch 404 errors and forward them to the error handler
app.use((req, res, next) => {
    next(createError(404));
});

// Error handling
app.use((err, req, res, next) => {
    // Set local variables to display error messages in the development environment
    res.locals.message = err.message;
    // Decide whether to display the full error according to the environment variable. Display in development, hide in production.
    res.locals.error = req.app.get('env') === 'development'? err : {};
    // Render the error page
    res.status(err.status || 500);
    res.render('error');
});

module.exports = app;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

2. ミドルウェアの登録

app.use([path,] callback [, callback...]) から、ミドルウェアは関数の配列または単一の関数であることがわかります。実装を簡素化するために、ミドルウェアを関数の配列として均一に処理します。 LikeExpress クラスでは、use()、get()、および post() の 3 つのメソッドはすべてミドルウェアの登録を実装できます。リクエスト方法の違いにより、トリガーされるミドルウェアのみが異なります。そこで次のことを検討します。

  • 一般的なミドルウェア登録機能を抽象化します。
  • これら 3 つのメソッドのミドルウェア関数の配列を作成して、さまざまなリクエストに対応するミドルウェアを保存します。 use() はすべてのリクエストに対する一般的なミドルウェア登録メソッドであるため、 use() ミドルウェアを格納する配列は get() と post() の配列の結合になります。

ミドルウェアキュー配列

クラス内のメソッドから簡単にアクセスできるように、ミドルウェア配列はパブリック領域に配置する必要があります。そこで、ミドルウェアの配列をコンストラクター関数constructor()に入れました。

const http = require("http");
const server = http.createServer((req, res) => {
    res.end("hello");
});
server.listen(3003, "127.0.0.1", () => {
    console.log("node service started successfully");
});
ログイン後にコピー
ログイン後にコピー

ミドルウェア登録機能

ミドルウェアの登録とは、対応するミドルウェア配列にミドルウェアを格納することを意味します。ミドルウェア登録関数は、受信パラメータを解析する必要があります。最初のパラメータはルートまたはミドルウェアである可能性があるため、最初にそれがルートであるかどうかを判断する必要があります。存在する場合は、そのまま出力します。それ以外の場合、デフォルトはルート ルートであり、残りのミドルウェア パラメーターを配列に変換します。

const http = require('http');

class LikeExpress {
    constructor() {}

    use() {}

    get() {}

    post() {}

    // httpServer callback function
    callback() {
        return (req, res) => {
            res.json = function (data) {
                res.setHeader('content-type', 'application/json');
                res.end(JSON.stringify(data));
            };
        };
    }

    listen(...args) {
        const server = http.createServer(this.callback());
        server.listen(...args);
    }
}

module.exports = () => {
    return new LikeExpress();
};
ログイン後にコピー
ログイン後にコピー

use()、get()、post()の実装

一般的なミドルウェア登録関数 register() を使用すると、対応する配列にミドルウェアを格納するだけで、use()、get()、post() を簡単に実装できます。

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

3. ルートマッチング処理

登録関数の最初のパラメータがルートの場合、リクエスト パスがルートと一致するか、そのサブルートである場合にのみ、対応するミドルウェア関数がトリガーされます。したがって、リクエスト メソッドに従って一致するルートのミドルウェア配列を抽出するルート マッチング関数と、後続の callback() 関数を実行するためのリクエスト パスが必要です。

// Handle errors caused by unmatched routes
const createError = require('http-errors');
const express = require('express');
const path = require('path');

const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');

// `app` is an Express instance
const app = express();

// View engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// Parse JSON format data in post requests and add the `body` field to the `req` object
app.use(express.json());
// Parse the urlencoded format data in post requests and add the `body` field to the `req` object
app.use(express.urlencoded({ extended: false }));

// Static file handling
app.use(express.static(path.join(__dirname, 'public')));

// Register top-level routes
app.use('/', indexRouter);
app.use('/users', usersRouter);

// Catch 404 errors and forward them to the error handler
app.use((req, res, next) => {
    next(createError(404));
});

// Error handling
app.use((err, req, res, next) => {
    // Set local variables to display error messages in the development environment
    res.locals.message = err.message;
    // Decide whether to display the full error according to the environment variable. Display in development, hide in production.
    res.locals.error = req.app.get('env') === 'development'? err : {};
    // Render the error page
    res.status(err.status || 500);
    res.render('error');
});

module.exports = app;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

次に、httpServer のコールバック関数 callback() で、実行する必要があるミドルウェアを抽出します。

const http = require("http");
const server = http.createServer((req, res) => {
    res.end("hello");
});
server.listen(3003, "127.0.0.1", () => {
    console.log("node service started successfully");
});
ログイン後にコピー
ログイン後にコピー

4. 次の仕組みの実装

Express ミドルウェア関数のパラメーターは req、res、next です。next は関数です。これを呼び出すことによってのみ、ES6 Generator の next() と同様に、ミドルウェア関数を順番に実行できます。私たちの実装では、次の要件を持つ next() 関数を記述する必要があります:

  • 毎回、ミドルウェア キュー配列からミドルウェアを 1 つずつ順番に抽出します。
  • 抽出したミドルウェアに next() 関数を渡します。ミドルウェア配列はパブリックであるため、 next() が実行されるたびに、配列内の最初のミドルウェア関数が取り出されて実行され、ミドルウェアの順次実行の効果が得られます。
const http = require('http');

class LikeExpress {
    constructor() {}

    use() {}

    get() {}

    post() {}

    // httpServer callback function
    callback() {
        return (req, res) => {
            res.json = function (data) {
                res.setHeader('content-type', 'application/json');
                res.end(JSON.stringify(data));
            };
        };
    }

    listen(...args) {
        const server = http.createServer(this.callback());
        server.listen(...args);
    }
}

module.exports = () => {
    return new LikeExpress();
};
ログイン後にコピー
ログイン後にコピー

エクスプレスコード

constructor() {
    // List of stored middleware
    this.routes = {
        all: [], // General middleware
        get: [], // Middleware for get requests
        post: [], // Middleware for post requests
    };
}
ログイン後にコピー

Leapcell: Web ホスティング、非同期タスク、Redis のための次世代サーバーレス プラットフォーム

Mastering Express.js: A Deep Dive

最後に、Express の導入に非常に適したプラットフォームである Leapcell を紹介します。

Leapcell は、次の特徴を持つサーバーレス プラットフォームです:

1. 多言語サポート

  • JavaScript、Python、Go、または Rust を使用して開発します。

2. 無制限のプロジェクトを無料でデプロイ

  • 使用料金のみお支払いください。リクエストや料金はかかりません。

3. 比類のないコスト効率

  • アイドル料金なしの従量課金制。
  • 例: $25 は、平均応答時間 60 ミリ秒で 694 万のリクエストをサポートします。

4. 合理化された開発者エクスペリエンス

  • 直感的な UI でセットアップが簡単。
  • 完全に自動化された CI/CD パイプラインと GitOps の統合。
  • 実用的な洞察を得るリアルタイムのメトリクスとログ。

5. 容易な拡張性と高性能

  • 自動スケーリングにより、高い同時実行性を簡単に処理できます。
  • 運用上のオーバーヘッドはゼロです。構築だけに集中してください。

ドキュメントでさらに詳しく見てみましょう!

Leapcell Twitter: https://x.com/LeapcellHQ

以上がExpress.js のマスタリング: ディープダイブの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート