angular工做區: 多應用程序項目

OctoPer的負載測試IDE(kraken)是具備多個前端應用程序的angular項目,javascript

  • 用於管理Docker容器和容器鏡像的管理UI
  • 使用Gatling調試和執行負載測試的Gatling UI 這兩個UI均基於Angular8,並共享許多組件,css和外部庫依賴項。

這篇博文是想給每一個想要建立具備多個應用程序和庫的Angular Workspace的開發人員一份參考指南。css

根據我建立Kraken的經驗,首先說明如何使用Angular/Cli生成此類項目, 而後進行共享資源和單元測試,並給出有關部署的提示html

Angular多應用項目建立

首先,讓咱們要知道什麼是angular Workspace Workspace是一組angular應用程序和庫。angular.json 是Angular Workspace 的根級別文件爲構建和開發工具提供了工做區範圍和特定於項目(應用程序或庫)的配置默認值。前端

但願可使用Angular cli生成Angular工做空間及其配置。就是本文章的主題:如何使用angular Cli 生成工做空間和其應用程序和庫。java

請記住,在Angular術語中項目既能夠是應用程序,也能夠是庫。二者都存儲在projects工做區的文件夾中, 並在根angular.json文件中進行配置。node

先決條件

Angular須要Node.js版本10.9.0或更高版本(運行node -v查看當前版本)。 Angular cli生成的Angular應用程序都依賴於以npm軟件包的形式提供的外部庫。 Node.js包含一個npm軟件包管理器。運行npm -v以檢查npm版本。我建議使用命令將npm更新到最新的可用版本 (在本博客發佈時爲6.10.0) npm install -g npm@latestnginx

最後,你須要Angular Cli, 使用如下命令在全局安裝它:git

npm install -g @angular/cli
複製代碼

建立工做區(Workspace)

ng new <name>命令用戶生成工做空間github

ng new kraken --createApplication=false --directory=frontend --interactive=false
複製代碼
  • --createApplication=false參數避免建立初始應用程序(默認值爲true)。不然,Angular CLI src在新工做空間的文件夾中建立一個應用程序。在工做空間的子文件夾(projects)中生成應用程序。
  • --interactive=false參數用在此處,用以免angular cli建立項目時提示無用的參數,例如初始應用程序(咱們不生成)是否應包含路由模塊或要使用的CSS預處理程序。
  • --directory=frontend參數是初始化工做空間的目錄名稱。默認爲工做空間名稱。

正如咱們在上面的屏幕截圖中看到的那樣,此命令在frontend文件夾中生成了幾個文件chrome

第一個是Angular Workspace配置文件 angular.json。目前,它僅包含有關項目(應用程序和庫) 位置的信息。一旦咱們生成了一些東西,它將變得很是複雜。

{
      "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
      "version": 1,
      "newProjectRoot": "projects",
      "projects": {}
    }
複製代碼

該package.json文件列出了Angular所需的全部依賴關係。 因爲該ng new命令還安裝了npm依賴項,所以將生成package-lock.json文件 以及包含下載的依賴項的node_modules文件夾。

tsconfig.json文件指定打字稿編譯器選項(anuglar項目使用TS)。 而tslint.json文件配置打字稿短絨,是一個工具,用於分析源代碼, 標記編程錯誤,錯誤,文體錯誤,以及可疑的構造。

最後,README.md還會生成一個文件。 閱讀該文檔以獲取與Angular CLI用法有關的信息:如何構建,服務和測試新生成的應用程序

建立應用程序(application)

ng generate application <name> 命令用於projects在工做區的子文件夾中建立新的應用程序。 運行如下命令以生成兩個應用程序:Administration和Gatling:

cd frontend
    ng generate application administration --style=scss --routing=true
    ng generate application gatling --style=scss --routing=true
複製代碼
  • 參數--style=scss設置用於樣式文件的SCSS預處理器(默認爲CSS)--參數能夠不帶。
  • 參數--routing=true告訴Angular CLI生成路由NgModule --參數能夠不帶。

這些命令在子文件夾projects生成administration、gatling兩個項目,其中包含的文件以下(和常規的angular cli生成的項目,缺乏package.json文件)

  • 兩個tsconfig.*.ts文件。它們擴展了工做空間的根目錄,tsconfig.ts並設置了特定的配置以編譯應用程序(tsconfig.app.ts)或其單元測試(tsconfig.spec.ts)。在Angular文檔中閱讀有關TypeScript配置的更多信息。
  • 該src文件夾包含您應用程序的全部TypeScript,HTML和CSS源(有關src文件夾結構的更多信息)。
  • karma.conf.js用於單元測試的Karma配置文件。
  • e2e用於使用量角器運行端到端測試的文件夾。

命令也更新了根angular.json文件,添加了兩個應用程序配置:

{
      "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
      "version": 1,
      "newProjectRoot": "projects",
      "projects": {
        "administration": {
          "projectType": "application",
          [...]
        },
        "gatling": {
          "projectType": "application",
          [...]
        }
      },
      "defaultProject": "administration"
    }
複製代碼

咱們稍後將瞭解針對每一個應用程序項目的配置,由於咱們將必須更新它們以共享資源。

建立庫 (librany)

ng generate library <name>命令用於生成庫。 在工做空間文件夾中(frontend若是您遵循本教程的介紹),請運行如下命令:

ng generate library tools
    ng generate library vendors

複製代碼

再次在這裏,angular.json使用兩個新建立的庫更新文件:

{
      "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
      "version": 1,
      "newProjectRoot": "projects",
      "projects": {
        "administration": {
          [...]
        },
        "gatling": {
          [...]
        },
        "tools": {
          "projectType": "library",
          [...]
          }
        },
        "vendors": {
          "projectType": "library",
          [...]
        }
      },
      "defaultProject": "administration"
    }


複製代碼

它還爲每一個庫projects/tools和projects/vendors建立相應的文件。文件與應用程序生成時的文件相似。

要注意的一件事是,在生成庫時不能指定樣式預處理器。angular.json庫的工做空間配置(文件)中沒有與此相關的配置。您每次在庫中生成組件時都必須指定樣式,例如使用command ng generate component my-component --style=scss --project=tools

建立共享服務

這裏的想法是在庫中生成服務,並在應用程序中使用它。 讓咱們在tools庫中建立一個虛擬服務:

ng generate service hello-world --project=tools

複製代碼

語法是,ng generate service <service-name>而且該參數--project是必需的,以指定在那個庫中生成服務。

這將建立一個文件projects/tools/src/hello-world.service.ts及其單元測試(projects/tools/src/hello-world.service.spec.ts)。更新它以建立一個簡單的getter:

import {Injectable} from '@angular/core';

    @Injectable({
      providedIn: 'root'
    })
    export class HelloWorldService {
      get message(): string {
        return 'Hello World!';
      }
    }
複製代碼
注意:該服務經過providedIn: 'root'選項聲明爲可注入。這意味着該服務是單例。它能夠在任何組件或服務中使用,而無需提供它。不管您在哪裏使用它,它始終是同一實例。

若是沒有此選項,咱們可能會使用每一個實例的語法爲每一個實例注入一個實例@Component({providers: [HelloWorldService]})。咱們也可使用語法在模塊級別執行相同的操做@NgModule({providers: [HelloWorldService]})。

在Angular文檔中閱讀有關依賴注入的更多信息。
複製代碼

更新AppComponent projects/administration/src/app/app.component.ts使用上面的服務

import {Component} from '@angular/core';
    import {HelloWorldService} from 'projects/tools/src/lib/hello-world.service';

    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })
    export class AppComponent {
      title = 'administration';

      constructor(helloWorld: HelloWorldService) {
        this.title = helloWorld.message;
      }
    }
複製代碼

若是使用的是IntelliJIdeaWebstorm,則HelloWorld服務的默認導入爲 import {HelloWorldService} from '../../../tools/src/lib/hello-world.service';。 若是您四處移動文件,這將很醜陋且難以維護。您能夠打開項目設置,而後選擇TypeScript>導入>「 使用相對於tsconfig.json的路徑」選項:

安裝Angular Material UI

Angular Material是一組遵循Material Design設置的約定的組件。 藉助Angular CLI,只需運行如下命令便可在兩個應用程序上安裝Angular Material。

ng add @angular/material
    ng add @angular/material --project=gatling
複製代碼
注意:第一個命令不須要--project=administration參數,由於它是工做區配置中的默認項目("defaultProject": "administration"在angular.json文件中)。
複製代碼

這兩個命令在package.json文件中添加依賴項@angular/material,還自動更新各類項目文件,添加適當的樣式,導入字體和NgModules:

UPDATE projects/administration/src/main.ts (391 bytes)
    UPDATE projects/administration/src/app/app.module.ts (502 bytes)
    UPDATE angular.json (10132 bytes)
    UPDATE projects/administration/src/index.html (482 bytes)
    UPDATE projects/administration/src/styles.scss (181 bytes)
複製代碼

我發現將外部依賴項從新組合到單個NgModule中更加乾淨。 這就是爲何咱們以前建立了一個vendors庫。

所以,讓咱們更新VendorsModule文件projects/vendors/src/lib/vendors.module.ts以導入和導出MatButtonModule,從而在一個地方從新組合咱們的外部依賴項:

import {NgModule} from '@angular/core';
    import {MatButtonModule} from '@angular/material';

    @NgModule({
      imports: [MatButtonModule],
      exports: [MatButtonModule]
    })
    export class VendorsModule { }
複製代碼

而後,咱們在AppModule中導入VendorsModule projects/administration/src/app/app.module.ts:

@NgModule({
      [...]
      imports: [
        VendorsModule,
      ],
      [...]
    })
    export class AppModule { }
複製代碼

最後,使用mat-raised-buttonAppComponent中的指令 projects/administration/src/app/app.component.html:

<div style="text-align:center">
      <h1>
        Welcome to {{ title }}!
      </h1>
      <div><img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,..."></div>
      <button mat-raised-button color="primary" >Click Me!</button>
    </div>
複製代碼

啓動應用程序

要爲Angular應用程序提供服務,需運行命令ng serve --project=administration。

而後,您能夠在http://localhost:4200/上打開網頁:

若是按照本教程的每一個步驟進行操做,則應該看到「歡迎使用Hello World !」消息以及提出的材料「 Click Me!」按鈕。

不然,您能夠下載源代碼(僅npm install在啓動應用程序以前運行)。

若是您想看一個更復雜的應用程序,請轉到「 完整的應用程序示例」一章。

另請注意,若是要同時啓動administration和gatling應用程序,則會看到錯誤消息:

Port 4200 is already in use. Use '--port' to specify a different port.
    Error: Port 4200 is already in use. Use '--port' to specify a different port.
複製代碼

須要使用--port選項 具體請官方文檔或者閱讀「 如何使用HAProxy服務多個角度的應用程序(下文有介紹)」一章以瞭解如何設置應用程序使用的默認端口。

Angular多應用程序共享資源

讓咱們回到負載測試IDE。將像Kraken這樣的大型應用程序拆分爲幾個模塊和庫是很不錯的。 它簡化了維護並提升了代碼的可重用性。

關於可重用性,跨組件庫共享CSS樣式和資產,擁有徹底隔離的模塊可能會更乾淨一些, 可是因爲我全部的庫和應用程序都依賴於Angular Material, 由於我不想爲每一個項目重複導入代碼。

庫和應用程序共享CSS

在上面的介紹中,咱們導入了默認的Angular Material主題之一。 爲了使Kraken具備IDE的外觀和感受,我想使用自定義Angular Material主題,其主題爲:

  • 黑暗的背景
  • 顏色比基本的主色和及其餘提示顏色(添加警告,成功,危險和其餘顏色),
  • 組件的佈局更加密集(尚無多層密度)。 Kraken的用戶界面

要建立此UI,我必須建立幾個組件庫:

  • 可調整大小的拆分面板,
  • 控制檯和文件樹的標籤,
  • 代碼編輯器,
  • 和結合了全部這些的主工做區。

它們都使用位於工做區根目錄styles文件夾中的通用CSS 。 例如,自定義材質主題SCSS文件將初始化Material Design並聲明自定義顏色:

@import '../node_modules/@angular/material/theming';

    [...]

    $app-primary: mat-palette($mat-blue);
    $app-accent: mat-palette($mat-green);
    $app-info: mat-palette($mat-light-blue);
    $app-success: mat-palette($mat-light-green);
    $app-error: mat-palette($mat-deep-orange);
    $app-background: mat-palette($mat-gray);

    [...]

    $mat-theme: (
      [...]
    );

    @include angular-material-theme($mat-theme);

複製代碼

而且緊湊的Scss文件,聲明瞭用於更改組件密度的自定義CSS類:

@import 'app-padding';
    @import 'app-font';

    // Must also disable the ripple effect
    @mixin compact-checkbox($size: 34px) {
      $half: $size / 2;
      .mat-checkbox-inner-container {
        height: $half;
        width: $half;
      }
    }

    @mixin compact-button($size: 34px) {
      .mat-icon-button {
        width: $size;
        height: $size;
        line-height: $size * 0.9;

        .ng-fa-icon {
          font-size: $size * 0.5;
        }
      }
    }
    [...]

複製代碼

爲了在管理和加特林負載測試應用程序中使用這些SCSS文件, 咱們必須在Angular的工做區配置中聲明它們angular.json:

"stylePreprocessorOptions": {
      "includePaths": [
        "styles"
      ]
    },
複製代碼

stylePreprocessorOptions必須加入到projects > administration / gatling > architect > build > options

在運行單元測試時,若是某些被測組件須要通用樣式,則可能會出現如下錯誤:

ERROR in ../icon/src/lib/icon/icon.component.scss                                                                                                                   
    Module build failed (from /home/kojiro/workspaces/kraken/frontend/node_modules/sass-loader/lib/loader.js):

    @import 'app-margin';
          ^
    Can't find stylesheet to import.

複製代碼

在這種狀況下,只需將添加stylePreprocessorOptionsprojects > my-project > architect > test > options工做空間配置部分。

跨庫和應用程序共享資產

除了公共CSS文件外,您可能還但願在應用程序和庫之間共享資產。

例如,在Kraken的資產中,咱們存儲:

  • Kraken logo,
  • Ace編輯器使用的Javascript文件。 實際上,因爲配置,Ace主題和模式文件位於ext文件夾中並已複製angular.json。 例如,Gatling build架構師選項包括如下配置:
"assets": [
      "projects/gatling/src/favicon.ico",
      "projects/gatling/src/assets",
      {
        "glob": "**/*",
        "input": "assets/",
        "output": "assets/"
      },
      {
        "glob": "**/worker-*.js",
        "input": "node_modules/ace-builds/src-min/",
        "output": "assets/ace/"
      },
    ],
複製代碼

它首先聲明特定於Gatling應用程序的資產。 而後,它將使用語法"glob": "**/*"將其包含在根資產文件夾中的全部文件。 最後,全部Ace方法都被複制到中assets/ace/

咱們還使用許多其餘與Ace代碼編輯器相關的javascript文件。 這些主題,模式和代碼段必須在Architect選項的scripts部分中聲明build:

"scripts": [
    "node_modules/ace-builds/src-min/mode-xml.js",
    "node_modules/ace-builds/src-min/mode-yaml.js",
    "node_modules/ace-builds/src-min/ext-searchbox.js",
    "node_modules/ace-builds/src-min/ext-language_tools.js",
    "node_modules/ace-builds/src-min/ext-modelist.js",
    "ext/mode-log.js",
    "ext/theme-kraken.js",
    "ext/snippets/scala.js"
  ]
複製代碼

不管您要使用資產和外部腳本實現什麼目標,建議您瀏覽一下Angular-Cli文檔頁面: Stories Asset Configuration

Angular工做區和單元測試

Angular CLI容許您使用如下語法在特定項目上運行單元測試:

ng test --project=<my-project>
複製代碼
  • 默認狀況下,它將連續運行單元測試,讓您知道它們是成功仍是失敗。 若是是使用fit而不是it在單元測試定義上運行該特定測試(您也能夠fdescribe在測試套件上使用)。

  • 它會在帶有選項的文件夾中自動生成測試覆蓋率報告。 /coverage/my-project--watch=false --codeCoverage=true

我但願有一個報告能夠從新組合全部覆蓋率信息,並經過並行運行單元測試來加快測試執行速度。 所以,我建立了如下腳本:

#!/bin/bash
    rm -rf coverage
    rm -rf coverage-all

    for dir in projects/*; do
      if [["$dir" != *-e2e]]
      then
        prefix="projects/";
        project=${dir#$prefix}; #Remove prefix
        echo "$project"
        ng test --watch=false --codeCoverage=true --sourceMap=true --project=$project &
      fi
    done

    wait  # Wait for all tasks to complete

    ./node_modules/istanbul/lib/cli.js report --dir ./coverage-all/ html

    google-chrome ./coverage-all/index.html &

複製代碼

它對每一個不以結尾結尾的項目-e2e(這些都是端到端測試項目)並行運行單元測試, 而且覆蓋範圍平行。而後,使用Istanbul client彙總全部報告。 警告:若是您有多個項目,則此腳本將同時運行多個Web瀏覽器。它可能會在計算機運行時凍結您的計算機!

Istanbul須要JSON格式的報告才能進行彙總.所以,也要更新karma.conf.js文件。它們位於每一個應用程序或庫的根目錄。只需添加json報告:

coverageIstanbulReporter: {
      dir: require('path').join(__dirname, '../../coverage/analysis'),
      reports: ['html', 'lcovonly', 'json'],
      fixWebpackSourcePaths: true
    },

複製代碼

若是您想知道如何編寫單元測試,請查看有關測試的Angular文檔

如何使用HAProxy服務服務多個Angular應用程序

在Kraken中,咱們有兩個Angular應用程序:AdministrationGatling

這個想法是要在不一樣的端口和base Href上服務;而後將它們打包爲在相同端口上使用但使用不一樣的基本Href的docker映像。 將它們打包爲在相同端口上使用,但使用不一樣的base Href的docker映像。

在特定端口和base Href上部署Angular應用

默認狀況下,Angular在相同的URL和端口上爲全部應用程序提供服務:http://localhost:4200

爲了可以在開發過程當中同時啓動兩個應用程序, 請在Angular工做區配置angular.json文件中更改其中一個的端口。 例如,在Kraken中,Gatling應用程序的serve架構師配置爲在端口4222上爲其提供服務:

"serve": {
      "builder": "@angular-devkit/build-angular:dev-server",
      "options": {
        "browserTarget": "gatling:build",
        "port": 4222
      },
      "configurations": {
        "production": {
          "browserTarget": "gatling:build:production"
        }
      }
    },
複製代碼

而後,ng serve使用如下參數運行命令:

ng serve --open --project=gatling --baseHref /gatling/
複製代碼

因爲參數和配置的緣由,它將經過URL http://localhost:4222/gatling打開Web瀏覽器。

將Angular應用打包爲Docker映像

藉助Angular-Cli ng build命令能夠構建Angular應用程序:

ng build gatling --prod --baseHref /gatling/
複製代碼

一樣,這裏--baseHref /gatling/用於指定base Href。 該應用程序內置於文件夾中dist/gatling。 如下DOCKERFILE生成一個NGINX Docker映像,其中包含已構建的應用程序:

FROM nginx:1.15.9-alpine
    ARG APPLICATION
    COPY nginx.conf /etc/nginx/nginx.conf
    WORKDIR /usr/share/nginx/html
    COPY dist/$APPLICATION .
    RUN ls -laR .
    EXPOSE 80
複製代碼

ng build命令的輸出將複製到/usr/share/nginx/html圖像的文件夾中,並使用如下Nginx配置:

worker_processes  1;

    events {
        worker_connections  1024;
    }

    http {
        server {
            listen 80 default_server;
            server_name  localhost;

            root   /usr/share/nginx/html;
            index  index.html index.htm;
            include /etc/nginx/mime.types;

            gzip on;
            gzip_min_length 1000;
            gzip_proxied expired no-cache no-store private auth;
            gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

            location / {
                try_files $uri $uri/ /index.html;
            }
        }
    }
複製代碼

運行如下命令以生成Docker映像:

docker build --rm=true -t gatling-ui:latest --build-arg APPLICATION=gatling .
複製代碼

使用HAProxy提供生產鏡像

HAProxy是一種開源軟件,可爲基於TCP和HTTP的應用程序提供高可用性代理服務器。 對於Kraken,咱們使用它在適當的Frontend上重定向HTTP請求,具體取決於base Href(感謝path_beg/administration關鍵字)。 這是配置文件:

global

    defaults
        mode    http
        option  forwardfor
        option  http-server-close
        # Set the max time to wait for a connection attempt to a server to succeed
        timeout connect 30s
        # Set the max allowed time to wait for a complete HTTP request
        timeout client  50s
        # Set the maximum inactivity time on the server side
        timeout server  50s
        # handle the situation where a client suddenly disappears from the net
        timeout client-fin 30s

    frontend http-in
        bind *:80
        mode http

        acl has_administration  path_beg /administration
        acl has_gatling  path_beg /gatling

        use_backend kraken-administration if has_administration
        use_backend kraken-gatling if has_gatling

    backend kraken-administration
        server kraken-administration-ui kraken-administration-ui:80 check fall 3 rise 2
        reqrep ^([^\ ]*\ /)administration[/]?(.*)     \1\2

    backend kraken-gatling
        server kraken-gatling-ui kraken-gatling-ui:80 check fall 3 rise 2
        reqrep ^([^\ ]*\ /)gatling[/]?(.*)     \1\2

複製代碼

啓動它的最簡單方法是使用HAProxy Docker映像。

要查看完整的示例(使用啓動兩個前端應用程序,多個後端服務器和HAProxy docker-compose)。

完整的應用

我但願這篇博文對但願嘗試Angular開發複雜的多項目工做區的人有所幫助。

能夠在GitHub上找到Kraken的Angular前端的源代碼,請查看完整的最新代碼示例。若是您認爲我錯過了Angular開發的重要部分或犯了一個錯誤,請給我寫評論。

最後,若是您想了解有關負載測試IDE的Kraken的更多信息,請查看其GitHub頁面

博文地址:地址

原文地址:

原文地址

相關文章
相關標籤/搜索