Angular本体を5.2から6系にメジャーバージョンアップで遭遇した壁

# 概要

- Angular本体を5.2から6系にメジャーバージョンアップした際の足跡と引っかかった点のメモ


## 公式のアップグレードガイド

- [Angular Update Guide](https://update.angular.io/)


## やったこと

- 公式の Update Guide から、該当したものだけを抜き出し、足りなかった部分を追記

### Before Updating

- [ ] Update your Angular CLI globally and locally, and migrate the configuration to the new angular.json format by running the following:

```sh
npm install -g @angular/cli
npm uninstall @angular/cli --save
npm install @angular/cli --save-dev
ng update @angular/cli
```

- [ ] Update any `scripts` you may have in your `package.json` to use the latest Angular CLI commands. All CLI commands now use two dashes for flags (eg `ng build --prod --source-map`) to be POSIX compliant.

- [ ] `@angular/core` をupdateした際に `angularfire2` で下記のエラーを防ぐため、 `rxjs-compat` をインストール
> Package "angularfire2" has an incompatible peer dependency to "rxjs" (requires "^5.5.4", would install "6.2.2").

```sh
npm install --save rxjs-compat
```

- [ ] @angular/flex-layout の6系最新版を個別にインストール (下記のエラー用の対応)
> Package "@angular/flex-layout" has an incompatible peer dependency to "rxjs" (requires "^5.5.0", would install "6.2.2").
> Incompatible peer dependencies found. See above.

```sh
npm install --save @angular/flex-layout@6.0.0-beta.16
```

- [ ] Update all of your Angular framework packages to v6, and the correct version of RxJS and TypeScript.

```sh
ng update @angular/core
```

After the update, TypeScript and RxJS will more accurately flow types across your application, which may expose existing errors in your application's typings

- [ ] Update Angular Material to the latest version.

```sh
ng update @angular/material
```

This will also automatically migrate deprecated APIs.

- [ ] Use `ng update` or your normal package manager tools to identify and update other dependencies.


### After the Update

- [ ] Remove deprecated RxJS 6 features using rxjs-tslint auto update rules.
For most applications this will mean running the following two commands:

```sh
npm install -g rxjs-tslint
npm install -g typescript
rxjs-5-to-6-migrate -p src/tsconfig.app.json
```

- [ ] Once you and all of your dependencies have updated to RxJS 6, remove rxjs-compat.

```sh
npm uninstall rxjs-compat --save
```

## アップデート手順で遭遇したエラー

### @angular/cli のエラー

> Your global Angular CLI version (6.0.8) is greater than your local version (1.6.8). The local Angular CLI version is used.
> 
> To disable this warning use "ng config -g cli.warnings.versionMismatch false".
> The specified command update is invalid. For available options, see `ng help`.

- 解決策
    - 一旦uninstallし、改めてinstallすると、最新版の6系がインストールされる
    - [angular/angular-cli - ng update failed with angular 5 project generated by CLI 1.7.4 #10664](https://github.com/angular/angular-cli/issues/10664)

```sh
npm uninstall @angular/cli --save
npm install @angular/cli --save-dev
```

### angularfire2 のエラー

> Package "angularfire2" has an incompatible peer dependency to "rxjs" (requires "^5.5.4", would install "6.2.2").

- 解決策
    - `rxjs-compat` をインストール
    - [angularfire 2 isn't working with Angular 6 #1602](https://github.com/angular/angularfire2/issues/1602)

```sh
npm install --save rxjs-compat
```

### @angular/flex-layout のエラー

```sh
$ ng update @angular/core
```

> Package "@angular/flex-layout" has an incompatible peer dependency to "rxjs" (requires "^5.5.0", would install "6.2.2").
> Incompatible peer dependencies found. See above.

- 解決策
    - flex-layoutの6系最新版を個別にインストール
    - [angular/flex-layout - Angular 6 support #735](https://github.com/angular/flex-layout/issues/735)

```sh
npm install --save @angular/flex-layout@6.0.0-beta.16
```

### rxjs-5-to-6-migrate のエラー

> $ rxjs-5-to-6-migrate -p src/tsconfig.app.json
> Running the automatic migrations. Please, be patient and wait until the execution completes.
> Error: Cannot find module 'typescript'

- 解決策
    - グローバルに `typescript` をインストール
    - [ReactiveX/rxjs-tslint - rxjs-5-to-6-migrate - cannot find any possible migration](https://github.com/ReactiveX/rxjs-tslint/issues/49)

```sh
npm install -g typescript
```

### Observable.of のエラー

> Observable.of is not a function
- 解決策
    - `import { of } from 'rxjs';` を追加
    - `Observable.of` を `of` だけに変更
    - [Observable.of is not a function with correct import - StackOverflow](https://stackoverflow.com/questions/50468446/observable-of-is-not-a-function-with-correct-import/50468586)


### switchMap のエラー

> switchMap is not a function
- 解決策
    - `pipe` オペレータの中で `switchMap` を指定するように変更
    - [I dont get rxjs 6 with angular 6 with interval, switchMap, and map - StackOverflow](https://stackoverflow.com/questions/50200859/i-dont-get-rxjs-6-with-angular-6-with-interval-switchmap-and-map)


### Angularfire2 のエラー

> Property 'downloadURL' does not exist on type 'AngularFireUploadTask'.

- 解決策
    - downloadUrl が無くなったので、形式を大幅に変更する必要あり
    - [AngularFireStorage - angularfire2/docs/storage/storage.md](https://github.com/angular/angularfire2/blob/master/docs/storage/storage.md)
    - [Angularfire2 Error “Property 'downloadURL does not exist on type 'AngularFireUploadTask'.”
](https://stackoverflow.com/questions/50613426/angularfire2-error-property-downloadurl-does-not-exist-on-type-angularfireupl/50613784#50613784)
    - [https://blog.angular.io/file-uploads-come-to-angularfire-6842352b3b47](https://blog.angular.io/file-uploads-come-to-angularfire-6842352b3b47)
    - [rxjs-compat missing 'toPromise' operator](https://github.com/ReactiveX/rxjs/issues/3482)

### date pipe のエラー

> Unable to convert "Timestamp" into a date' for pipe 'DatePipe'

- 解決策
    - `{{ createdAt.toDate() | date:'yyyy/MM/dd HH:mm' }}` のように、 `.toDate()` を加える
    - [DatePipe is not working correctly in Angular 6 - StackOverflow](https://stackoverflow.com/questions/50421317/datepipe-is-not-working-correctly-in-angular-6)


### ng buildのエラー

- `ng build` のオプションから `--target` と `--environment` は無くなった
- 代わりに、 `--configuration` を使う
- `ng build --aot --target=production --environment=dev` を書き換える場合
    - `angular.json` の `configurations` 内に、 `production` と同じ中身で `dev` を追加し、 `fileReplacements` だけ削除
    - その他のパラメータは、必要に応じて変更
    - コマンド部分を `ng build --configuration=dev` に置き換え

```json
          "configurations": {
            "production": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            },
            "dev": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            }
          }
```


## 参照

- [Version 6 of Angular Now Available](https://blog.angular.io/version-6-of-angular-now-available-cc56b0efa7a4)