Angular 4.x系のプロジェクトを5.x系にアップデートした際のメモ

自分の携わっているプロジェクトのAngularのバージョンを４系から5系にバージョンアップを行った。その際に行ったことをメモしておく。ちなみに開発環境としてAngular CLIではなく[angular-seed](https://github.com/mgechev/angular-seed)を使用しいている。

## angular-seedのバージョンアップ

最新のangular-seedを現在のリポジトリに取り込むことで、Angularを現在の最新バージョン（v5.0.1）にできる。

angular-seedのリポジトリを現在のリポジトリに取り込むために`git subtree`を使う。

まず外部リポジトリ`upstream`としてangular-seedのリポジトリを登録する。

```bash
$ git remote add upstream https://github.com/mgechev/angular-seed
```

登録した外部リポジトリ`upstream`の内容を取り込む。任意のディレクトリに取り込みたいので、`-P`オプションで指定。

```bash
$ git subtree pull -P frontend/ upstream master
```

### 参考サイト

- [Gitのsubtreeについてのまとめ](https://gist.github.com/timakin/34255f56dd5595cee421)
- [Git - サブツリーマージ](https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E3%82%B5%E3%83%96%E3%83%84%E3%83%AA%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%B8)

## コンフリクトを解消

angular-seedの最新版を取り込むと必ずコンフリクトが発生する。特に`package.json`や`yarn.lock`は凄まじいことになっている。とりあえず以下に注意する。

- 自分で追加したパッケージは残す
- 追加していないパッケージを取り込み先を反映する


## 関連パッケージをインストール

`package.json`や`yarn.lock`のコンフリクトを解消したら、関連パッケージも最新の状態にする必要がある。`yarn`または`npm`でインストール。

```bash
# yarnでインストールする場合
$ yarn install

# npmでインストールする場合
$ npm install
```

この時点で、`npm start`して、アプリケーションを起動してみる。コンフリクト解消とパッケージのインストールがちゃんとできていれば、おそらく立ち上がるはず。ただ、完全に動くとまではいかないはず。

## @anular/http 5.x系をインストール

Angular 5からHTTPリクエストを行うためのモジュール`@angular/http`が非推奨となった。代わりにAngular 4.3から追加された`@angular/common/http`の`HttpClient`を使用するようになっている。この部分は修正が大変なので追々対応するとして、ひとまず動かすために現状の`@angular/http`をアップデートすることにした。

以下のコマンドで`@angular/http`の最新版をインストール。

```bash
# yarnでインストールする場合
$ yarn add @angular/http

# npmでインストールする場合
$ npm i -S @angular/http
```

ブラウザのコンソールに以下のエラーが出るようであれば、

```console
Uncaught SyntaxError: Unexpected token <
```

angular-seedの`project.config.ts`に以下を追加。

```ts
{ name: '@angular/http', path: 'node_modules/@angular/http/bundles/http.umd.min.js' },
```

## RouterModuleの設定を修正

またRxJSのバージョンが`5.5.3`の場合、Angular 5ではうまくルーティングができないという不具合があるとのこと。`5.5.2`にダウングレードすれば問題ないとのこと。

- [Angular 5.0.5 doesn't work with RxJS] (5.5.3https://github.com/angular/angular/issues/20752)

実際に今回のangular-seedのアップデートでRxJSのバージョンが`5.5.3`になっていたので、以下のようなエラーが出た。

```console
ERROR Error: Uncaught (in promise): EmptyError: no elements in sequence
```

RouterModuleの設定は以下のようになっていた場合は、

```ts
@NgModule({
  imports: [
    RouterModule.forChild([
      { path: 'home', component: HomeComponent }
    ])
  ],
  exports: [RouterModule]
})
```

`pathMatch: 'full'`を追加して、以下のようにすると無事ルーティングが行われるようになる。

```ts
@NgModule({
  imports: [
    RouterModule.forChild([
      { path: 'home', component: HomeComponent, pathMatch: 'full' }
    ])
  ],
  exports: [RouterModule]
})
```

## @angular/material 5.x系をインストール

とりあえず、ここまでで通常通り動くようになった。ただ自分たちのプロジェクトでは、`@angular/material`を使用しているので、こちらも`5.x系`にアップデートすることにした。これまでは`2.0.0-beta.12`を使用していた。

以下のコマンドでインストール。今回はバージョンを指定しないと、最新版がインストールされなかったので、バージョンを指定してインストールした。

```bash
# yarnでインストールする場合
$ yarn add @angular/material@5.0.4 @angular/cdk@5.0.4

# npmでインストールする場合
$ npm install --save @angular/material@5.0.4 @angular/cdk@5.0.4
```

ブラウザのコンソールに以下のエラーが出るようであれば、

```console
Uncaught SyntaxError: Unexpected token <
```

angular-seedの`project.config.ts`にパッケージを追加。自分たちのケースでは、`@angular/cdk`の`accordion`と`layout`が読み込まれていなかったようなので、以下を追加。

```ts
{
  name: '@angular/cdk/accordion',
  path: 'node_modules/@angular/cdk/bundles/cdk-accordion.umd.js'
},
{
  name: '@angular/cdk/layout',
  path: 'node_modules/@angular/cdk/bundles/cdk-layout.umd.js'
},
```

## まとめ

とりあえず、これで4.x系の時とほぼ同じように動くようになった。あとは自分で追加したパッケージがAngular 5でもちゃんと動いているか確認し、もし何か不具合があれば対処する必要がある。それからAngular 5からRxJS v5.5.2以降を採用するようになりオペレータのインポートの方法にも変更があったりする。この辺りも追々対応していきたい。同様に、記事にも書いたがHTTPリクエストの部分も推奨されている`@angular/common/http`の`HttpClient`を使用するようにしていきたい。