Node.js 是否有“标准”的方式来组织/提升Express.js服务器?
我对Node.js和JavaScript世界非常陌生,来自PHP环境 我面临着以下问题:许多PHP框架都做了大量的增强应用程序的工作,即自己设置服务器、中间件、记录器和压缩 在Express中,我在单个app.ts TypeScript示例中手动执行此操作:Node.js 是否有“标准”的方式来组织/提升Express.js服务器?,node.js,typescript,express,Node.js,Typescript,Express,我对Node.js和JavaScript世界非常陌生,来自PHP环境 我面临着以下问题:许多PHP框架都做了大量的增强应用程序的工作,即自己设置服务器、中间件、记录器和压缩 在Express中,我在单个app.ts TypeScript示例中手动执行此操作: // Create schema and load configurations import config from './config'; // Configure and load the logger import logger
// Create schema and load configurations
import config from './config';
// Configure and load the logger
import logger from './logger';
// Create the Express.js server
// ...
// Configure global middlewares
app.use(morgan('tiny'));
app.use(compression());
app.use('/', express.static(`${__dirname}/../public`));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Configure global routing
app.get('/', (req, res) => {
res.sendFile(`${__dirname}/../public/index.html`);
});
// Establish a connection to the database server
createConnection({
// options
}).then(() => {
// Start the web server
app.listen(/* options */);
});
这个文件有一部分太大了,我想把它分开。在节点生态系统中是否有任何标准的方法
以下方法有意义吗
import * as express from 'express';
import config from './config';
import { Connection } from 'typeorm';
export class ServerConfigurer {
configureApp(app): void {
// Configure global middlewares
}
createConnection(): Promise<Connection> {
// Create MySQL connection
}
}
。。。然后在my app.ts中,使用ServerConfigurer类提升应用程序
在Express中,我在单个app.ts中手动执行此操作
几乎所有的微框架都是如此,Express尤其如此。组织项目的方法没有对错之分
是否有“标准”的方式来组织/提升Express.js服务器
通常,您会发现许多示例都遵循这种模式。例如,您通常会发现布局如下所示:
example
├── app.js
├── controllers/
├── models/
├── routes/
├── public/
└── views/
但是,Express主要用于构建API。现在,前端视图/和公共/文件夹通常是一个React、Vue或Angular应用程序,它是自己的项目,独立于Express API。综上所述,Express API项目的典型布局为:
example
├── app.js
├── controllers/
├── models/
└── routes/
app.js是一切初始化的地方。所谓初始化,我指的是装载路由、中间件、数据库连接、事件侦听器……任何真正的东西。app.js是您的Express应用程序的主要/第一个入口点
models/是定义所有数据库模型的地方,通常是Mongo。例如:
// models/contact.js
const mongoose = require('mongoose');
const definition = {
name: {
type: String,
trim: true,
required: true,
}
};
const schema = new mongoose.Schema(definition, { timestamps: true });
module.exports = mongoose.model('Contact', schema);
// controllers/contact.js
const Contact = require('../models/contact');
exports.index = async (req, res) => {
const contacts = await Contact.find().exec();
res.json({
status: 200,
data: contacts,
});
};
// routes/contact.js
const express = require('express');
const contactController = require('../controllers/contact');
const router = express.Router();
router.get('/', contactController.index);
module.exports = router;
控制器/是所有路由处理程序都要去的地方。例如:
// models/contact.js
const mongoose = require('mongoose');
const definition = {
name: {
type: String,
trim: true,
required: true,
}
};
const schema = new mongoose.Schema(definition, { timestamps: true });
module.exports = mongoose.model('Contact', schema);
// controllers/contact.js
const Contact = require('../models/contact');
exports.index = async (req, res) => {
const contacts = await Contact.find().exec();
res.json({
status: 200,
data: contacts,
});
};
// routes/contact.js
const express = require('express');
const contactController = require('../controllers/contact');
const router = express.Router();
router.get('/', contactController.index);
module.exports = router;
最后我们有routes/这是定义所有路由和挂载/映射控制器的地方。例如:
// models/contact.js
const mongoose = require('mongoose');
const definition = {
name: {
type: String,
trim: true,
required: true,
}
};
const schema = new mongoose.Schema(definition, { timestamps: true });
module.exports = mongoose.model('Contact', schema);
// controllers/contact.js
const Contact = require('../models/contact');
exports.index = async (req, res) => {
const contacts = await Contact.find().exec();
res.json({
status: 200,
data: contacts,
});
};
// routes/contact.js
const express = require('express');
const contactController = require('../controllers/contact');
const router = express.Router();
router.get('/', contactController.index);
module.exports = router;
最后,我们需要将一切联系在一起:
const express = require('express');
const mongoose = require('mongoose');
const contactRoutes = require('./routes/contact');
const app = express();
// Connect to mongo.
mongoose.connect(process.env.MONGO_URI);
// Fail on connection error since we need the database.
mongoose.connection.on('error', error => { throw error; });
// Allows parsing the body content via `req.body`
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Mount API routes.
app.use('/contacts', contactRoutes);
app.listen(process.env.NODE_PORT, () => console.log(`Listening on ${process.env.NODE_PORT}`))
没有标准的方法。我想说,我见过的最常见的方法是在一个文件中初始化服务器和所有全局中间件,然后将路由定义放在导出路由器的其他文件中。然后,您可以导入它们并用一行app激活它们。use/somepath,require./someRoutes.js;陈述我还没有看到创建serverConfigurer类的必要性,因为它主要是在代码中的一个地方只使用一次的东西。通常,如果您将路由定义移出服务器初始化文件,那么它就不会太大。非常好的解释。是的,我只关注app.ts,因为我的控制器和模型已经在一个单独的文件夹中,然后加载到app.ts中。因此,在app.ts中,将模块粘在一起是很常见的,只有最顶层的模块,这意味着全局性的东西,例如适用于所有路由的中间件。您可以在我的示例中看到,我只在控制器中导入联系人模型。不需要在主应用程序文件中导入它。