web-dev-qa-db-ja.com

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

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

102
Eric the Red

私は次のように私のものを分割しています:

~/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

(routesフォルダーから作業しており、モデルを1レベル上に移動してから下に移動する必要があると想定しています)


編集4

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

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

derby.jsも非常に興味深いようです。誇大広告のない meteor と似ており、実際にクレジットが必要な場所(特にnodeおよびexpress)でクレジットを提供します。


編集3

CoffeeScriptのファン(私ではない)であり、reeeeaaaaaallyがRailsのL&Fを望んでいる場合、Tower.js


編集2

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

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


編集1

nodejs-express-mongoose-demoは、私が鉱山を構築した方法に非常に似ています。見てみな。

82
Chance

警告:ノードノックアウトのために一緒にハッキングしたコードを参照しますが、それは一種の動作ですが、エレガントまたは洗練されたものからはほど遠いです。

app.jsの分割についてより具体的にするには、次の app.js ファイルがあります

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

bootstrap(app);

これは基本的に、すべてのブートストラップを別のファイルに配置してから、サーバーbootstrap.

それでは bootstrap は何をしますか?

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");
};

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

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

たとえば、 routing ファイルを見てみましょう

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);

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

免責事項:readdirSyncは、httpサーバーを起動する前にを呼び出した場合にのみ問題ありません.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);
    });
};

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

基本的には、すべてを素敵な小さなモジュールに整理し、ブートストラップメカニズムを使用するということです。

私の他のプロジェクト(私のブログ) 同様の構造を持つ初期化ファイルがあります

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

9
Raynos

保守可能なルーティング組織については、 この記事 について express-routescanノードモジュール とそれを試してみてください。これは私にとって最高のソリューションです。

1

エクスプレスジェネレーターツールの上にアプリを構築しています。 _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.jsおよびapp.use()各ルートに各ルートファイルを要求する必要がありませんでした。そのため、すべての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'));
};
_

Express.Router()を使用してユーザールートを記述したため、アプリケーションをよりモジュール化することを目的として、複数のルートを「グループ化」して一度にエクスポートできるため、単純にrequire(./users)できます。

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

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

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

module.exports = router;
_

これがあなたの質問に答えてくれることを願っています!幸運を祈ります!

0
JKleinne