【问题标题】:How to bootstrap all models & services on server start express js如何引导服务器上的所有模型和服务启动 express js
【发布时间】:2016-10-19 15:45:52
【问题描述】:

我想在服务器启动时加载我的所有模型,这样在与服务器进行任何交互之前就不需要包含模型文件。

现在,我只需要我需要的所有控制器和其他文件中的文件。但我计划有一个文件并包括所有模型并在服务器启动时将它们设为全局。这样我就不需要在任何地方都需要它们了。

例如:-

global.ConfigModel = require(APP_PATH + '/api/models/ConfigModel.js');

那么,请您指出我是好方法还是必须使用其他方法。

我想实现 Sails Js 框架引导模型和服务的方式,这样就不需要一次又一次地要求文件。

有什么帮助吗?

【问题讨论】:

    标签: node.js express mongoose sails.js


    【解决方案1】:

    使用global 不是一个好主意。但是在每个服务文件中一次又一次地为想要的模型使用require()也很麻烦。

    我建议你有适当的目录层次结构并使用index.js。例如,

    project_dir/
        models/
            Book.js
            Config.js
            index.js
        services/
            auth.js
            book.js
            index.js
    

    models/index.js,我require所有的模型只有一次:

    'use strict';
    
    module.exports = {
        Book: require('./Book'),
        Config: require('./Config')
    };
    

    services/index.js 也是如此。

    然后在任何地方,我只需 require 模型目录并访问每个模型作为它的关键之一。

    'use strict';
    
    const models = require('./models'); // It looks for index.js in ./models
    
    function myfunc() {
        return models.Book.getAll();
    }
    

    这样你就不必一遍又一遍地require所有模型,而且看起来也很干净。

    我将它用于模型、助手、服务、存储库、路由。

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      通过将 express 'app' 传递给辅助方法,我们可以收集所有模型和控制器,并将它们分别添加到 app.models 和 app.controllers 对象中。我们也会遍历路线,但不需要存储它们。

      目录结构:

      myApplication
       |__ src  
       |   |__ controllers
       |        |__ Account.js
       |            index.js
       |            User.js
       |       models
       |        |__ Account.js
       |            index.js
       |            User.js
       |       routes
       |        |__ account.js
       |            index.js
       |            user.js
       |
       |__ node_modules
       |__ package.json
       |__ 
       |__
       |__
       |
       |__ server.js
      

      我们使用 index.js 文件作为我们的辅助方法。这些方法只是遍历目录中的所有 js 文件(index.js 除外)并需要它们。

      // controllers/index.js
      var fs = require('fs');
      var path = require('path');
      module.exports = function(app) {
          app.controllers = {};
          fs.readdirSync(__dirname).forEach(function(f) {
              if (f !== "index.js" && path.extname(f) === '.js'){
                  var controller = require(path.join(__dirname,f))(app);
                  app.controllers[controller.name] = controller;
              }
          });
      };
      
      
      // models/index.js
      var fs = require('fs');
      var path = require('path');
      module.exports = function(app) {
          app.models = {};
          fs.readdirSync(__dirname).forEach(function(f) {
              if (f !== "index.js" && path.extname(f) === '.js'){
                  var model = require(path.join(__dirname,f))(app);
                  app.models[model.modelName] = model;
              }
          });
      };
      
      
      // routes/index.js
      var fs = require('fs');
      var path = require('path');
      module.exports = function (app) {
        fs.readdirSync(__dirname).forEach(function(file) {
            if (file !== "index.js" && path.extname(file) === '.js'){
              require(path.join(__dirname, file))(app);
            }
          });
      };
      

      示例模型、控制器和路由:

      // models/Account.js
      var mongoose = require('mongoose');
      var Schema = mongoose.Schema;
      module.exports = function(){
          var AccountSchema = new Schema({
              number : {type : String, required: true},
              owner: {type: Schema.Types.ObjectId, ref: 'User'}
          });
          return mongoose.model("Account", AccountSchema); //'Account' is used to access this model as app.models.Account
      };
      
      
      // controllers/Account.js
      module.exports = function(app) {
          var Account  = app.models.Account;
          var Controller = {
              name: 'Account'  //this name is used to access this controller in routes as app.controllers.Account
          };
      
          // POST method to create user account
          Controller.createAccount = function(req, res) {
             Account.create(req.body, function(err, result){
                 if(err){
                     res.status(500).send("Server Error")
                 }
                 else{
                     res.send({message: "account created"});
                 }
             })
          };
      
          return Controller;
      };
      
      
      // routes/account.js
      module.exports = function (app) {
          var AccountController = app.controllers.Account;
          app.post('/api/accounts', AccountController.createAccount);
      };
      

      在 server.js 中:

      var express = require('express');
      var app = express();
      .
      .
      .
      . // server configurations
      .
      .
      .
      // maintain the below order:
      require("./src/models")(app); // call the method in /src/models/index.js and pass express app
      require("./src/controllers")(app);
      require("./src/routes")(app);
      

      你不会在模型、控制器或路由中添加一个空的 js 文件,因为它会通过错误。

      【讨论】:

        【解决方案3】:

        在全局命名空间中添加变量可能是一场噩梦,尤其是当项目变得越来越大时。您正在无缘无故地污染全局命名空间,其他可能加入该项目的开发人员将无法很容易地理解正在发生的事情,并且存在覆盖此变量的危险。就个人而言,我反对这种做法。这只是您必须在每个文件上要求的一行,它将使您的项目更安全。

        如果您想摆脱需求并拥有所有依赖项,那么最好寻找依赖注入和控制反转。很少有模块可以为您做到这一点,我建议您对它们进行一些调查。

        【讨论】:

        • 感谢您的信息。但是你有没有想过,如果我有很多控制器文件、服务,我必须一直要求文件。所以它也只是一个无聊的东西。这就是为什么我只是想有一个更好的解决方案。
        猜你喜欢
        • 2017-04-11
        • 2018-07-17
        • 1970-01-01
        • 2017-05-15
        • 2023-04-02
        • 1970-01-01
        • 2014-11-01
        • 2012-04-14
        • 1970-01-01
        相关资源
        最近更新 更多