Вот что я стараюсь помнить всякий раз, когда создаю одностраничное приложение Angular с поддержкой Express на сервере.

Если вам когда-либо нужно было очень быстро написать приложение для хакатона или, может быть, кодирование для поиска работы, и вы работаете с Angular, этот пост для вас. Я не буду описывать тонкости создания приложений Angular и Express. Это всего лишь контрольный список всех маленьких кусочков, которые нужно не забыть добавить. Если вы пропустите один из них, цитируя XKCD, вы сегодня не полетите в космос.

Что не включено:

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

  • Аутентификация. Не все приложения требуют аутентификации. А те, которые действительно предъявляют совершенно другие требования — некоторые требуют локальной аутентификации с использованием солевых паролей, некоторые требуют настройки OAuth у разных провайдеров (но какие именно? Google? Facebook? Twitter?), некоторые требуют настройки OAuth на собственном API и т. д. и т. д. и т. д. Таким образом, я не вдавался в аутентификацию ниже. Если вы хотите добавить аутентификацию в свое приложение, я рекомендую проверить Passport.
  • База данных: вам может показаться странным отсутствие базы данных! Но если вы создаете приложение для дома или хакатона, вам может не понадобиться такая внутренняя логика. Возможно, вам просто нужен фасадный интерфейс, который вы можете разработать. Кроме того, какую базу данных вы хотели бы использовать? SQL? МонгоДБ? Позже я могу написать несколько сообщений о полной настройке приложений стека MEAN и SEAN. Я не хотел копаться в этом посте, для краткости.

Что включено:

Итак, что я решил включить в этот контрольный список? Этот контрольный список предполагает, что вы пытаетесь:

  • создать одностраничное приложение Angular 1.x на интерфейсе
  • доставить одну страницу index.html с помощью приложения Express
  • предоставить API из приложения Express, который будет использоваться приложением Angular
  • доставлять статические файлы (CSS, JS и т. д.) из приложения Express

Структура каталогов

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

project 
| 
+-- main.js      (Express app) 
| 
+-- index.html   (HTML where your app will run) 
| 
+-- api          (API routes for sending data to Angular front-end) 
|   | 
|   +-- index.js 
| 
+-- public       (for static files, like JS and CSS) 
|   | 
|   +-- js 
|   |   | 
|   |   +-- script.js    (the Angular app) 
|   | 
|   +-- css 
|       | 
|       +-- style.css 
| 
+-- node_modules     (this one is created automatically below)

Зависимости: узел и NPM

Вам нужно будет установить Node и NPM, чтобы это приложение работало.

Чтобы установить зависимости, создайте package.json с помощью команды npm init в каталоге верхнего уровня вашего приложения.

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

npm install --save express body-parser angular angular-ui-router

Экспресс контрольный список

Время создать экспресс-приложение!

1. Установите Экспресс

Для начала убедитесь, что вы запустили npm install — сохраните экспресс (если вы не установили все зависимости заранее).

2. Создайте экспресс-приложение

В файле main.js создайте экземпляр экспресс-приложения со следующим кодом:

var express = require('express');
var app = express();

3. Добавьте разбор тела

Добавьте функциональность разбора тела. Это позволит вам анализировать JSON и формировать данные из вашего приложения.

Убедитесь, что вы установили пакет body-parser npm.

Затем добавьте промежуточное ПО для разбора тела в свое приложение, например:

var bodyParser = require('body-parser'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false}));

4. Добавьте маршрутизатор API

Далее вам нужно будет создать маршрутизатор API. Это перехватит любые запросы к /api и отправит их на отдельный маршрутизатор, который их обработает.

Чтобы добавить маршрутизатор в приложение Express, используйте следующие строки кода:

app.use('/api', require('./api'))

Затем создайте папку с именем api. В этой папке создайте файл index.js и добавьте следующее содержимое:

var express = require('express');
var router = express.Router(); 
// handle requests, or send them to another subrouter 
module.exports = router;

Этот файл index.js будет действовать как своего рода диспетчер для всех запросов API.

5. Добавьте статическую маршрутизацию файлов

Для этого приложения вам как минимум нужно будет обслуживать статические файлы для вашего приложения Angular. Вы также можете обслуживать файлы CSS, Bootstrap, Foundation или другие библиотеки JS и/или фреймворки. (Хотя на заметку, я рекомендую не использовать jQuery, если вы уже используете Angular — это слишком много JS для добавления в ваш интерфейс)

Чтобы обслуживать статические файлы из вашего каталога node_modules, куда был добавлен скрипт Angular, добавьте следующий код в ваш файл main.js:

app.use(express.static(__dirname + "/node_modules"));

Обязательно используйте __dirname для любых других статических каталогов, которые вы хотите обслуживать. Если вы хотите также обслуживать «общедоступный» каталог, добавьте эту строку в ваш файл main.js:

app.use(express.static(__dirname + "/public"));

6. Служите индексу для всех других запросов

Чтобы фактически обслуживать приложение, вам нужно будет отправить свой index.html на любые другие полученные запросы. Для этого добавьте следующий код в файл main.js:

app.get("*", function(req, res, next) { res.send(__dirname + `/index.html`); })

7. Добавьте обработку ошибок

Программное обеспечение промежуточного слоя для обработки ошибок: сделайте будущее счастливым.

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

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

app.use(function(req, res, next, err) { 
   res.status(err.status || 500)
   res.send(err.message || 'Internal Server Error');
});

7. Слушайте порт

Выберите порт (в примере я использовал 8000) и добавьте эту строку внизу вашего файла main.js:

app.listen(8000);

Если вы планируете развертывание в сервисе, таком как Heroku, вы также можете сделать следующее:

app.listen(ENV.port || 8000);

Угловой контрольный список

Ваше приложение Angular будет находиться в файле public/js/script.js.

1. Создайте экземпляр приложения Angular с помощью UI Router

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

var app = Angular.module('MyApp', ['ui.router']);

Не забудьте внедрить UI Router!

2. Настройте параметры приложения

Вам нужно будет настроить ваше приложение, чтобы:

  • Исправьте префиксы маршрута (чтобы избежать «#» в каждом URL-адресе)
  • Укажите маршрут, по которому приложение будет работать по умолчанию (в случае нераспознанного URL-адреса).

Все это произойдет в app.config(function() {}).

Для этого вам нужно внедрить locationProvider и urlRouterProvider.

Давай сделаем это:

app.config(function($locationProvider, $urlRouterProvider) {  
  $locationProvider.html5Mode(true);
  $urlRouterProvider.otherwise('/');
});

index.html Контрольный список

Чтобы ваше приложение Angular работало правильно, вам нужно запомнить несколько ключевых моментов, которые нужно добавить в файл index.html.

1. Создайте файл index.html

Я начну с простой корректной HTML-страницы без содержимого, например:

<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
  </head>
  <body>
  </body>
</html>

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

2. Загрузите в Angular

Не забудьте загрузить сам Angular! Достаточно легко забыть. Но мы настроили для него статический маршрут и все такое, так что давайте обязательно добавим его в ‹head›, вот так:

<script src="node_modules/angular/angular.min.js"></script>

ПРИМЕЧАНИЕ: точный маршрут внутри ваших node_modules МОЖЕТ измениться в более позднем выпуске Angular. Пожалуйста, проверьте еще раз, что это правильный путь.

3. Загрузите UI-маршрутизатор

Вам также нужно будет не забыть загрузить Angular UI Router в ‹head› вот так:

<script src="node_modules/angular-ui-router/release/angular-ui-router.min.js"></script>

ПРИМЕЧАНИЕ: точный маршрут внутри ваших node_modules МОЖЕТ измениться в более позднем выпуске Angular UI Router. Пожалуйста, проверьте еще раз, что это правильный путь.

4. Загрузите в свое приложение

Опять же, легко забыть, очень важно не забыть. То же, что и выше, добавьте к ‹head› в вашем индексе следующим образом:

<script src="js/script.js"></script>

5. Загрузите приложение Angular с помощью директивы ng-app

Не забудьте использовать ng-app для загрузки вашего приложения Angular. Он должен быть где-то в вашем HTML — в частности, в узле, который будет родительским для всех узлов, для которых вы хотите иметь функциональность Angular.

Не могу не подчеркнуть этот момент — если вы по какой-то причине забудете об этом, абсолютно никакой ваш код Angular вообще не будет работать.

Обычно я добавляю ng-app в ‹тело›, например так:

<body ng-app="MyApp"> </body>

Если вы создаете сложное приложение, для которого требуется несколько приложений Angular, вы можете в конечном итоге загрузить разные атрибуты ng-app в разных частях вашего HTML.

Вы также можете добавить директиву ng-app в элемент ‹html›.

6. Добавьте представление пользовательского интерфейса для Angular UI Router.

Вам нужно будет решить, какие аспекты вашей страницы изменятся, когда маршрутизатор Angular изменит состояние. Как правило, общие компоненты, такие как панель навигации, нижний колонтитул или, возможно, даже боковые панели, могут остаться прежними, а «контент» сайта изменится.

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

<ui-view></ui-view>

Или вы можете добавить его в качестве атрибута к элементу HTML по вашему выбору, например:

<div ui-view></div>

Это действительно зависит от вас и от структуры вашего приложения.

7. Добавьте базовый URL

Если вы хотите, чтобы маршрутизатор пользовательского интерфейса правильно работал в режиме HTML5, который мы добавили ранее в наши файлы Angular, нам нужно добавить элемент ‹base› внутри ‹head› нашего HTML и установить для него наш базовый маршрут («/» ).

<head>
  <base href="/">
</head>

Приложение: Собираем все вместе

Если вы хотите увидеть файлы в их полноте, они следующие:

main.js

Вот main.js, содержащий приложение Express:

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use('/api', require('./api'));
app.use(express.static(_dirname + "/node_modules"));
app.use(express.static(_dirname + "/public"));
app.get("*", function(req, res, next) {
  res.send(_dirname + "/index.html");
});
app.use(function(req, res, next, err) {
  res.status(err.status || 500)
  res.send(err.message || 'Internal Server Error');
});
app.listen(ENV.port || 8000);

API/index.js

Вот файл api/index.js:

var express = require('express');
var router = express.Router();
// handle API requests
module.exports = router;

index.html

Вот файл index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>
    <script src="node_modules/angular/angular.min.js"></script>
    <script src="node_modules/angular-ui-router/release/angular-ui-router.min.js"></script>
    <script src="js/script.js"></script>
    <link rel="stylesheet" href="css/style.css">
    <base href="/">
  </head>
  <body ng-app="MyApp">
    <ui-view></ui-view>
  </body>
</html>

общедоступный/js/script.js

Код Angular в файле script.js будет выглядеть так:

var app = Angular.module('MyApp', ['ui-router']); 
app.config(function($locationProvider, $urlRouterProvider) { 
  $locationProvider.html5Mode(true); 
  $urlRouterProvider.otherwise('/');
});

Вопросы? Комментарии? Исправления? Пожалуйста, не стесняйтесь связаться со мной и дайте мне знать! "Напишите мне!"

Первоначально опубликовано на paloobi.tumblr.com.