Статьи

Создайте полный сайт MVC с ExpressJS

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


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

Я предполагаю, что вы знакомы с Nodejs, он установлен в вашей системе, и что вы, вероятно, уже создали некоторые приложения с ним.

В основе Express лежит Connect . Это промежуточная платформа, которая поставляется с множеством полезных вещей. Если вам интересно, что же такое промежуточное программное обеспечение, вот небольшой пример:

Промежуточное программное обеспечение — это в основном функция, которая принимает объекты request и response и next функцию. Каждое промежуточное ПО может решить ответить с помощью объекта response или передать поток следующей функции, вызвав next обратный вызов. В приведенном выше примере, если вы удалите вызов метода next() во втором промежуточном программном обеспечении, строка hello world никогда не будет отправлена ​​в браузер. В общем, так работает Экспресс. Есть несколько предопределенных промежуточных программ, которые, конечно, сэкономят вам много времени. Как, например, Body parser который анализирует тела запросов и поддерживает application / json, application / x-www-form-urlencoded и multipart / form-data. Или Cookie parser , который анализирует заголовки cookie и заполняет req.cookies объектом, ключом которого является имя cookie.

Express на самом деле оборачивает Connect и добавляет некоторые новые функциональные возможности. Как, например, логика маршрутизации, которая делает процесс намного более плавным. Вот пример обработки запроса GET:


Есть два способа настроить Express. Во-первых, поместив его в файл package.json и запустив npm install (есть шутка, что npm означает, что нет проблем, человек :)).

Код фреймворка будет помещен в node_modules и вы сможете создать его экземпляр. Однако я предпочитаю альтернативный вариант, используя инструмент командной строки. Просто установите Express глобально с помощью npm install -g express . Благодаря этому у вас теперь есть новый инструмент CLI. Например, если вы запустите:

1
express —sessions —css less —hogan app

Express создаст скелет приложения с несколькими настройками, уже настроенными для вас. Вот варианты использования для команды express(1) :

01
02
03
04
05
06
07
08
09
10
Usage: express [options]
Options:
  -h, —help output usage information
  -V, —version output the version number
  -s, —sessions add session support
  -e, —ejs add ejs engine support (defaults to jade)
  -J, —jshtml add jshtml engine support (defaults to jade)
  -H, —hogan add hogan.js engine support
  -c, —css add stylesheet support (less|stylus) (defaults to plain css)
  -f, —force force on non-empty directory

Как видите, вариантов всего несколько, но для меня их достаточно. Обычно я использую меньше как препроцессор CSS и hogan как движок шаблонов. В этом примере нам также потребуется поддержка сеанса, поэтому аргумент --sessions решает эту проблему. Когда приведенная выше команда завершается, наш проект выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
/public
    /images
    /javascripts
    /stylesheets
/routes
    /index.js
    /user.js
/views
    /index.hjs
/app.js
/package.json

Если вы посмотрите файл package.json , вы увидите, что все необходимые нам зависимости добавлены сюда. Хотя они еще не были установлены. Для этого просто запустите npm install после чего node_modules папка node_modules .

Я понимаю, что вышеуказанный подход не всегда уместен. Возможно, вы захотите поместить ваши обработчики маршрутов в другой каталог или что-то подобное. Но, как вы увидите в следующих нескольких главах, я внесу изменения в уже сгенерированную структуру, что довольно легко сделать. Так что вы должны просто думать о команде express(1) как о шаблонном генераторе.


Для этого урока я разработал простой сайт фальшивой компании FastDelivery. Вот скриншот полного дизайна:

сайт

В конце этого урока у нас будет полное веб-приложение с работающей панелью управления. Идея состоит в том, чтобы управлять каждой частью сайта в отдельных зонах ограниченного доступа. Макет был создан в Photoshop и нарезан на CSS (меньше) и HTML (хоган) файлы. Теперь я не собираюсь рассказывать о процессе нарезки, потому что это не тема этой статьи, но если у вас есть какие-либо вопросы по этому поводу, не стесняйтесь спрашивать. После нарезки у нас есть следующие файлы и структура приложения:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
/public
    /images (there are several images exported from Photoshop)
    /javascripts
    /stylesheets
        /home.less
        /inner.less
        /style.css
        /style.less (imports home.less and inner.less)
/routes
    /index.js
/views
    /index.hjs (home page)
    /inner.hjs (template for every other page of the site)
/app.js
/package.json

Вот список элементов сайта, которые мы собираемся администрировать:

  • Домой (баннер посередине — заголовок и текст)
  • Блог (добавление, удаление и редактирование статей)
  • Страница услуг
  • Страница карьеры
  • Страница контактов

Есть несколько вещей, которые мы должны сделать, прежде чем мы сможем начать реальную реализацию. Настройка конфигурации является одним из них. Давайте представим, что наш маленький сайт должен быть развернут в трех разных местах — локальный сервер, промежуточный сервер и рабочий сервер. Конечно, настройки для каждой среды разные, и мы должны реализовать достаточно гибкий механизм. Как вы знаете, каждый скрипт узла запускается как консольная программа. Таким образом, мы можем легко отправить аргументы командной строки, которые будут определять текущую среду. Я завернул эту часть в отдельный модуль, чтобы позже написать тест для него. Вот файл /config/index.js :

Есть только две настройки (на данный момент) — mode и port . Как вы можете догадаться, приложение использует разные порты для разных серверов. Вот почему мы должны обновить точку входа сайта, в app.js

Для переключения между конфигурациями просто добавьте среду в конце. Например:

1
node app.js staging

Будет производить:

1
Express server listening on port 4000

Теперь у нас есть все наши настройки в одном месте, и ими легко управлять.


Я большой поклонник TDD . Я постараюсь охватить все базовые классы, используемые в этой статье. Конечно, наличие тестов для абсолютно всего сделает эту запись слишком долгой, но в целом именно так вы должны действовать при создании своих собственных приложений. Одна из моих любимых платформ для тестирования — это жасмин . Конечно, это доступно в реестре npm:

1
npm install -g jasmine-node

Давайте создадим каталог tests который будет содержать наши тесты. Первое, что мы собираемся проверить, это наша настройка конфигурации. Файлы спецификаций должны заканчиваться на .spec.js , поэтому файл должен называться config.spec.js .

Запустите jasmine-node ./tests и вы должны увидеть следующее:

1
2
Finished in 0.008 seconds
3 tests, 6 assertions, 0 failures, 0 skipped

На этот раз я написал сначала реализацию, а затем тест. Это не совсем способ TDD, но в следующих нескольких главах я сделаю обратное.

Я настоятельно рекомендую тратить много времени на написание тестов. Нет ничего лучше, чем полностью протестированное приложение.

Пару лет назад я осознал кое-что очень важное, что может помочь вам создавать лучшие программы. Каждый раз, когда вы начинаете писать новый класс, новый модуль или просто новую логику, спросите себя:

Как я могу проверить это?

Ответ на этот вопрос поможет вам гораздо эффективнее кодировать, создавать лучшие API и размещать все в красиво разделенных блоках. Вы не можете писать тесты для кода спагетти. Например, в файле конфигурации выше ( /config/index.js ) я добавил возможность отправки mode в конструктор модуля. Вы можете спросить, почему я делаю это, когда основная идея — получить режим из аргументов командной строки? Это просто … потому что мне нужно было это проверить. Давайте представим, что через месяц мне нужно что-то проверить в production конфигурации, но скрипт узла запускается с staging параметром. Я не смогу сделать это изменение без этого небольшого улучшения. Этот предыдущий маленький шаг сейчас фактически предотвращает проблемы в будущем.


Поскольку мы создаем динамический веб-сайт, нам нужна база данных для хранения наших данных. Я решил использовать mongodb для этого урока. Mongo — это база данных документов NoSQL. Инструкции по установке можно найти здесь, и, поскольку я пользователь Windows, я следовал за установкой Windows . Как только вы закончите установку, запустите демон MongoDB, который по умолчанию прослушивает порт 27017. Таким образом, теоретически мы должны иметь возможность подключиться к этому порту и установить связь с сервером mongodb. Чтобы сделать это из скрипта узла, нам нужен модуль / драйвер mongodb . Если вы загрузили исходные файлы для этого урока, модуль уже добавлен в файл package.json . Если нет, просто добавьте "mongodb": "1.3.10" в ваши зависимости и запустите npm install .

Далее мы собираемся написать тест, который проверяет, работает ли сервер mongodb. Файл /tests/mongodb.spec.js :

Обратный вызов в методе .connect клиента mongodb получает объект db . Мы будем использовать его позже для управления нашими данными, а это значит, что нам нужен доступ к ним внутри наших моделей. Не стоит создавать новый объект MongoClient каждый раз, когда нам нужно сделать запрос к базе данных. Вот почему я перенес работу экспресс-сервера в функцию обратного вызова функции connect :

Более того, поскольку у нас есть настройка конфигурации, было бы неплохо разместить там хост и порт mongodb, а затем изменить URL-адрес подключения на:

Обратите особое внимание на промежуточное ПО: attachDB , которое я добавил непосредственно перед вызовом функции http.createServer . Благодаря этому небольшому дополнению мы .db свойство .db объекта запроса. Хорошей новостью является то, что мы можем добавить несколько функций во время определения маршрута. Например:

Итак, с этим Express заранее вызывает attachDB чтобы добраться до нашего обработчика маршрута. Как только это произойдет, объект запроса будет иметь свойство .db и мы сможем использовать его для доступа к базе данных.


Мы все знаем схему MVC . Вопрос в том, как это относится к Express. Более или менее, это вопрос интерпретации. В следующих нескольких главах я создам модули, которые выступают в качестве модели, вида и контроллера.

Модель — это то, что будет обрабатывать данные, которые находятся в нашем приложении. Он должен иметь доступ к объекту db , возвращенному MongoClient . В нашей модели также должен быть метод ее расширения, потому что мы можем захотеть создавать модели различных типов. Например, мы могли бы хотеть BlogModel или ContactsModel . Поэтому нам нужно написать новую спецификацию: /tests/base.model.spec.js , чтобы протестировать эти две функциональные возможности. И помните, определяя эти функциональные возможности до того, как мы начнем кодировать реализацию, мы можем гарантировать, что наш модуль будет делать только то, что мы хотим, чтобы он делал.

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

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

Здесь есть два вспомогательных метода. Установщик для объекта db и получатель для нашей collection баз данных.

Представление будет отображать информацию на экране. По сути, представление — это класс, который отправляет ответ браузеру. Express предоставляет короткий способ сделать это:

Объект ответа — это оболочка, которая имеет приятный API, облегчающий нашу жизнь. Тем не менее, я бы предпочел создать модуль, который будет инкапсулировать эту функциональность. Каталог views умолчанию будет изменен на templates и будет создан новый каталог, в котором будет размещен класс Base представления. Это небольшое изменение теперь требует другого изменения. Мы должны уведомить Express, что наши файлы шаблонов теперь находятся в другом каталоге:

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

  • Его конструктор должен получить объект ответа и имя шаблона.
  • Он должен иметь метод render который принимает объект данных.
  • Это должно быть расширяемым.

Вы можете удивиться, почему я расширяю класс View . Разве это не просто вызов метода response.render ? На практике есть случаи, когда вы захотите отправить другой заголовок или, возможно, каким-либо образом манипулировать объектом response . Как, например, обслуживание данных JSON:

Вместо того, чтобы делать это каждый раз, было бы неплохо иметь класс JSONView класс JSONView . Или даже класс XMLView для отправки данных XML в браузер. Просто лучше, если вы создаете большой веб-сайт, чтобы обернуть эти функции, а не копировать один и тот же код снова и снова.

Вот спецификация для /views/Base.js :

Чтобы проверить рендеринг, мне нужно было создать макет. В этом случае я создал объект, который имитирует объект ответа Express. Во второй части теста я создал другой класс View, который наследует базовый класс и применяет пользовательский метод рендеринга. Вот класс /views/Base.js .

Теперь у нас есть три спецификации в нашем каталоге tests и если вы запустите jasmine-node ./tests результат должен быть:

1
2
Finished in 0.009 seconds
7 tests, 18 assertions, 0 failures, 0 skipped

Помните маршруты и как они были определены?

Знак '/' после маршрута, который в приведенном выше примере на самом деле является контроллером. Это просто функция промежуточного программного обеспечения, которая принимает request , response и next .

Выше, как должен выглядеть ваш контроллер в контексте Express. express(1) командной строки express(1) создает каталог с именем routes , но в нашем случае лучше называть его controllers , поэтому я изменил его, чтобы отразить эту схему именования.

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

  • он должен иметь метод extend , который принимает объект и возвращает новый дочерний экземпляр
  • дочерний экземпляр должен иметь метод run , который является старой функцией промежуточного программного обеспечения
  • должно быть свойство name , которое идентифицирует контроллер
  • мы должны иметь возможность создавать независимые объекты, основанные на классе

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

А вот и реализация /controllers/Base.js :

Конечно, каждый дочерний класс должен определять свой собственный метод run вместе со своей собственной логикой.


Хорошо, у нас есть хороший набор классов для нашей архитектуры MVC, и мы покрыли наши недавно созданные модули тестами. Теперь мы готовы продолжить работу с сайтом нашей фальшивой компании FastDelivery . Давайте представим, что сайт состоит из двух частей — интерфейсной панели и панели администрирования. Внешний интерфейс будет использоваться для отображения информации, записанной в базе данных, нашим конечным пользователям. Панель администратора будет использоваться для управления этими данными. Давайте начнем с нашей панели администратора (управления).

Давайте сначала создадим простой контроллер, который будет служить страницей администрирования. Файл /controllers/Admin.js :

Используя предварительно написанные базовые классы для наших контроллеров и представлений, мы можем легко создать точку входа для панели управления. Класс View принимает имя файла шаблона. Согласно приведенному выше коду файл должен называться admin.hjs и должен быть помещен в /templates . Содержание будет выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
<!DOCTYPE html>
<html>
    <head>
        <title>{{ title }}</title>
        <link rel=’stylesheet’ href=’/stylesheets/style.css’ />
    </head>
    <body>
        <div class=»container»>
            <h1>{{ content }}</h1>
        </div>
    </body>
</html>

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

Теперь, чтобы сделать контроллер видимым, мы должны добавить маршрут к нему в app.js :

Обратите внимание, что мы не отправляем метод Admin.run напрямую как промежуточное ПО. Это потому, что мы хотим сохранить контекст. Если мы сделаем это:

слово this в Admin будет указывать на что-то еще.

Каждая страница, которая начинается с /admin должна быть защищена. Для этого мы будем использовать промежуточное программное обеспечение Express: Sessions . Он просто присоединяет объект к запросу, называемому session . Теперь мы должны изменить наш контроллер администратора, чтобы сделать две дополнительные вещи:

  • Следует проверить, есть ли доступный сеанс. Если нет, то отобразите форму входа.
  • Он должен принять данные, отправленные формой входа в систему и авторизовать пользователя, если имя пользователя и пароль совпадают.

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

Во-первых, у нас есть оператор, который пытается распознать пользователя через объект сеанса. Во-вторых, мы проверяем, была ли отправлена ​​форма. Если это так, данные из формы доступны в объекте request.body который заполняется промежуточным программным обеспечением bodyParser . Затем мы просто проверяем, совпадают ли имя пользователя и пароль.

А теперь вот метод run контроллера, который использует наш новый помощник. Мы проверяем, авторизован ли пользователь, отображая либо саму панель управления, либо мы отображаем страницу входа:

Как я указывал в начале этой статьи, у нас есть много вещей для администрирования. Чтобы упростить процесс, давайте хранить все данные в одной коллекции. Каждая запись будет иметь title , text , picture и type свойства. Свойство type будет определять владельца записи. Например, странице «Контакты» потребуется только одна запись с type: 'contacts' , а странице блога потребуется больше записей. Итак, нам нужны три новые страницы для добавления, редактирования и отображения записей. Прежде чем мы перейдем к созданию новых шаблонов, стилей и добавлению новых элементов в контроллер, мы должны написать наш класс модели, который находится между сервером MongoDB и нашим приложением и, конечно, предоставляет значимый API.

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

Если мы хотим добавить новую запись для нашей страницы контактов, мы можем просто использовать:

Итак, у нас есть хороший API для управления данными в нашей коллекции mongodb. Теперь мы готовы написать пользовательский интерфейс для использования этой функциональности. Для этой части контроллер Admin нужно будет немного изменить. Чтобы упростить задачу, я решил объединить список добавленных записей и форму для их добавления / редактирования. Как вы можете видеть на скриншоте ниже, левая часть страницы зарезервирована для списка, а правая часть для формы.

панель управления

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

Это выглядит немного некрасиво, но работает так, как я хотел. Первый помощник — это метод del который проверяет текущие параметры GET и, если он находит action=delete&id=[id of the record] , он удаляет данные из коллекции. Вторая функция называется form и отвечает главным образом за отображение формы в правой части страницы. Он проверяет, отправлена ​​ли форма и правильно ли обновляет или создает записи в базе данных. В конце метод list извлекает информацию и подготавливает таблицу HTML, которая затем отправляется в шаблон. Реализация этих трех помощников можно найти в исходном коде этого руководства.

Здесь я решил показать вам функцию, которая обрабатывает загрузку файла:

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

1
<input type=»file» name=»picture» />

Это означает, что мы можем получить доступ к отправленным данным через req.files.picture . В приведенном выше фрагменте кода req.files.picture.path используется для получения необработанного содержимого файла. Позже те же данные записываются во вновь созданный каталог, и в конце возвращается правильный URL. Все эти операции являются синхронными, но рекомендуется использовать асинхронную версию readFileSync , mkdirSync и writeFileSync .

Тяжелая работа теперь завершена. Панель администрирования работает, и у нас есть класс ContentModel , который дает нам доступ к информации, хранящейся в базе данных. Теперь нам нужно написать внешние контроллеры и связать их с сохраненным содержимым.

Вот контроллер для домашней страницы — /controllers/Home.js

Домашней странице нужна одна запись с типом домашней страницы и четыре записи с типом blog . После завершения работы контроллера нам просто нужно добавить маршрут к нему в app.js :

Опять же, мы присоединяем объект db к request . Практически тот же рабочий процесс, что и в панели администрирования.

Другие страницы для нашего интерфейса (на стороне клиента) практически идентичны, так как все они имеют контроллер, который извлекает данные с использованием класса модели и, конечно, определенного маршрута. Есть две интересные ситуации, которые я хотел бы объяснить более подробно. Первый связан со страницей блога. Нужно уметь показывать все статьи, а также представлять только одну. Итак, нам нужно зарегистрировать два маршрута:

Они оба используют один и тот же контроллер: Blog , но вызывают разные методы run . Обратите внимание на строку /blog/:id . Этот маршрут будет соответствовать URL-адресам, таким как /blog/4e3455635b4a6f6dccfaa1e50ee71f1cde75222b и длинный хеш будет доступен в req.params.id . Другими словами, мы можем определить динамические параметры. В нашем случае это идентификатор записи. Получив эту информацию, мы можем создать уникальную страницу для каждой статьи.

Вторая интересная часть — это то, как я создал страницы «Услуги», «Карьера» и «Контакты». Понятно, что они используют только одну запись из базы данных. Если бы нам пришлось создавать разные контроллеры для каждой страницы, нам пришлось бы копировать / вставлять один и тот же код и просто менять поле type . Есть лучший способ добиться этого, имея только один контроллер, который принимает type в своем методе run . Итак, вот маршруты:

И контроллер будет выглядеть так:


Развертывание веб-сайта на основе Express на самом деле аналогично развертыванию любого другого приложения Node.js:

  • Файлы размещены на сервере.
  • Процесс узла должен быть остановлен (если он запущен).
  • Команда npm install должна быть запущена для установки новых зависимостей (если есть).
  • Основной сценарий должен быть запущен снова.

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

1
forever start yourapp.js

Это то, что я использую на своих серверах. Это хороший маленький инструмент, но он решает большую проблему. Если вы запускаете свое приложение только с помощью node yourapp.js , то, как только ваш скрипт неожиданно завершает работу, сервер node yourapp.js . forever , просто перезапускает приложение.

Сейчас я не системный администратор, но я хотел поделиться своим опытом интеграции приложений для узлов с Apache или Nginx , потому что я думаю, что это как-то является частью рабочего процесса разработки.

Как вы знаете, Apache обычно работает на порту 80, что означает, что если вы откроете http://localhostили http://localhost:80увидите страницу, обслуживаемую вашим сервером Apache, и, скорее всего, ваш скрипт узла прослушивает другой порт. Итак, вам нужно добавить виртуальный хост, который принимает запросы и отправляет их на нужный порт. Например, предположим, что я хочу разместить сайт, который мы только что создали, на моем локальном сервере Apache под expresscompletewebsite.devадресом. Первое, что нам нужно сделать, это добавить наш домен в hostsфайл.

1
127.0.0.1 expresscompletewebsite.dev

После этого мы должны отредактировать httpd-vhosts.confфайл в каталоге конфигурации Apache и добавить

01
02
03
04
05
06
07
08
09
10
11
12
13
14
# expresscompletewebsite.dev
<VirtualHost *:80>
    ServerName expresscompletewebsite.dev
    ServerAlias www.expresscompletewebsite.dev
    ProxyRequests off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    <Location />
        ProxyPass http://localhost:3000/
        ProxyPassReverse http://localhost:3000/
    </Location>
</VirtualHost>

Сервер по-прежнему принимает запросы на порт 80, но перенаправляет их на порт 3000, где узел прослушивает.

Настройка Nginx намного проще и, честно говоря, это лучший выбор для размещения приложений на базе Nodejs. Вам все еще нужно добавить доменное имя в ваш hostsфайл. После этого просто создайте новый файл в /sites-enabledкаталоге под установкой Nginx. Содержимое файла будет выглядеть примерно так:

1
2
3
4
5
6
7
8
server {
    listen 80;
    server_name expresscompletewebsite.dev
    location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_set_header Host $http_host;
    }
}

Имейте в виду, что вы не можете запустить Apache и Nginx с указанными выше настройками хостов. Это связано с тем, что им обоим требуется порт 80. Кроме того, вы можете провести небольшое дополнительное исследование о лучшей конфигурации сервера, если планируете использовать приведенные выше фрагменты кода в производственной среде. Как я уже сказал, я не эксперт в этой области.


Express — это отличный фреймворк, который дает вам хорошую отправную точку для начала разработки ваших приложений. Как видите, вопрос о том, как вы будете расширять его, и что вы будете использовать для его создания, зависит от выбора. Он упрощает скучные задачи благодаря использованию нескольких замечательных промежуточных программ и оставляет разработчикам забавные детали.

Если вы хотите ускорить свою работу по разработке, вы можете найти множество полезных скриптов и приложений для JavaScript на Envato Market.

Сценарии и приложения для JavaScript на Envato Market
Сценарии и приложения для JavaScript на Envato Market

Исходный код этого примера сайта, который мы создали, доступен на GitHub — https://github.com/tutsplus/build-complete-website-expressjs . Не стесняйтесь раскошелиться и играть с ним. Вот шаги для запуска сайта.

  • Скачать исходный код
  • Перейти в appкаталог
  • Бегать npm install
  • Запустить демон mongodb
  • Бегать node app.js