Có quy ước chung nào để chia nhỏ và sửa đổi app.js
tệp trong ứng dụng Express.js không? Hay là thông thường để giữ mọi thứ trong một tệp duy nhất?
Có quy ước chung nào để chia nhỏ và sửa đổi app.js
tệp trong ứng dụng Express.js không? Hay là thông thường để giữ mọi thứ trong một tệp duy nhất?
Câu trả lời:
Tôi đã chia tay như sau:
~/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
Tôi sử dụng Exports để trả lại những gì có liên quan. Ví dụ, trong các mô hình tôi làm:
module.exports = mongoose.model('PhoneNumber', PhoneNumberSchema);
và sau đó nếu tôi cần tạo một số điện thoại, nó đơn giản như sau:
var PhoneNumber = require('../models/phoneNumber');
var phoneNumber = new PhoneNumber();
nếu tôi cần sử dụng lược đồ, thì PhoneNumber.schema
(giả định rằng chúng tôi đang làm việc từ thư mục tuyến đường và cần tăng 1 cấp độ rồi xuống mô hình)
Các wiki nhanh có một danh sách của các khuôn khổ xây dựng trên đầu trang của nó.
Trong số đó, tôi nghĩ rằng matador của Twitter được cấu trúc khá tốt. Chúng tôi thực sự đã sử dụng một cách tiếp cận rất giống với cách họ tải các phần của ứng dụng.
derby.js cũng trông cực kỳ thú vị. Nó giống như một thiên thạch mà không có tất cả sự cường điệu và thực sự mang lại tín dụng khi tín dụng đến hạn (đặc biệt là nút và nhanh).
Nếu bạn là một fan hâm mộ của CoffeeScript (tôi thì không) và thực sự muốn có L&F of Rails, thì cũng có Tower.js .
Nếu bạn đã quen thuộc với Rails và không bận tâm đến việc thừa một số khái niệm thì đó là Locomotive . Nó là một khung công tác nhẹ được xây dựng trên Express. Nó có cấu trúc rất giống với RoR và mang một số khái niệm thô sơ hơn (chẳng hạn như định tuyến).
Nó đáng để kiểm tra ngay cả khi bạn không định sử dụng nó.
nodejs-express-mongoose-demo rất giống với cách tôi đã cấu trúc. Kiểm tra nó ra.
Cảnh báo: mã tham chiếu mà tôi đã hack cùng nhau để loại bỏ nút, nó có vẻ hiệu quả nhưng không phải là thanh lịch hoặc bóng bẩy.
Để cụ thể hơn về việc chia nhỏ, app.js
tôi có tệp app.js sau
var express = require('express'),
bootstrap = require('./init/bootstrap.js'),
app = module.exports = express.createServer();
bootstrap(app);
Về cơ bản, điều này có nghĩa là tôi đặt tất cả khởi động của mình trong một tệp riêng biệt, sau đó tôi khởi động máy chủ.
Vậy bootstrap để làm gì?
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");
};
Nó chia nhỏ tất cả thiết lập khởi tạo máy chủ thành nhiều phần đẹp mắt. Đặc biệt
app.configure
)Ví dụ, chúng ta hãy xem xét tệp định tuyến
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);
Ở đây tôi tải tất cả các mô hình và tuyến đường của mình dưới dạng các mảng tệp.
Disclaimer: readdirSync
chỉ ok khi được gọi trước khi bạn khởi động máy chủ http (trước đó .listen
). Gọi các cuộc gọi chặn đồng bộ vào thời gian bắt đầu của máy chủ chỉ làm cho mã dễ đọc hơn (về cơ bản đó là một cuộc tấn công)
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);
}
});
Ở đây tôi đục lỗ socket.io để thực sự sử dụng ủy quyền thay vì cho phép bất kỳ tom và jack nào nói chuyện với máy chủ socket.io của tôi
routes.forEach(function(file) {
var route = require(routeUrl + file),
model = require(modelUrl + file);
route(app, model, io);
});
};
Ở đây tôi bắt đầu các tuyến đường của mình bằng cách chuyển mô hình có liên quan vào từng đối tượng tuyến đường được trả về từ tệp tuyến đường.
Về cơ bản, jist là bạn sắp xếp mọi thứ thành các mô-đun nhỏ xinh và sau đó có một số cơ chế khởi động.
Dự án khác của tôi (blog của tôi) có tệp init có cấu trúc tương tự .
Tuyên bố từ chối trách nhiệm: blog bị hỏng và không xây dựng được, tôi đang làm việc trên nó.
Đối với tổ chức định tuyến duy trì bạn có thể kiểm tra bài viết này về các nhanh-routescan mô-đun nút và thử nó. Đây là giải pháp tốt nhất cho tôi.
Tôi có các ứng dụng của mình được xây dựng dựa trên công cụ tạo nhanh. Bạn có thể cài đặt nó bằng cách chạy npm install express-generator -g
và chạy nó bằng cách sử dụng express <APP_NAME>
.
Để cung cấp cho bạn một góc nhìn, một trong những cấu trúc ứng dụng nhỏ hơn của tôi trông như thế này:
~/
|~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
Một điều thú vị mà tôi thích về cấu trúc này mà tôi cuối cùng đã áp dụng cho bất kỳ ứng dụng express nào mà tôi phát triển là cách các tuyến đường được tổ chức. Tôi không thích phải yêu cầu từng tệp định tuyến vào app.js và app.use()
từng tuyến đường, đặc biệt là khi tệp lớn hơn. Do đó, tôi thấy hữu ích khi nhóm và tập trung tất cả app.use()
vào tệp ./routes/index.js.
Cuối cùng, app.js của tôi sẽ trông giống như sau:
...
const express = require('express');
const app = express();
...
require('./routes/index')(app);
và ./routes/index.js của tôi sẽ trông giống như sau:
module.exports = (app) => {
app.use('/users', require('./users'));
app.use('/banks', require('./banks'));
};
Tôi có thể đơn giản là require(./users)
vì tôi đã viết tuyến người dùng bằng express.Router () cho phép tôi "nhóm" nhiều tuyến và sau đó xuất chúng cùng một lúc, với mục tiêu làm cho ứng dụng trở nên mô-đun hơn.
Đây là một ví dụ về những gì bạn sẽ ổn trên tuyến đường ./routers/users.js của tôi:
const router = require('express').Router();
router.post('/signup', async (req, res) => {
// Signup code here
});
module.exports = router;
Hy vọng rằng điều này đã giúp trả lời câu hỏi của bạn! May mắn nhất!