Я замечаю, что проекты Node.js часто включают такие папки:
/libs,/vendor,/support,/spec,/tests
Что именно они означают? Какая разница между ними и где я должен включать ссылочный код?
Я замечаю, что проекты Node.js часто включают такие папки:
/libs,/vendor,/support,/spec,/tests
Что именно они означают? Какая разница между ними и где я должен включать ссылочный код?
Что касается папок, которые вы упомянули:
/libs
обычно используется для пользовательских classes/functions/modules
/vendor
или /support
содержит сторонние библиотеки (добавляются как подмодуль git при использовании git в качестве исходного кода)/spec
содержит спецификации для тестов BDD./tests
содержит unit-тесты для приложения (с использованием инфраструктуры тестирования, см. здесь) ПРИМЕЧАНИЕ: и /vendor
и /support
устарели, поскольку NPM ввел чистое управление пакетами. Рекомендуется обрабатывать все сторонние зависимости, используя NPM и файл package.json.
При создании довольно большого приложения я рекомендую следующие дополнительные папки (особенно, если вы используете какой-то MVC-/ORM-Framework, такой как express или mongoose):
/models
содержит все ваши модели ORM (так называемые Schemas
в мангусте)/views
содержит ваши view-шаблоны (используя любой язык шаблонов, поддерживаемый в экспрессе)/public
содержит весь статический контент (изображения, таблицы стилей, клиентский JavaScript) /assets/images
содержит файлы изображений/assets/pdf
содержит статические файлы pdf/css
содержит таблицы стилей (или скомпилированный вывод с помощью механизма css)/js
содержит клиентский JavaScript/controllers
содержат все ваши экспресс-маршруты, разделенные модулем/областью вашего приложения (примечание: при использовании функции начальной загрузки экспресса эта папка называется /routes
)Я привык организовывать свои проекты таким образом, и я думаю, что это работает довольно хорошо.
Обновление для приложений Express на основе CoffeeScript (с использованием connect-assets):
/app
содержит ваш скомпилированный JavaScript/assets/
содержит все клиентские ресурсы, которые требуют компиляции /assets/js
содержит ваши файлы CoffeeScript на стороне клиента/assets/css
содержит все ваши таблицы стилей LESS/Stylus/public/(js|css|img)
содержит ваши статические файлы, которые не обрабатываются никакими компиляторами/src
содержит все ваши специфичные для сервера файлы CoffeeScript/test
содержит все скрипты модульного тестирования (реализованные с использованием тестовой платформы по вашему выбору)/views
содержит все ваши экспресс-взгляды (будь то Jade, EJS или любой другой шаблонизатор)Существует обсуждение GitHub из-за вопроса, подобного этому: https://gist.github.com/1398757
Вы можете использовать другие проекты для руководства, поиска в GitHub для:
И наконец, в книге (http://shop.oreilly.com/product/0636920025344.do) предлагается эта структура:
Еще один пример из моей архитектуры проекта можно посмотреть здесь:
├── Dockerfile
├── README.md
├── config
│ └── production.json
├── package.json
├── schema
│ ├── create-db.sh
│ ├── db.sql
├── scripts
│ └── deploy-production.sh
├── src
│ ├── app -> Containes API routes
│ ├── db -> DB Models (ORM)
│ └── server.js -> the Server initlializer.
└── test
В принципе, логическое приложение разделено на папки DB и APP внутри директории SRC.
Это косвенный ответ на структуру папок, очень связанную.
Несколько лет назад у меня был один и тот же вопрос, я взял структуру папок, но мне пришлось сделать много каталогов, перемещающихся позже, потому что папка предназначалась для другой цели, чем то, что я читал в Интернете, то есть какой именно папка имеет разные значения для разных людей в некоторых папках.
Теперь, выполнив несколько проектов, в дополнение к объяснению во всех других ответах, о самой структуре папок, я бы настоятельно предложил следовать структуре самого Node.js, который можно увидеть по адресу: https://github.com/nodejs/node. Он имеет большую детализацию по всем, скажем, линтам и другим, структура файлов и папок, которые у них есть и где. В некоторых папках есть README, которые объясняют, что находится в этой папке.
Начиная с этой структуры, хорошо, потому что в какой-то момент появляется новое требование, но у вас будет возможность для улучшения, поскольку уже после этого выполняется Node.js, который поддерживается на протяжении многих лет.
Надеюсь, что это поможет.
Важно отметить, что нет единого мнения о том, что лучший подход и соответствующие структуры в целом не обеспечивают и не поощряют определенные структуры.
Я нахожу это разочаровывающим и огромным, но не менее важным. Это своего рода недооцененная версия (но более важная для IMO) проблемы руководства по стилю. Мне нравится указывать на это, потому что ответ один и тот же: не имеет значения, какую структуру вы используете, если она четко определена и последовательна.
Поэтому я бы предложил вам найти всеобъемлющее руководство, которое вам нравится, и дать понять, что проект основан на этом.
Это не легко, особенно если вы новичок в этом! Ожидайте проводить часы, исследуя. Вы найдете большинство руководств, рекомендующих MVC-подобную структуру. Хотя несколько лет назад это могло быть солидным выбором, сегодня это не всегда так. Например здесь другой подход.
app.js
package.json
route-> index.route.js
->mainApp.route.js
sample app.js:
var express = require('express');
var app = express();
var path = require('path');
var helmet = require("helmet");
var bodyParser = require('body-parser');
var logger = require('./util/logger.util');
var errorUtil = require('./util/errorMessages.util');
var HTTP_CODES = require('./util/httpCodes.util');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
//CORS support with OPTIONS
app.use(function (req, res, next) {
var oneof = false;
if (req.headers.origin) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
oneof = true;
}
if (req.headers['access-control-request-method']) {
res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
oneof = true;
}
if (req.headers['access-control-request-headers']) {
res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
oneof = true;
}
if (oneof) {
res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
}
// intercept OPTIONS method
if (oneof && req.method === 'OPTIONS') {
res.sendStatus(200);
} else {
next();
}
});
//Mount points
app.use('/', require('./routes/index.route'));
app.use('/v1', require('./routes/mainApp.route'));
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function (err, req, res, next) {
//err.isBoom => JOI validation error flag
if (err.isBoom) {
var error = {
"code": HTTP_CODES.BAD_REQUEST,
"errors": [
{
"domain": "Servers",
"message": err.data[0].message.replace(/\"/g,'')
}
],
"message": "Enter a valid Query Parameter"
};
res.status(HTTP_CODES.BAD_REQUEST);
res.json(error);
} else if (err.status === 404) {
var error = {
"code": HTTP_CODES.NOT_FOUND,
"errors": [
{
"domain": "Servers",
"message": "Invalid Request"
}
],
"message": "Enter a valid Query or Path Parameter"
};
res.status(HTTP_CODES.NOT_FOUND)
res.json(error);
} else {
var error = {
"code": HTTP_CODES.INTERNAL_SERVER_ERROR,
"errors": [
{
"domain": "API",
"message": err.code
}
],
"message": "Database Error"
};
logger.debug(err);
res.status(HTTP_CODES.INTERNAL_SERVER_ERROR)
res.json(error);
}
});
module.exports = app;
Sample index.route.js:
var express = require('express');
var router = express.Router();
/* GET Landing Page*/
router.get('/', function (req, res) {
res.render('index', { title: 'API' });
});
module.exports = router;
enter code here