5

我正在使用 Socket.IO 开发我的第一个 Node.js 应用程序,一切都很好,但现在应用程序正在慢慢变大,我想将应用程序代码分成不同的文件以便更好地维护。

例如,我在主文件中定义了我所有的猫鼬模式和路由。下面是 socket.IO 连接的所有函数。但是现在我想要一个额外的模式文件,一个额外的路由文件和一个函数文件。

当然,我知道编写自己的模块或使用 require 加载文件的可能性。这对我来说没有意义,因为我不能使用 app、io 或 db 等变量而不使它们成为全局变量。如果我将它们传递给我模块中的函数,我将无法更改它们。我错过了什么?我想看看一个例子,这是如何在不使用全局变量的情况下在实践中完成的。

4

1 回答 1

15

听起来您有一个高度耦合的应用程序;您很难将代码拆分为模块,因为不应该相互依赖的应用程序片段会这样做。研究OO设计的原则可能会有所帮助。

例如,如果您要将数据库逻辑从主应用程序中分离出来,您应该能够这样做,因为数据库逻辑不应该依赖于app或者io-- 它应该能够独立工作,并且您require可以将其放入应用程序的其他部分来使用它。

这是一个相当基本的示例——它比实际代码更像是伪代码,因为重点是通过示例演示模块化,而不是编写工作应用程序。它也只是您决定构建应用程序的众多方式中的一种。

// =============================
// db.js

var mongoose = require('mongoose');
mongoose.connect(/* ... */);

module.exports = {
  User: require('./models/user');
  OtherModel: require('./models/other_model');
};


// =============================
// models/user.js (similar for models/other_model.js)

var mongoose = require('mongoose');
var User = new mongoose.Schema({ /* ... */ });
module.exports = mongoose.model('User', User);


// =============================
// routes.js

var db = require('./db');
var User = db.User;
var OtherModel = db.OtherModel;

// This module exports a function, which we call call with
// our Express application and Socket.IO server as arguments
// so that we can access them if we need them.
module.exports = function(app, io) {
  app.get('/', function(req, res) {
    // home page logic ...
  });

  app.post('/users/:id', function(req, res) {
    User.create(/* ... */);
  });
};


// =============================
// realtime.js

var db = require('./db');
var OtherModel = db.OtherModel;

module.exports = function(io) {
  io.sockets.on('connection', function(socket) {
    socket.on('someEvent', function() {
      OtherModel.find(/* ... */);
    });
  });
};


// =============================
// application.js

var express = require('express');
var sio = require('socket.io');
var routes = require('./routes');
var realtime = require('./realtime');

var app = express();
var server = http.createServer(app);
var io = sio.listen(server);

// all your app.use() and app.configure() here...

// Load in the routes by calling the function we
// exported in routes.js
routes(app, io);
// Similarly with our realtime module.
realtime(io);

server.listen(8080);

这一切都是在我对各种 API 的文档进行最少检查的情况下写下来的,但我希望它为你如何从应用程序中提取模块埋下种子。

于 2012-11-11T19:13:50.067 回答