Подтвердить что ты не робот

Хотите получить представление о структуре приложения NodeJS (полный стек JavaScript)

Я хотел бы знать структуру типичного приложения NodeJS, потому что чем больше я читаю и вижу проекты, тем больше я запутался, особенно в отношении таких вопросов (или даже больше после того, как я обновил этот вопрос):

  1. Возьмем, к примеру, стек MEAN, из того, что я знаю, NodeJS и Express заботятся о серверной части, обеспечивают интерфейс сервера и т.д. MongoDB и Angular довольно просты.

    Но куда должна идти бизнес-логика? Скажем, если у меня есть controller.js который содержит функцию, а файл route.js связывает запрос с этой функцией контроллера. Мой вопрос: под каким модулем эти файлы принадлежат/работают под (Express или NodeJS?)

  2. Где находится отправная точка приложения NodeJS? Скажем, index.php является отправной точкой приложения PHP, но где он находится для приложения NodeJS? Я вижу, что все проекты Nodejs имеют файл server.js или app.js и т.д. (Содержащий что-то вроде module.exports = app;). Но как NodeJS может узнать, какой файл найти и выполнить?

Я новичок в NodeJS, Express, sequelize.js/Mongoose, Jade/EJS, но хочу начать работу над проектом NodeJS. Не могли бы вы рассказать о фактической функции, которую предоставляют каждый модуль, и общее представление о типичной структуре для полного приложения Jde с накоплением JS? Заранее спасибо!

4b9b3361

Ответ 1

Хорошо, это довольно широкий вопрос, и я определенно не эксперт, но я сделаю все возможное здесь.

TL; DR

  • routes - это контроллеры, которые сообщают, какую логику следует выполнять, когда пользователь переводит свой браузер на определенный путь в вашем приложении, включая какие виды визуализации и какие данные отправлять в эти представления.
  • models - это только то, что - модели данных в вашем приложении
  • module.exports = сообщает файлу, что именно он "экспортирует", то есть какой код необходимо выполнить или получить из основного файла приложения.
  • require(..) содержит модуль. Вы можете установить это на переменной, чтобы позже вы могли вызывать функции модуля или просто выполнять функцию, если это все, что возвращает module.exports.

Объединение этих методов поможет вам прикрепить прочную структуру для любого из ваших приложений.


Длинный ответ

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

Контроллеры

Сгенерированный проект создаст /routes/index.js, который (если вы понимаете MVC), по сути, является вашим основным контроллером. Маршрут в экспресс написан так:

app.get('/path', function(req, res, next){ .. } );

Позволяет прервать это: нашей прикладной переменной (app) сообщается, что в запросе GET на '/path' выполняется анонимная функция обратного вызова с переменными req, res, next (запрос, ответ, обратный вызов соответственно). Я считаю полезным думать об этом как о специальном обработчике событий.

Важно отметить, что в этот момент мы могли бы также вызвать app.post с тем же синтаксисом для сообщений в URL-адресе, а не в получении.

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

app.get('/', function(req, res, next){

    //some business logic

    res.render('views/home');
});

Когда пользователь пытается получить индексный путь нашего приложения (/), мы просто визуализируем наш home вид, который из корня нашего проекта хранится в папке views.

Но что, если мы хотим модулизировать это, чтобы мы не объявляли все наши маршруты в наших основных app.js или server.js?

Мы используем module.exports = .. в наших модулях, чтобы сообщить нашему серверу, что именно включить. В моем контроллере я экспортирую одну функцию, которая принимает приложение в качестве аргумента и использует это для определения наших маршрутов следующим образом:

Контроллеры/user.js

 module.exports = function(app){

    app.get('/users', function(req, res){
        var users = req.db.collection('users').find();
        if (!users) {
            console.log("no users found");
            res.redirect('/');
        } else {
            res.render('users/index', {users : users});
        }
    });

};

Не беспокойтесь о коде req.db, я привязываю базу данных к запросу в своем приложении, но это не делается по умолчанию. Просто поймите, что я получаю список "пользователей" здесь и перенаправляю пользователя в индекс моего приложения, если его нет.

Модели

Mongoose предоставляет нам отличный интерфейс для написания моделей. С помощью мангуста письменные модели представляют собой трехэтапный процесс:

  • Определить схему
  • Определение логики модели
  • Сгенерировать и экспортировать модель

Вот пример модели User:

Модели /user.js

var mongoose = require('mongoose'),
    userSchema = new mongoose.Schema({

        name: { type: String, required: true },
        joinDate: {type: Date, default: date.now }

    }),
    User = mongoose.model('user', userSchema);

module.exports = user;

Серверное приложение

module.exports используется, чтобы помочь нам определить некоторую модульность нашей кодовой базы. Когда мы запускаем приложение Node, мы в конечном счете запускаем один файл JavaScript (вы уже видели этот файл с server.js или app.js).

Чтобы этот файл не был слишком большим с несколькими моделями и маршрутами, мы используем require(module) для включения кода из других JS файлов. module в нашем случае будет путь к модулю, который мы хотим потребовать. Если у вас есть следующая структура документа:

| Controllers
    - User.js
| Models
    - User.js
| Views
app.js

Чтобы включить ваш пользовательский контроллер из app.js, вы должны написать: require('./Controllers/User'). Поскольку наши модули контроллера просто экспортируют функции, мы можем вызвать эту функцию сразу после инструкции require, просто добавив круглые скобки в конце (с любыми параметрами). Включение моих контроллеров выглядит так:

require('./Controllers/User')(app)

Я передаю фактическое приложение, потому что мой модуль (ниже) просто экспортирует функцию, которая добавляет бизнес-логику к моим маршрутам приложений. Это нужно только вызывать и никогда не использовать, поэтому я не фиксирую свой контроллер как переменную для вызова методов позже.

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

var User = require('./Models/User');

Теперь мы можем каждый раз называть методы нашей модели User. Mongoose дает нам множество базовых функций бесплатно:

User.find({}, function(err, users){ .. });

Вышеупомянутая функция позволит найти всех наших пользователей, а затем выполнить анонимную функцию с потенциальным err (это null, если нет проблем), а затем список наших пользователей в формате JSON. Довольно изящный.

Сочетание всех этих концепций заключается в том, как вы создаете базовое веб-приложение с помощью Express и Node.js. Пожалуйста, дайте мне знать в комментариях, если я могу пояснить, как я использую Express. Это знание на уровне поверхности, и я предлагаю вникать в документацию и смотреть плагины, чтобы расширить возможности ваших приложений. Удачи!