Я замечаю, что проекты 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