使用Angular7构建我自己的MEAN堆栈Web应用程序的几乎所有步骤(1)

简而言之

用 Angular7 建立我式的 MEAN 技术栈备忘录。
本次将进行”客户端基础生成”的操作。

先决条件

这是截至2019年1月1日的信息。并且假设以下环境成立。

    • Angular CLI: 7.0.6

 

    • Node.js: 10.15.0

 

    npm: 6.4.1

另外,假定您对「根目录」、「路由」、「目录」、「组件」、「构建」和「脚本」等词的概念有一定了解。
如果不清楚,请事先简单搜索一下这些词的含义。
(即使您不清楚,按指示进行也能编写出应用程序)

预先准备

请参考「使用 npm 命令安装和升级 Angular CLI 的方法(汇总)」等文章,准备好环境。
以下内容假设您已经能够运行 ng 命令和 npm 命令。

Angular应用程序的初始生成

建立前台基础。

使用Angular CLI进行应用程序自动生成

首先,执行以下命令。
使用 SCSS 生成样式(如果不喜欢,可以选择省略选项)。

# ng new 任意のアプリ名
ng new demo-app --routing=true --style=scss

请确保在执行命令时将“应用程序名称”统一替换。

生成的根目录名称可以更改。

如果在已经克隆了空项目的情况下进行本次生成命令,请将由Angular CLI生成的项目名称目录下的所有文件,除了node_modules和README.md之外,移动或复制到克隆Git目录的根目录。然后删除不需要的目录,并再次运行npm install。

如果指出了脆弱性,就要立即修复。

# 脆弱性に対する対応コマンド
npm audit fix

每次安装npm时,都需要执行这个命令,所以请记住每次都要求它。

将其改为支持PWA

使用以下的 PWA 兼容指令,可以安装 ServiceWorker。

# ng add @angular/pwa --project=アプリ名
ng add @angular/pwa --project=demo-app

当将PWA支持启用后,ngsw-config.json、manifest.json等文件会增加。
因为在使PWA功能时,会利用ServiceWorker来在浏览器中缓存各种内容,如若觉得这让人烦恼的话,可以在启动应用程序之前注释掉PWA功能相关的部分(如src/app/app.module.ts等)。
(※ 为什么会进行缓存,请自行查阅ServiceWorker的相关资料)

实现普遍性

# ng g universal --client-project=アプリ名
ng g universal --client-project=demo-app

在 angular.json 文件中新增一个名为 server 的属性。

追加AppShell

# ng g app-shell --client-project=アプリ名 --universal-project=アプリ名
ng g app-shell --client-project=demo-app --universal-project=demo-app

生成了AppShell的源代码。
(请自行查找AppShell是什么)

引入 Angular Material(可省略)

引入Angular的Material Design。
如果不把Web应用程序设计成Material Design,可以跳过此步骤。

请按照”这篇Qiita文章”中的实际步骤进行安装。

在客户端创建基础

创建一个目录

请在 src/app 目录下创建新的文件夹,内容如下所示。

[ルートディレクトリ]
  ├─ src
  │  └─ app
  │      ├─ app-shell # 既存
  :      ├─ components # 新規作成: コンポーネント用
  :      :

创建合适的组件

我們需要創建一個適當屏幕級別的組件。
這次我們準備了一個名為 Home 的主屏組件。

# src/app/components ディレクトリに移動
cd src/app/components

# コンポーネント生成 (モジュールが2つあるのでスキップオプションを付けないとエラーになるかも)
ng generate c home --skip-import

当完成后,可以使用 cd ../../.. 命令返回原始的目录位置。

主屏组件修改

在完成的组件中进行以下修正:
向界面中添加测试按钮和按钮按下的处理程序。

首先需要修改 TypeScript。

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

  id: number;
  name: string;
  age: number;

  // エラーメッセージ
  message: string;

  sampleList: { id: number, name: string, age: number }[] = [];

  constructor() { }

  ngOnInit() {
  }

  test() {
    // エラーメッセージ初期化
    this.message = '';

    // 入力判定 および 表示処理
    if (this.id && this.name && this.age) {
      this.sampleList.push({ id: this.id, name: this.name, age: this.age });
    } else {
      this.message = '未入力の項目があります。必ず全て入力してください';
    }
  }

  // 表示リストをリセット
  resetList() {
    this.sampleList = [];
  }

}

请修正HTML。

<div class="home">
  <h2>ホーム画面</h2>

  <!--他のコンポーネントに遷移するときに使用  -->
  <!-- <a [routerLink]="'/home2'">go to home2</a> -->

  <!-- エラーメッセージ -->
  <p *ngIf="message" class="error-message">{{ message }}</p>

  <!-- 入力エリア -->
  <div class="condition">
    <label>ユーザID</label>
    <input type="number" [(ngModel)]="id">

    <label>名前</label>
    <input type="text" [(ngModel)]="name">

    <label>年齢</label>
    <input type="number" [(ngModel)]="age">

    <button (click)="test()">表示追加</button>
    <button (click)="resetList()">リセット</button>
  </div>

  <!-- 一覧表示エリア -->
  <table>
    <thead>
      <tr>
        <th>ID</th><th>名前</th><th>年齢</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let element of sampleList">
        <td>{{ element.id }}</td><td>{{ element.name }}</td><td>{{ element.age }}歳</td>
      </tr>
    </tbody>
  </table>
</div>

然后在CSS中添加。

.home { padding: 1rem }
.error-message { color: red }
.condition { margin: 2rem }
.condition input { margin-right: 1rem }
.condition button { margin-left: 1rem }

table {
  width: 100%;
  margin: 3rem 0;
}
thead {
  color: white;
  background-color: #3f51b5;
}

将其添加到模块中

为了启用主屏幕组件,需要将其注册到模块中。
同时,也需要导入Angular所需的模块以处理表单。

:
import { FormsModule } from '@angular/forms'; // 追加

import { HomeComponent } from './components/home/home.component'; // 追加

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent, // 追加
  ],
  imports: [
    :
    FormsModule, // 追加
  ],
:
})
export class AppModule { }

添加画面路由

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { HomeComponent } from './components/home/home.component';

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' }, // 追加
  { path: 'home', component: HomeComponent }, // 追加
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

提前导入通用模块。

为了谨慎起见,我会将 module-map-ngfactory-loader 的类型定义文件放在那儿。

npm i -D @nguniversal/module-map-ngfactory-loader

在模块中添加module-map-ngfactory-loader。

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader'; // 追加
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { Routes, RouterModule } from '@angular/router';
import { AppShellComponent } from './app-shell/app-shell.component';

const routes: Routes = [ { path: 'shell', component: AppShellComponent }];

@NgModule({
  imports: [
    AppModule,
    ServerModule,
    ModuleMapLoaderModule, // 追加
    RouterModule.forRoot(routes),
    MatProgressSpinnerModule
  ],
  bootstrap: [AppComponent],
  declarations: [AppShellComponent],
})
export class AppServerModule {}

修改应用程序的构建/启动命令

将package.json文件中的脚本部分更改如下:

...

  "scripts": {
    "ng": "ng",
    "dev": "ng serve",
    "start": "npx node-static ./dist/demo-app --spa --port=3000",
    "build": "npm run build:client",
    "build:client": "ng run demo-app:app-shell:production", // ng run アプリ名:app-shell:production
    "build:clientsub": "ng build && ng run demo-app:server",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },

...

更改接待端口

为了保险起见,在执行ng serve时指定并匹配接受的端口。

angular.json的意思是角度json。

在数据结构中,添加一个端口设置到projects.项目名.架构师.提供的选项中。

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "demo-app": {
      
      "architect": {
        
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "demo-app:build", // カンマだけ追加
            "port": 3000 // 1行追加
          },
          "configurations": {
            "production": {
              "browserTarget": "demo-app:build:production"
            }
          }
        },
        
      }
    },
    
角度计.js

更改测试时URL的端口号

...
  baseUrl: 'http://localhost:3000', // 4200 から修正
...

请稍微确认一下

# ビルド
npm run build

# ビルド終わったら、アプリ起動
npm run start

启动后,通过Web浏览器访问http://localhost:3000 。如果能够确认显示成功,则表示成功(停止请按Ctrl + C)。

只有在AppShell生效时,初次显示界面时会短暂显示AppShellComponent的内容,而且仅限于初次界面显示缓慢的情况。

实际显示的屏幕示例

在浏览器中,初始情况下应该显示如下屏幕。
※ 在图片中,使用 Angular Material 在页眉部分引入了 Material Design。

スクリーンショット 2019-02-09 19.38.45.png

当你按下“添加显示”按钮而没有输入任何内容时,应该会有这种感觉。

スクリーンショット 2019-02-09 19.39.29.png

如果您尝试填写输入框并点击“添加显示”按钮,应该会将其添加到列表中。(如果连续快速点击,将会添加很多)

スクリーンショット 2019-02-09 19.39.12.png

只需要按下”重置”按钮,一切都应该消失。

后端引入准备工作

在做服务器端之前,将客户端相关的目录修改为易于理解的名称。
这次将其修改为”browser”目录。

更改源代码文件夹的名称。

将客户端的目录名称从 src 更改为 browser。

修改 angular.json

在 angular.json 文件中,将 src 替换为 browser。

确认行动

# ビルド
npm run build

# ビルド終わったら、アプリ起動
npm run start

只要正常运行就可以了。

? 请参考以下开发步骤

广告
将在 10 秒后关闭
bannerAds