Структура папки для проекта Node.js

Я замечаю, что проекты Node.js часто включают такие папки:

/libs,/vendor,/support,/spec,/tests

Что именно они означают? Какая разница между ними и где я должен включать ссылочный код?

Ответ 1

Что касается папок, которые вы упомянули:

  • /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 или любой другой шаблонизатор)

Ответ 2

Существует обсуждение GitHub из-за вопроса, подобного этому: https://gist.github.com/1398757

Вы можете использовать другие проекты для руководства, поиска в GitHub для:

  • ThreeNodes.js - на мой взгляд, похоже, имеет определенную структуру, не подходящую для каждого проекта;
  • легче - более простая структура, но не хватает организации;

И наконец, в книге (http://shop.oreilly.com/product/0636920025344.do) предлагается эта структура:

  • index.html
  • JS/
    • main.js
    • модели /
    • вид /
    • Коллекции /
    • Шаблоны /
    • ЛИЭС /
      • магистральная /
      • Подчеркивание /
      • ...
  • CSS/
  • ...

Ответ 3

Еще один пример из моей архитектуры проекта можно посмотреть здесь:

├── 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.

Ответ 4

Это косвенный ответ на структуру папок, очень связанную.

Несколько лет назад у меня был один и тот же вопрос, я взял структуру папок, но мне пришлось сделать много каталогов, перемещающихся позже, потому что папка предназначалась для другой цели, чем то, что я читал в Интернете, то есть какой именно папка имеет разные значения для разных людей в некоторых папках.

Теперь, выполнив несколько проектов, в дополнение к объяснению во всех других ответах, о самой структуре папок, я бы настоятельно предложил следовать структуре самого Node.js, который можно увидеть по адресу: https://github.com/nodejs/node. Он имеет большую детализацию по всем, скажем, линтам и другим, структура файлов и папок, которые у них есть и где. В некоторых папках есть README, которые объясняют, что находится в этой папке.

Начиная с этой структуры, хорошо, потому что в какой-то момент появляется новое требование, но у вас будет возможность для улучшения, поскольку уже после этого выполняется Node.js, который поддерживается на протяжении многих лет.

Надеюсь, что это поможет.

Ответ 5

Важно отметить, что нет единого мнения о том, что лучший подход и соответствующие структуры в целом не обеспечивают и не поощряют определенные структуры.

Я нахожу это разочаровывающим и огромным, но не менее важным. Это своего рода недооцененная версия (но более важная для IMO) проблемы руководства по стилю. Мне нравится указывать на это, потому что ответ один и тот же: не имеет значения, какую структуру вы используете, если она четко определена и последовательна.

Поэтому я бы предложил вам найти всеобъемлющее руководство, которое вам нравится, и дать понять, что проект основан на этом.

Это не легко, особенно если вы новичок в этом! Ожидайте проводить часы, исследуя. Вы найдете большинство руководств, рекомендующих MVC-подобную структуру. Хотя несколько лет назад это могло быть солидным выбором, сегодня это не всегда так. Например здесь другой подход.

Ответ 6

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