Построение SPA приложений на Angular 4 / Nodejs

4.933 (3)

 

В данной статье будут разобраны все основные инструменты и ключевые моменты при построениии Single Page Application на стэке технологий MEAN (MongoDB, Express, Angular, Nodejs).

Все примеры будут приведены на основе нашего корпоративного приложения.

1. Конфигурирование приложения.

Основные настройки.

- /package.json


{
  "name": "mean_prototype",
  "scripts": {
    "compile-angular": "ng build -prod --no-sourcemap && mv ./dist/client/index-prod.html ./dist/client/index.html",
    "compile-client": "npm run compile-angular",
    "compile-server-packages": "cp ./package.json ./dist/server/package.json && npm i --production --prefix ./dist/server && rm ./dist/server/package.json",
    "compile-server": "cd ./src/server && tsc && cd ../../ && npm run compile-server-packages",
    "compile-full": "npm i && npm run compile-server && npm run compile-client",
    "compile-angular-dev": "cd src && tsc",
    "cad": "npm run compile-angular-dev",
    "start": "tsc && node ./dist/server/index.js",
    "serve": "lite-server -c=bs-config.json",
...
  },
  "dependencies": {
    "body-parser": "^1.17.1",
    "cookie-parser": "^1.4.3",
    "crypto": "0.0.3",
    "errorhandler": "^1.5.0",
    "express": "^4.15.3",
...
  },
  "devDependencies": {
    "@angular/animations": "^4.1.3",
    "@angular/cdk": "^2.0.0-beta.8",
    "@angular/cli": "^1.0.4",
    "@angular/common": "^4.1.3",
    "@angular/compiler": "^4.1.3",
    "@angular/compiler-cli": "^4.1.3",
    "@angular/core": "^4.1.3",
...

 

Основной файл конфигурации приложения. 
В нем описано само приложение: его название, версия, краткое описание, тип лицензии и прочее.

Также в нем настраиваются скрипты, которые будут выполнятся из корня приложения, с помощью команд npm и npm run, например - npm run compile-angular.

В данном конфигурационном файле настраиваются все зависимости приложения - node модули, которые необходимы приложению для работы, все они будут установлены командой npm install.
Зависимости разделены на два (в нашем случае, на самом деле их больше) типа: 
dependencies и devDependencies.

dependencies - обычно в эту группу входят все production зависимости (те, которые используются непосредственно на проекте в рабочей среде).
В нашем конкретном случае, в эту группу были помещены только production зависимости серверной части Nodejs. Это сделано потому, что vendor код серверной части (node модули) очень сложно оптимизировать (что в нашем случае очень важно), как это делается с клиентской частью (это будет описано ниже). Поэтому мы четко разграничиваем модули, необходимые для работы production сервера, и все остальные.

devDependencies - обычно в данную группу входят все те модули, что необходимы при разработке, но не в production версии. В нашем случае, в данную группу помещены все модули, кроме тех, что необходимы для production серверной части.
Наше приложение использует для сборки клиентской части проекта инструмент angular-cli, который компилирует сам исходный код клиентской части, а также все то, что было использовано в исходном коде проекта из node_modules, и ничего лишнего. Это позволяет нам не тратить время на разделение модулей на production и dev в обычном их понимании.

 

Дополнительные настройки.

При разработке приложений на MEAN стэке технологий, часто используются такие инструменты и технологии, как typescript, angular-cli, gulp, и некоторые другие. Все эти инструменты помогают разрабатывать приложение быстро и эффективно. Далее будет описан каждый из них.

TypeScript (далее TS)- это язык программирования, который является надстройкой над языком JavaScript (далее JS). Это компилируемый язык, он не используется в чистом виде, а только для компиляции в JS код, который уже используется в браузере или на Nodejs сервере. Он обратно совместим с JavaScript, это значит, что чистый JS код будет также распознаваться компилятором, как валидный TS код.
TS идеально дополняет JS. Он добавляет классы, наследование, строгую типизацию, в классическом их виде:


import * as cookieParser from 'cookie-parser';
import {Acl} from './models/Acl';
import {TestSocket} from './sockets/TestSocket';

/**
 * Корневой класс сервера, который инициализирует приложение
 *
 * @class Server
 */
export class Server {

    public app: express.Application;

    /**
     * Bootstrap the application.
     *
     * @class Server
     * @method bootstrap
     * @static
     * @return Server Returns the newly created injector for this app.
     */
    public static bootstrap(): Server {
        return new Server();
    }

    /**
     * Constructor.
     *
     * @class Server
     * @constructor
     */
    constructor() {
        // initialization of the app
        this.init();
...

 

Компиляция исходного TS кода в JS происходит следующим образом.

 

Клиентская часть

Angular-cli
/.angular-cli.json


{
  "project": {
    "name": "mean_prototype"
  },
  "apps": [
    {
      "root": "src/client",
      "outDir": "dist/client",
      "assets": [
        "favicon.ico"
      ],
      "index": "index-prod.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
...

 

Angular-cli - это node модуль, который выполняет функции создания различных элементов angular таких как компоненты, директивы, модули и сервисы, с помощью простых команд в терминале. А также позволяет выполнять сборку angular приложения Ahead-of-time, собранный таким образом проект занимает гораздо меньше места, быстрее рендерится браузером, и лучше оптимизирован, по сравнению со стандартной angular сборкой Just-in-time.

Конфигурационный файл модуля angular-cli, с помощью которого мы производим быстрое создание элементов angular приложения, например мы можем создать компонент TestComponent.ts с базовыми настройками, файлами шаблона, стилей и spec файл с базовой конфигурацией для юнит тестов на jasmine, командой ng generate component test.

В данном файле следует обратить особое внимание на параметры root - директория исходного кода, outDir - директория, в которую сохраняется собранное в production приложение, tsconfig - файл конфигурации компилятора TS

/src/client/tsconfig.json


{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [ "es2015", "dom" ],
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  }
}

Файл конфигурации компилятора TS.
Генерируется при создании нового проекта с помощью angular-cli, и остается практически нетронутым. Особое значение тут имеет параметр target, это версия EcmaScript (ядро JS) используемая интерпретатором компилятора.

После такой настройки клиентской части, для сборки нам остается выполнить в терминале, от корня приложения 
ng build -prod --no-sourcemap 
или, если angular-cli не установлен глобально, то 
./node_modules/@angular/cli/bin/ng build -prod --no-sourcemap
Будет проведена сборка production версии клиентской части, и помещена в /dist/client

Поскольку данный вид компиляции хоть и оптимизирует приложение, но является весьма не быстрым, поэтому в разработке используется dev сборка, подробнее в разделе о gulp.

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

/gulpfile.ts


...
/**
 * Compile TypeScript sources and create sourcemaps in build directory.
 */
gulp.task('compile_client', [], () => {
    const tsResult = gulp.src('src/client/**/*.ts')
        .pipe(sourcemaps.init())
        .pipe(tsProjectClient());
    return tsResult.js
        .pipe(sourcemaps.write('.', {sourceRoot: '/src/client'}))
        .pipe(gulp.dest('dev-dist/client'))
        .pipe(livereload());
});

gulp.task('compile_server', [], () => {
    const tsResult = gulp.src('src/server/**/*.ts')
        .pipe(tsProjectServer());
    return tsResult.js
        .pipe(gulp.dest('dist/server'));
});
...

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

 

В данном случае выполняется dev сборка angular части проекта, так как она гораздо быстрее production сборки.

 

 

2. Структура приложения.

 

/dev-dist - директория, в которую собирается (с помощью gulp) dev версия клиентской части, которая используется в процессе разработки.

/dist - содержит весь production код (директории client и server).

/doc - содержит автоматически генерируемую документацию по приложению (возможно будет подробнее описано в будущих статьях).

/e2e - содержит End-to-end тесты приложения, которые отрабатывают с помощью инструмента protractor (возможно будет подробнее описано в будущих статьях).

/node_modules - зависимости приложения, используются только в dev версии, так как в production клиенте все зависимости вшиваются в bundle в директории /dist/client. для серверной части проходит отдельная установка зависимостей, из группы dependencies файла /package.json.

/src - содержит исходный код приложения.

 

 

Комментарий (3)

Yauhen Kavalenka

05 Сентября 2017 в 17:27

А можно получить ссылочку на данный пример? github репозиторий например.

0/ 0
ответить

sidadmin

Yauhen Kavalenka, здравствуйте! К сожалению, данный проект находится в приватном репозитории, и ссылку на данный проект мы предоставить не можем. Данная статься имеет скорее ознакомительный характер, и не претендует на уровень подробного гайда. Спасибо за ваш комментарий!

Евгений

05 Сентября 2017 в 17:26

А можно получить ссылку на Ваш проект с этим примером?

0/ 0
ответить

Войдите с помощью соцсетей:
или
введите свои данные: