ふるてつのぶろぐ

福岡在住のエンジニアです。

写真提供:福岡市

Angular11でWebアプリを作ろう - V11にバージョンアップ - ng update

今日すること

こんにちは、ふるてつです。
もう年末ですね。
Angularがバージョン 11 にあがりました。
9から10に上がるときはそれほど修正はなかったのでブログを書かなかったのですが、今回はすこし修正が多く感じたのでその内容を書こうと思います。

バージョンアップ情報の確認

まずはこちらのサイトで手順やその他情報をチェックします。
https://update.angular.io/?v=10.0-11.0
わたしの場合は、Materialを使っているので「I use Angular Material」はチェックONにします。
f:id:tetsufuru:20201215161520p:plain:w800 特に大きな変更とか書いてないですね、楽にバージョンアップできそうです。

ng updateコマンド

早速ですがAngularCLIng updateコマンドを実行します。
すると下記のリストがでてきました。
今回はcdkclicorematerialrxjsのほぼ全部のバージョンアップが必要そうです。

ng update
The installed local Angular CLI version is older than the latest stable version.
Installing a temporary version to perform the update.
Installing packages for tooling via npm.
Installed packages for tooling via npm.
Using package manager: 'npm'
Collecting installed dependencies...
Found 39 dependencies.
    We analyzed your package.json, there are some packages to update:

      Name                               Version                  Command to update
     --------------------------------------------------------------------------------
      @angular/cdk                       10.1.0 -> 11.0.0         ng update @angular/cdk
      @angular/cli                       10.0.3 -> 11.0.2         ng update @angular/cli
      @angular/core                      10.0.4 -> 11.0.2         ng update @angular/core
      @angular/material                  10.1.0 -> 11.0.0         ng update @angular/material
      rxjs                               6.6.0 -> 6.6.3           ng update rxjs

    There might be additional packages which don't provide 'ng update' capabilities that are outdated.
    You can update the addition packages by running the update command of your package manager.

実際にバージョンアップするコマンドですが、上のリストの最後右端に書いてあります。
コマンドを実行する順番はcoreが最初で、次clicdk、そしてmaterial、最後にrxjsがこれまでの経験的に良い気がします。
しかし今回は最初にcoreだと警告が出てしまい、順番を変えてcliから先にしました。
この辺の違いをわたしよくわかっていないですねぇ。

ちなみに下がcoreの時の警告です。
こういうメッセージがでたら焦らずに皆さんもupdateの順番を変えてみてください。
--forceのオプションをつけて実行しろとも書いてありますが、どうしてもできないときでいいと思います。

ng update @angular/core
The installed local Angular CLI version is older than the latest stable version.
Installing a temporary version to perform the update.
Installing packages for tooling via npm.
Installed packages for tooling via npm.
Using package manager: 'npm'
Collecting installed dependencies...
Found 39 dependencies.
Fetching dependency metadata from registry...
                  Package "@angular-devkit/build-angular" has an incompatible peer dependency to "typescript" (requires ">=3.9 < 3.10", would install "4.0.5").
× Migration failed: Incompatible peer dependencies found.
Peer dependency warnings when installing dependencies means that those dependencies might not work correctly together.
You can use the '--force' option to ignore incompatible peer dependencies and instead address these warnings later.   
  See "C:\Users\tetsu\AppData\Local\Temp\ng-KpdYdZ\angular-errors.log" for further details.

バージョンアップ実施

angular/cliのバージョンアップ

まず最初にCLIをバージョンアップします。
ng update @angular/cli

ng update @angular/cli
The installed local Angular CLI version is older than the latest stable version.
Installing a temporary version to perform the update.
Installing packages for tooling via npm.
Installed packages for tooling via npm.
Using package manager: 'npm'
Collecting installed dependencies...
Found 39 dependencies.
Fetching dependency metadata from registry...
    Updating package.json with dependency @angular-devkit/build-angular @ "0.1100.2" (was "0.1000.3")...
    Updating package.json with dependency @angular/cli @ "11.0.2" (was "10.0.3")...
    Updating package.json with dependency @angular/compiler-cli @ "11.0.2" (was "10.0.4")...
    Updating package.json with dependency @angular/language-service @ "11.0.2" (was "10.0.4")...
    Updating package.json with dependency karma @ "5.1.1" (was "5.0.9")...
    Updating package.json with dependency typescript @ "4.0.5" (was "3.9.7")...
    Updating package.json with dependency @angular/animations @ "11.0.2" (was "10.0.4")...
    Updating package.json with dependency @angular/common @ "11.0.2" (was "10.0.4")...
    Updating package.json with dependency @angular/compiler @ "11.0.2" (was "10.0.4")...
    Updating package.json with dependency @angular/core @ "11.0.2" (was "10.0.4")...
    Updating package.json with dependency @angular/forms @ "11.0.2" (was "10.0.4")...
    Updating package.json with dependency @angular/platform-browser @ "11.0.2" (was "10.0.4")...
    Updating package.json with dependency @angular/platform-browser-dynamic @ "11.0.2" (was "10.0.4")...
    Updating package.json with dependency @angular/router @ "11.0.2" (was "10.0.4")...
  UPDATE package.json (1684 bytes)
√ Packages installed successfully.
** Executing migrations of package '@angular/cli' **

> Removing "Solution Style" TypeScript configuration file support.
  DELETE tsconfig.base.json
  UPDATE tsconfig.json (569 bytes)
  UPDATE tsconfig.app.json (290 bytes)
  UPDATE tsconfig.spec.json (288 bytes)
  UPDATE e2e/tsconfig.json (230 bytes)
  Migration completed.

> Replace deprecated library builder '@angular-devkit/build-ng-packagr'.
  Migration completed.

> Add 'declarationMap' compiler options for non production library builds.
  Migration completed.

> Remove deprecated options from 'angular.json' that are no longer present in v11.
  UPDATE angular.json (4278 bytes)
  Migration completed.

> Update workspace dependencies to match a new v11 project.
  UPDATE package.json (1685 bytes)
√ Packages installed successfully.
  Migration completed.

** Executing migrations of package '@angular/core' **

> In Angular version 11, the type of `AbstractControl.parent` can be `null` to reflect the runtime value more accurately.
  This migration automatically adds non-null assertions to existing accesses of the `parent` property on types like `FormControl`, `FormArray` and `FormGroup`.
  Migration completed.

> ViewEncapsulation.Native has been removed as of Angular version 11.
  This migration replaces any usages with ViewEncapsulation.ShadowDom.
  Migration completed.

> NavigationExtras omissions migration.
  In version 11, some unsupported properties were omitted from the `extras` parameter of the `Router.navigateByUrl` and `Router.createUrlTree` methods.
  Migration completed.

> Updates the `initialNavigation` property for `RouterModule.forRoot`.
  Migration completed.

> NavigationExtras.preserveQueryParams has been removed as of Angular version 11.
   This migration replaces any usages with the appropriate assignment of the queryParamsHandling key.
  Migration completed.

> The default value for `relativeLinkResolution` is changing from 'legacy' to 'corrected'.
This migration updates `RouterModule` configurations that use the default value to 
now specifically use 'legacy' to prevent breakages when updating.
  UPDATE src/app/app-routing.module.ts (2120 bytes)
  Migration completed.

> `async` to `waitForAsync` migration.
  The `async` testing function has been renamed to `waitForAsync` to avoid confusion with the native `async` keyword.
  UPDATE src/app/app.component.spec.ts (2120 bytes)
  UPDATE src/app/core/components/error-messaging/error-messaging.component.spec.ts (2219 bytes)
  UPDATE src/app/core/components/loading/loading.component.spec.ts (1732 bytes)
  UPDATE src/app/core/components/mat-date-picker/mat-date-picker.component.spec.ts (3059 bytes)
  UPDATE src/app/core/components/success-messaging/success-messaging.component.spec.ts (2018 bytes)
  UPDATE src/app/core/components/yes-no-dialog/yes-no-dialog.component.spec.ts (1112 bytes)
  UPDATE src/app/pages/components/product-listing-page/product-listing-page.component.spec.ts (17363 bytes)
  UPDATE src/app/pages/components/product-registering-page/product-registering-page-edit.component.spec.ts (25442 bytes)
  UPDATE src/app/pages/components/product-registering-page/product-registering-page-new.component.spec.ts (28742 bytes)
  UPDATE src/app/pages/components/purchase-history-listing-page/purchase-history-listing-page.component-clear.spec.ts (7167 bytes)
  UPDATE src/app/pages/components/purchase-history-listing-page/purchase-history-listing-page.component.spec.ts (13654 bytes)
  UPDATE src/app/pages/components/sign-in-page/sign-in-page.component.spec.ts (7720 bytes)
  UPDATE src/app/pages/components/stock-registering-page/stock-registering-page.component.spec.ts (21791 bytes)
  UPDATE src/app/shared/components/footer/footer.component.spec.ts (795 bytes)
  UPDATE src/app/shared/components/header/header.component.spec.ts (4596 bytes)
  UPDATE src/app/shared/components/sidenav/sidenav.component.spec.ts (3605 bytes)
  UPDATE src/app/super-user-pages/dummy-purchasing-page/dummy-purchasing-page.component.spec.ts (25496 bytes)
  Migration completed.

CLIのバージョンアップでの変更点

CLIをバージョンアップすると2種類のコードが変更されました。
1つ目は「AppRoutingModule」です。
バージョンアップ前

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

バージョンアップ後

@NgModule({
  imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
  exports: [RouterModule]
})

 importsの中に{ relativeLinkResolution: 'legacy' }が追加になりました。
日本語リファレンスを見るとRouterバグフィックスとのこと。
必要かどうかV11で新規プロジェクトを作ってみたところCLIが自動で作った「AppRoutingModule」には { relativeLinkResolution: 'legacy' }は含まれていませんでした。
特に動作に問題が出ていなければ不要と思い、上段の方のコードに戻しました。

もう一つはcomponentのテストクラスです。

beforeEach(async(() => {

のところが、バージョンアップした後は下記のようになりました。

beforeEach(waitForAsync(() => {

使用するメソッドがasync()からwaitForAsync()に変わったようです。
こちらもV11でコマンドで新規にcomponentを作ってみます。
すると下記のようにasync ()はまだ使われていて、下の行にawaitが追加されたcomponentのテストコードができました。
あとかっこのネストが一つ減りました。

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [ExampleComponent]
  }).compileComponents();
  router = TestBed.inject(Router);
});

というわけでV11で新規に作った場合に合わせることにして、waitForAsyncに変わったところはasync ()awaitの組み合わせに変えました。

angular/coreのバージョンアップ

次は最初に警告が出たcoreです。
ng update @angular/core

ng update @angular/core
Using package manager: 'npm'
Collecting installed dependencies...
Found 39 dependencies.
Fetching dependency metadata from registry...
Package '@angular/core' is already up to date.

今度は問題なく上がりました。

angular/materialのバージョンアップ

次はmaterialを上げます。
ng update @angular/material

ng update @angular/material
Using package manager: 'npm'
Collecting installed dependencies...
Found 39 dependencies.
Fetching dependency metadata from registry...
    Updating package.json with dependency @angular/cdk @ "11.0.0" (was "10.1.0")...
    Updating package.json with dependency @angular/material @ "11.0.0" (was "10.1.0")...
  UPDATE package.json (1684 bytes)
√ Packages installed successfully.
** Executing migrations of package '@angular/cdk' **

> Updates the Angular CDK to v11.
    
      ✓  Updated Angular CDK to version 11

  Migration completed.

** Executing migrations of package '@angular/material' **

> Updates Angular Material to v11.
    
    ⚠  General notice: The HammerJS v9 migration for Angular Components is not able to migrate tests. Please manually clean up tests in your project if they rely on HammerJS.
    Read more about migrating tests: https://git.io/ng-material-v9-hammer-migrate-tests
    
      ✓  Updated Angular Material to version 11

  Migration completed.

こちらも良い感じです。

angular/cdkのバージョンアップ

次はcdkを上げます。
ng update @angular/cdk

ng update @angular/cdk
Using package manager: 'npm'
Collecting installed dependencies...
Found 39 dependencies.
Fetching dependency metadata from registry...
Package '@angular/cdk' is already up to date.

もうバージョンが上がっているとのこと、特に問題ないです。

rxjsのバージョンアップ

最後にrxjsを上げます。
ng update rxjs

ng update rxjs
Using package manager: 'npm'
Collecting installed dependencies...
Found 39 dependencies.
Fetching dependency metadata from registry...
    Updating package.json with dependency rxjs @ "6.6.3" (was "6.6.0")...
  UPDATE package.json (1684 bytes)
√ Packages installed successfully.

こちらも問題なしですね。

GlobalのAngularをバージョンアップ

わたしはGlobalの方のAngularをバージョンアップするのをしばしば忘れます。
localだけで動くAngularをお使いの方は関係ありませんが、Globalもある方はお忘れなく😎
わたしはいったん消して最新をインストールしなおす感じです。
真ん中のnpm cache verifyの代わりにnpm cache clean --forceコマンドを実行する方もいるようです。

npm uninstall -g @angular/cli
npm cache verify
npm install -g @angular/cli@latest

動作確認(Unitテスト)

バージョンアップが終わったのでUnitテストを実行しようとしたらエラーで動きません。
カバレッジ関連のようですが、これまでに使っていたkarma-coverage-istanbul-reporterが非推奨になり、 バージョン11からはkarma-coverageを使うようになってました。
あとkarma.conf.jsの内容も変わるようです。

ng test
'karma-coverage-istanbul-reporter' usage has been deprecated since version 11.
Please install 'karma-coverage' and update 'karma.conf.js.' For more info, see https://github.com/karma-runner/karma-coverage/blob/master/README.md
Compiling @angular/core : es2015 as esm2015
Compiling @angular/cdk/keycodes : es2015 as esm2015
Compiling @angular/animations : es2015 as esm2015
Compiling @angular/compiler/testing : es2015 as esm2015
Compiling @angular/common : es2015 as esm2015
Compiling @angular/animations/browser : es2015 as esm2015
Compiling @angular/cdk/observers : es2015 as esm2015
~ 以下略 ~

karma-coverageのインストール

そこでカルマカバレッジをインストールします。
こちらのコマンドです。
npm install karma karma-coverage --save-dev

npm install karma karma-coverage --save-dev
npm WARN codelyzer@6.0.0 requires a peer of @angular/compiler@>=2.3.1 <11.0.0 || >9.0.0-beta <11.0.0 || >9.1.0-beta <11.0.0 || >9.2.0-beta <11.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN codelyzer@6.0.0 requires a peer of @angular/core@>=2.3.1 <11.0.0 || >9.0.0-beta <11.0.0 || >9.1.0-beta <11.0.0 || >9.2.0-beta <11.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN ngx-translate-testing@5.0.0 requires a peer of @angular/common@^10.0.0-rc.0 || >=10.0.0 <11.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN ngx-translate-testing@5.0.0 requires a peer of @angular/core@^10.0.0-rc.0 || >=10.0.0 <11.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ karma@5.1.1
+ karma-coverage@2.0.3
added 3 packages from 95 contributors, removed 1 package, updated 1 package and audited 1540 packages in 19.373s

77 packages are looking for funding
  run `npm fund` for details

karma.conf.jsの変更点

こちらは変更前の「karma.conf.js」です。
「karma-coverage-istanbul」の関連がV11でなくなった模様です。

// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'), // ←なくなる
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client: {
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    coverageIstanbulReporter: { // ←なくなる
      dir: require('path').join(__dirname, './coverage/product-manage-site-for-hands-on'), // ←なくなる
      reports: ['html', 'lcovonly', 'text-summary'], // ←なくなる
      fixWebpackSourcePaths: true // ←なくなる
    }, // ←なくなる
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false,
    restartOnFileChange: true
  });
};

変更後の「karma.conf.js」はこちらです。
V11で新規プロジェクトを作成してCLIが自動作成した「karma.conf.js」をそのまま自分のに上書きしました✨

// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage'),
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client: {
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    jasmineHtmlReporter: { // ←追加される
      suppressAll: true // removes the duplicated traces // ←追加される
    }, // ←追加される
    coverageReporter: { // ←追加される
      dir: require('path').join(__dirname, './coverage/product-manage-site-for-hands-on'), // ←追加される
      subdir: '.', // ←追加される
      reporters: [ // ←追加される
        { type: 'html' }, // ←追加される
        { type: 'text-summary' } // ←追加される
      ] // ←追加される
    }, // ←追加される
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false,
    restartOnFileChange: true
  });
};

E2Eテストの確認

E2Eテストも問題なく動きました。

バージョン確認

最後にAngularのバージョンを確認してみます。
ng version

ng version

     _                      _                 ____ _     ___ 
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | | 
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | | 
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 11.0.2
Node: 12.18.1
OS: win32 x64

Angular: 11.0.2
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1100.2
@angular-devkit/build-angular   0.1100.2
@angular-devkit/core            11.0.2
@angular-devkit/schematics      11.0.2
@angular/cdk                    11.0.1
@angular/material               11.0.1
@schematics/angular             11.0.2
@schematics/update              0.1100.2
rxjs                            6.6.3
typescript                      4.0.5

良かったです、11 に上がってます。

今日の感想


V4あたりのころからAngularのバージョンアップに悩まされてきたので、ちょっとやそっとのことでは困らなくなってきました。
V11ではすこし既存ソースの修正が多かったように感じます。
それでもUnitテストとE2Eテストを準備しておけば、それなりに安心してバージョンアップできるかなぁと思います。

もう年末ですね、わたしは今年の3月から在宅勤務中ですが、来年もしばらくは在宅のままになりそうです。 では来年もよろしくお願いします。