express.jsアプリケーションを構成する方法は?


102

Express.jsアプリケーションでapp.jsファイルを分割してモジュール化するための共通の規則はありますか?または、すべてを1つのファイルに保存するのが一般的ですか?


3
それらをルートに分割する人々がいます。また、エクスプレスリソースを確認することもできます。
BRampersad 2011年

@Brandon_Rリソースを試しましたか?私はそれをちらっと見て、それがきちんと見えたと思った、まだタイヤをまだ蹴っていない。
チャンス

1
少し遅くなりましたが、最近、app.jsをコントローラーやビューなどでうまく分解できるように、express用のルーターをオープンソース化しました。github.com/ kishorenc
jeffreyveon

回答:


82

私は次のように分割されました:

~/app
|~controllers
| |-monkey.js
| |-zoo.js
|~models
| |-monkey.js
| |-zoo.js
|~views
| |~zoos
|   |-new.jade
|   |-_form.jade
|~test
|  |~controllers
|    |-zoo.js
|  |~models
|    |-zoo.js
|-index.js

エクスポートを使用して、関連するものを返します。たとえば、私が行うモデルでは:

module.exports = mongoose.model('PhoneNumber', PhoneNumberSchema);

電話番号を作成する必要がある場合は、次のように簡単です。

var PhoneNumber = require('../models/phoneNumber');
var phoneNumber = new PhoneNumber();

スキーマを使用する必要がある場合は、 PhoneNumber.schema

(これは、ルートフォルダーから作業していて、1レベル上に移動してからモデルに降りる必要があることを前提としています)


編集4

Express Wikiには、その上に構築されたフレームワークのリストがあります。

そのうち、Twitterのマタドールはかなりよく構成されていると思います。実際に、アプリの一部を読み込む方法と非常によく似たアプローチを使用しました。

derby.jsも非常に興味深く見えます。これは、誇大宣伝のない流星に似ており、実際にクレジットが支払われるべき場所(特にノードとエクスプレス)にクレジットを提供します。


編集3

CoffeeScriptのファンで(私はそうではありません)、RailsのL&Fが必要な場合は、Tower.jsあります。


編集2

Railsに精通していて、いくつかの概念のブリードオーバーを気にしない場合は、Locomotiveがあります。Express上に構築された軽量のフレームワークです。RoRと非常によく似た構造を持ち、より基本的な概念(ルーティングなど)の一部を継承しています。

使用する予定がない場合でも、チェックアウトする価値があります。


編集1

nodejs-express-mongoose-demoは、私の構造と非常によく似ています。見てみな。


2
ビジネスロジックはどこに行くのですか?認証などにヘルパーを使用したことはありますか?
エリックザレッド

@ErictheRed MVCパターン(レール、Asp.Net mvcなど)に精通している場合、私はルートをコントローラーと見なし、その後すべての種類のものが適切に配置されます。ビジネスロジックはモデルに組み込まれます(ただし、検証とマングースに問題があります)。ヘルパーのために、私は再利用するもののために自分のためにまとめている単純な内部ユーティリティライブラリでエクスポートを使用しています。
チャンス

サンプルセットアップをgithubにアップロードして確認してください。ルートフォルダ/ファイルには何が入っていますか?
chovy

1
@chovy 非常によく似た構造を持つgithub.com/qed42/nodejs-express-mongoose-demoへのリンクを追加しました
Chance

Expressの上に構築された肥大化したフレームワークを回避することをお勧めします
Raynos

9

警告:ノードノックアウトのために私が一緒にハッキングしたコードを参照しています。

分割の詳細についてapp.jsは、次のapp.jsファイルがあります。

var express = require('express'),
    bootstrap = require('./init/bootstrap.js'),
    app = module.exports = express.createServer();

bootstrap(app);

これは基本的に、すべてのブートストラップを別のファイルに配置し、サーバーをブートストラップすることを意味します。

では、ブートストラップは何をするのでしょうか?

var configure = require("./app-configure.js"),
    less = require("./watch-less.js"),
    everyauth = require("./config-everyauth.js"),
    routes = require("./start-routes.js"),
    tools = require("buffertools"),
    nko = require("nko"),
    sessionStore = new (require("express").session.MemoryStore)()

module.exports = function(app) {
    everyauth(app);
    configure(app, sessionStore);
    less();
    routes(app, sessionStore);
    nko('/9Ehs3Dwu0bSByCS');


    app.listen(process.env.PORT);
    console.log("server listening on port xxxx");
};

まあそれはすべてのサーバー初期化設定を素敵なチャンクに分割します。具体的には

  • everyauthを使用してすべてのリモートOAuth認証を設定するチャンクがあります。
  • アプリケーションを構成するチャンクがあります(基本的にを呼び出すapp.configure
  • パンチが少ないコードが少しあるので、実行時にそれより少ないものをcssに再コンパイルします。
  • すべてのルートを設定するコードがあります
  • 私はこの小さなnkoモジュールを呼び出します
  • 最後に、ポートをリッスンしてサーバーを起動します。

たとえば、ルーティングファイルを見てみましょう

var fs = require("fs"),
    parseCookie = require('connect').utils.parseCookie;

module.exports = function(app, sessionStore) {
    var modelUrl = __dirname + "/../model/",
        models = fs.readdirSync(modelUrl),
        routeUrl = __dirname + "/../route/"
        routes = fs.readdirSync(routeUrl);

ここでは、すべてのモデルとルートをファイルの配列としてロードします。

免責事項: httpサーバーを起動する前(の前)readdirSyncに呼び出された場合のみ問題ありません.listen。サーバーの開始時に同期ブロッキング呼び出しを呼び出すと、コードが読みやすくなります(基本的にはハックです)。

    var io = require("socket.io").listen(app);

    io.set("authorization", function(data, accept) {
        if (data.headers.cookie) {
            data.cookie = parseCookie(data.headers.cookie);

            data.sessionId = data.cookie['express.sid'];

            sessionStore.get(data.sessionId, function(err, session) {

                if (err) {
                    return accept(err.message, false);
                } else if (!(session && session.auth)) {
                    return accept("not authorized", false)
                }
                data.session = session;
                accept(null, true);
            });
        } else {
            return accept('No cookie', false);
        }
    });

ここで、私はsocket.ioをパンチして、トムとジャックに私のsocket.ioサーバーと通信させるのではなく、実際に認証を使用します

    routes.forEach(function(file) {
        var route = require(routeUrl + file),
            model = require(modelUrl + file);

        route(app, model, io);
    });
};

ここで、ルートファイルから返された各ルートオブジェクトに関連モデルを渡すことで、ルートを開始します。

基本的にjistは、すべてを素敵な小さなモジュールに整理してから、いくつかのブートストラップメカニズムを備えています。

私の他のプロジェクト(私のブログ)には、同様の構造のinitファイルがあります

免責事項:ブログは壊れていて構築できません。現在取り組んでいます。



0

私のアプリはexpress-generatorツールの上に構築されています。npm install express-generator -gを実行してインストールし、を使用して実行でき express <APP_NAME>ます。

見方を変えると、私の小さなアプリケーションの構造の1つは次のようになります。

~/
|~bin
| |-www
|
|~config
| |-config.json
|
|~database
| |-database.js
|
|~middlewares
| |-authentication.js
| |-logger.js
|
|~models
| |-Bank.js
| |-User.js
|
|~routes
| |-index.js
| |-banks.js
| |-users.js
|
|~utilities
| |-fiat-converersion.js
|
|-app.js
|-package.json
|-package-lock.json

この構造について私が気に入っているクールな点の1つは、開発したエクスプレスアプリケーションに採用することになり、ルートの編成方法です。app.use()特にファイルが大きくなるので、app.jsへの各ルートファイルと各ルートを要求する必要がありませんでした。そのため、すべてのapp.use()ファイルを./routes/index.jsファイルにグループ化して一元化すると便利です。

最終的に、私のapp.jsは次のようになります。

...
const express = require('express');
const app = express();

...
require('./routes/index')(app);

そして、私の./routes/index.jsは次のようになります。

module.exports = (app) => {
  app.use('/users', require('./users'));
  app.use('/banks', require('./banks'));
};

私は単純にできる午前require(./users)私は私が「グループ」の複数のルートすることを可能にし、アプリケーションをよりモジュラー作ることを目標に、一度に書き出すexpress.Routerを使用して、ユーザーのルートを()書きましたので。

これは、私の./routers/users.jsルートでうまくいく例です:


const router = require('express').Router();

router.post('/signup', async (req, res) => {
    // Signup code here
});

module.exports = router;

うまくいけば、これがあなたの質問に答えるのに役立ちました!がんばって!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.