В данной статье будут разобраны все основные инструменты и ключевые моменты при построениии Single Page Application на стэке технологий MEAN (MongoDB, Express, Angular, Nodejs).
Все примеры будут приведены на основе нашего корпоративного приложения.
Основные настройки.
- /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 сборки.
/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 репозиторий например.
sidadmin
Yauhen Kavalenka, здравствуйте! К сожалению, данный проект находится в приватном репозитории, и ссылку на данный проект мы предоставить не можем. Данная статься имеет скорее ознакомительный характер, и не претендует на уровень подробного гайда. Спасибо за ваш комментарий!
Евгений
05 Сентября 2017 в 17:26А можно получить ссылку на Ваш проект с этим примером?