<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Suguru Inatomi</title>
    <description>The latest articles on DEV Community by Suguru Inatomi (@lacolaco).</description>
    <link>https://dev.to/lacolaco</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F43285%2F95a227fc-3a13-49c5-bbca-0cce957e339a.png</url>
      <title>DEV Community: Suguru Inatomi</title>
      <link>https://dev.to/lacolaco</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lacolaco"/>
    <language>en</language>
    <item>
      <title>Building Browser Extensions with WXT + Angular</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Mon, 12 Jan 2026 09:08:00 +0000</pubDate>
      <link>https://dev.to/lacolaco/building-browser-extensions-with-wxt-angular-kfj</link>
      <guid>https://dev.to/lacolaco/building-browser-extensions-with-wxt-angular-kfj</guid>
      <description>&lt;p&gt;I created a starter template for developing browser extensions by combining WXT and Angular. You can efficiently develop extensions for multiple browsers including Chrome and Firefox using Angular’s latest features.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/lacolaco" rel="noopener noreferrer"&gt;
        lacolaco
      &lt;/a&gt; / &lt;a href="https://github.com/lacolaco/wxt-angular-starter" rel="noopener noreferrer"&gt;
        wxt-angular-starter
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Browser extension starter template using WXT and Angular
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;WXT + Angular Starter&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A browser extension starter template using &lt;a href="https://wxt.dev/" rel="nofollow noopener noreferrer"&gt;WXT&lt;/a&gt; and &lt;a href="https://angular.dev/" rel="nofollow noopener noreferrer"&gt;Angular&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Angular 21&lt;/strong&gt; with zoneless change detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS v4&lt;/strong&gt; for styling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WXT&lt;/strong&gt; for cross-browser extension development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vite 7&lt;/strong&gt; powered build system&lt;/li&gt;
&lt;li&gt;TypeScript with strict mode&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Clone the repository&lt;/span&gt;
git clone https://github.com/user/wxt-angular-starter.git
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; wxt-angular-starter

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Install dependencies&lt;/span&gt;
pnpm install

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Start development server (Chrome)&lt;/span&gt;
pnpm dev

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Start development server (Firefox)&lt;/span&gt;
pnpm dev:firefox&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Available Scripts&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Script&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm dev&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start dev server for Chrome&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm dev:firefox&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start dev server for Firefox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build for Chrome&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm build:firefox&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build for Firefox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm zip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build and package for Chrome&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm zip:firefox&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build and package for Firefox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm compile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Type-check without emitting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Project Structure&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;├── entrypoints/
│   ├── popup/          # Angular popup entrypoint
│   │   ├── index.html
│   │   ├── main.ts     # Angular bootstrap
│   │   ├── app.ts      # Root component
│   │   └── style.css&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/lacolaco/wxt-angular-starter" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;h2&gt;
  
  
  What is WXT
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://wxt.dev/" rel="noopener noreferrer"&gt;https://wxt.dev/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WXT&lt;/strong&gt; is a framework that streamlines browser extension development. Built on Vite, it provides a comfortable development experience with fast HMR (Hot Module Replacement) and a file-based manifest auto-generation system.&lt;/p&gt;

&lt;p&gt;Particularly useful is its ability to generate extensions for multiple browsers including Chrome, Firefox, Edge, and Safari from a single codebase. It supports both Manifest V2 and V3, absorbing browser-specific differences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Browser Extensions with Angular
&lt;/h2&gt;

&lt;p&gt;For the UI part of browser extensions, you’ll be loading HTML. WXT officially supports several libraries. When you run the &lt;code&gt;wxt init&lt;/code&gt; command, you can choose templates like Vanilla, React, or Vue, but there’s no Angular template yet. However, the setup isn’t too difficult - you can simply configure Angular on top of the Vanilla base.&lt;/p&gt;

&lt;p&gt;Note that to run Angular with Vite, you need the &lt;code&gt;@analogjs/vite-plugin-angular&lt;/code&gt; plugin. This plugin is provided by the AnalogJS project and enables Angular to work within the Vite ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@analogjs/vite-plugin-angular" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@analogjs/vite-plugin-angular&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;The starter template has the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── entrypoints/
│ ├── popup/ # Angular popup interface
│ │ ├── index.html
│ │ ├── main.ts # Angular bootstrap
│ │ ├── app.ts # Root component
│ │ └── style.css # Tailwind CSS
│ ├── background.ts # Background script
│ └── content.ts # Content script
├── wxt.config.ts # WXT configuration
├── tsconfig.json # Base TypeScript config
└── [tsconfig.app](http://tsconfig.app/).json # Angular-specific config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In WXT, manifests are automatically generated from files in the &lt;code&gt;entrypoints&lt;/code&gt; directory. The &lt;code&gt;popup&lt;/code&gt; directory serves as the entry point for the Angular application, while &lt;code&gt;background.ts&lt;/code&gt; and &lt;code&gt;content.ts&lt;/code&gt; can be written in plain TypeScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup Steps
&lt;/h2&gt;

&lt;p&gt;Here are the steps to build from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Initialize WXT Project
&lt;/h3&gt;

&lt;p&gt;First, create a WXT project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm dlx wxt@latest init my-extension
cd my-extension
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install Dependencies
&lt;/h3&gt;

&lt;p&gt;Install Angular core and build tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Angular core
pnpm add @angular/core @angular/common @angular/compiler @angular/platform-browser rxjs

# Build tools
pnpm add -D @analogjs/vite-plugin-angular @angular/build @angular/compiler-cli

# Tailwind CSS (optional)
pnpm add -D tailwindcss @tailwindcss/vite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Pin Vite Version
&lt;/h3&gt;

&lt;p&gt;Since &lt;code&gt;@analogjs/vite-plugin-angular&lt;/code&gt; requires Vite 7.x, pin the version in &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "pnpm": {
    "overrides": {
      "vite": "^7.3.0"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After adding this, run &lt;code&gt;pnpm install&lt;/code&gt; to apply the version.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Configure WXT
&lt;/h3&gt;

&lt;p&gt;Configure Vite plugins in &lt;code&gt;wxt.config.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig } from 'wxt';
import angular from '@analogjs/vite-plugin-angular';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  vite: () =&amp;gt; ({
    resolve: {
      mainFields: ['module'], // Prioritize ESM
    },
    plugins: [
      angular({
        tsconfig: '[tsconfig.app](http://tsconfig.app/).json',
        // Limit Angular compilation to specific entrypoints
        transformFilter: (_code: string, id: string) =&amp;gt; {
          return id.includes('/entrypoints/popup/');
        },
      }),
      tailwindcss(),
    ],
  }),
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key is the &lt;code&gt;transformFilter&lt;/code&gt; configuration. This ensures that only files in the &lt;code&gt;entrypoints/popup/&lt;/code&gt; directory are processed by the Angular compiler. Background and content scripts are treated as plain TypeScript, allowing coexistence of code that doesn’t use Angular.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Configure TypeScript
&lt;/h3&gt;

&lt;p&gt;Separate project-wide configuration from Angular-specific configuration.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tsconfig.json&lt;/code&gt; (project-wide):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "extends": "./.wxt/tsconfig.json",
  "compilerOptions": {
    "experimentalDecorators": true,
    "useDefineForClassFields": false
  },
  "angularCompilerOptions": {
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;tsconfig.app.json&lt;/code&gt; (Angular-specific):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2022",
    "moduleResolution": "bundler",
    "lib": ["ES2022", "DOM"],
    "strict": true,
    "experimentalDecorators": true,
    "useDefineForClassFields": false,
    "skipLibCheck": true,
    "isolatedModules": true
  },
  "angularCompilerOptions": {
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  },
  "include": ["entrypoints/popup/**/*.ts"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;include&lt;/code&gt; limits the files processed by the Angular compiler. If you want to use Angular in other entrypoints like options pages, add them here.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Create Angular Popup
&lt;/h3&gt;

&lt;p&gt;Finally, create the entry point for the Angular application.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;entrypoints/popup/index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;My Extension&amp;lt;/title&amp;gt;
    &amp;lt;meta name="manifest.type" content="browser_action" /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;app-root&amp;gt;&amp;lt;/app-root&amp;gt;
    &amp;lt;script type="module" src="./main.ts"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;entrypoints/popup/main.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import './style.css';
import { bootstrapApplication } from '@angular/platform-browser';
import { provideZonelessChangeDetection } from '@angular/core';
import { App } from './app';

bootstrapApplication(App, {
  providers: [provideZonelessChangeDetection()],
}).catch((err: unknown) =&amp;gt; console.error(err));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;entrypoints/popup/app.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ChangeDetectionStrategy, Component } from '@angular/core';

@Component({
  selector: 'app-root',
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'block p-4' },
  template: `
    &amp;lt;h1 class="text-lg font-bold"&amp;gt;Hello from Angular!&amp;lt;/h1&amp;gt;
  `,
})
export class App {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;entrypoints/popup/style.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import 'tailwindcss';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we’re now on Angular v21, I’m using &lt;code&gt;provideZonelessChangeDetection()&lt;/code&gt; to enable change detection without Zone.js. In limited environments like browser extensions, Zone.js overhead is often wasteful, so this reduces bundle size and minimizes runtime overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development and Build
&lt;/h2&gt;

&lt;p&gt;Once setup is complete, you can start the development server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Chrome dev server
pnpm dev

# Firefox dev server
pnpm dev:firefox
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqr4g2wuc0ble94sd81iz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqr4g2wuc0ble94sd81iz.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For production builds and packaging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Chrome build
pnpm build

# Firefox build and ZIP
pnpm zip:firefox
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Combining WXT and Angular enables modern browser extension development. The appeal is being able to leverage both WXT’s excellent developer experience and Angular’s powerful features. Using this starter template, you can start development immediately without the setup hassle.&lt;/p&gt;

&lt;p&gt;The repository mentioned at the beginning is published as a GitHub template repository, so if you’re interested, click &lt;strong&gt;Use this template&lt;/strong&gt; on the repository to create your own browser extension.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdb006zis59lv9o6krzr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdb006zis59lv9o6krzr.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>web</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Understanding Angular Ivy Library Compilation</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Wed, 24 Feb 2021 07:13:34 +0000</pubDate>
      <link>https://dev.to/angular/understanding-angular-ivy-library-compilation-246n</link>
      <guid>https://dev.to/angular/understanding-angular-ivy-library-compilation-246n</guid>
      <description>&lt;p&gt;Original Post: &lt;a href="https://blog.lacolaco.net/2021/02/angular-ivy-library-compilation-design-in-depth-en/" rel="noopener noreferrer"&gt;https://blog.lacolaco.net/2021/02/angular-ivy-library-compilation-design-in-depth-en/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, I will explain how to compile Angular libraries with Ivy, which is now possible in Angular v11.1, and its details. The intended audience is those who are developing Angular third-party libraries, or simply interested in Angular’s internal mechanism. You don’t need to know anything in this article to develop Angular applications.&lt;/p&gt;

&lt;p&gt;The content of this article is based on the Design Doc written by the Angular team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.google.com/document/d/148eXrCST6TM7Uo90KxaBrMbOkwJbYrQSQgRaGMK5WRc/edit#" rel="noopener noreferrer"&gt;Ivy Library Compilation - Conceptual Design Doc&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to compile libraries with Ivy
&lt;/h2&gt;

&lt;p&gt;When you develop an Angular library using Angular CLI or something similar, Ivy is currently disabled for production build. It is probably set in a file like &lt;code&gt;src/tsconfig.lib.prod.json&lt;/code&gt; as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"angularCompilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enableIvy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Angular libraries compiled and published to NPM with this configuration are still compatible for use even if the applications are not Ivy-enabled.&lt;/p&gt;

&lt;p&gt;Starting from Angular v11.1, you can experimentally remove compatibility for applications not yet Ivy-enabled, and compile the library optimized for Ivy-enabled applications. To use Ivy compilation for libraries to be published to NPM, configure as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"angularCompilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enableIvy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"compilationMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partial"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;"compilationMode": "partial"&lt;/code&gt; is an important part, and I will explain what it means in the later part of this post. Of course, libraries compiled with this setting can only be used in Ivy-enabled applications, so it is still not currently recommended.&lt;/p&gt;

&lt;p&gt;By the way, for libraries that are only used locally in monorepo, such as Angular CLI and Nrwl/Nx, you can simply use &lt;code&gt;enableIvy: true&lt;/code&gt;. The &lt;code&gt;"compilationMode": "partial"&lt;/code&gt; is required only for the libraries that are published in NPM. This difference is also explained later in this article.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"angularCompilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enableIvy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Terminology
&lt;/h2&gt;

&lt;p&gt;In order to make the following explanations concise, let’s first sort out the terminology.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;term&lt;/th&gt;
&lt;th&gt;meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Angular decorators&lt;/td&gt;
&lt;td&gt;Decorators defined by Angular such as &lt;code&gt;@Component&lt;/code&gt;, &lt;code&gt;@Directive&lt;/code&gt;, and &lt;code&gt;@Injectable&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compiler&lt;/td&gt;
&lt;td&gt;The Angular compiler is a tool that analyzes Angular decorators and generates executable code.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ngc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;An executable CLI for the Angular compiler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ivy compiler&lt;/td&gt;
&lt;td&gt;A compiler introduced in Angular v9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View Engine (VE) compiler&lt;/td&gt;
&lt;td&gt;A deprecated compiler that was used by default until Angular v8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Ivy compilation for applications
&lt;/h2&gt;

&lt;p&gt;Before we start talking about libraries, let’s start with compiling an application with Ivy already enabled by default. The Angular decorator in the application will be analyzed by the compiler to generate the executable code based on the extracted metadata.&lt;/p&gt;

&lt;p&gt;Let’s look at an example of compiling a simple component. Suppose we have the following component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-comp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div&amp;gt; Hello! &amp;lt;/div&amp;gt;`&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeComponent&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you compile this code with Ivy, you will get the following JavaScript output. The two points are as follows&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The decorator does not remain in the JavaScript.&lt;/li&gt;
&lt;li&gt;The generated code is inserted as a static field in the component class.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeComponent&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;SomeComponent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ɵcmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ɵɵdefineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selectors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-comp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;ɵɵelementStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;ɵɵtext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; Hello! &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;ɵɵelementEnd&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Ivy compiler generates the code to create the &lt;em&gt;definition&lt;/em&gt; from the metadata contained in the decorator. The HTML template, which was a string, becomes executable code as a &lt;strong&gt;Template Function&lt;/strong&gt;. The &lt;code&gt;ɵɵelementStart&lt;/code&gt; and &lt;code&gt;ɵɵtext&lt;/code&gt; used in the template functions are called &lt;strong&gt;Template Instructions&lt;/strong&gt; , and abstract the concrete DOM API calls and data binding update process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Fivy-app-compilation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Fivy-app-compilation.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angular compilation is internally divided into two steps; Analysis step and code generation step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analysis step
&lt;/h3&gt;

&lt;p&gt;In the analysis step of compilation, it integrates the metadata obtained from the decorators of the entire application and detects the dependencies between components/directives. At this point, the important part is the &lt;code&gt;@NgModule&lt;/code&gt;. It is used to determine the references corresponding to unknown HTML tags and attributes contained in templates. After the analysis step, the compiler gets the following information.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which components depend on which directives/components&lt;/li&gt;
&lt;li&gt;What dependencies are needed to instantiate each component/directive&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code generation step
&lt;/h3&gt;

&lt;p&gt;In the code generation step, it generates the code for each Angular decorator based on the information obtained in the analysis step. The generated code has two requirements: &lt;strong&gt;Locality&lt;/strong&gt; and &lt;strong&gt;Runtime Compatibility&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Locality
&lt;/h4&gt;

&lt;p&gt;Locality is also expressed as &lt;strong&gt;self-contained&lt;/strong&gt;. It means that all the references needed for compiling the component are included in the component class itself. This makes differential builds more efficient. To make it easier to understand, let’s look back at the issues in the pre-Ivy View Engine days without Locality.&lt;/p&gt;

&lt;p&gt;The VE compiler generated code as a file named &lt;code&gt;*.ngfactory.js&lt;/code&gt; which was independent of the original file. Angular executes this &lt;code&gt;*.ngfactory.js&lt;/code&gt; at runtime, and the generated code refers to the original component class. This approach becomes problematic when a component depends on another component.&lt;/p&gt;

&lt;p&gt;For example, when a component &lt;code&gt;&amp;lt;app-parent&amp;gt;&lt;/code&gt; uses a template to call a component &lt;code&gt;&amp;lt;app-child&amp;gt;&lt;/code&gt;, there is no reference from &lt;code&gt;parent.component.ts&lt;/code&gt; to &lt;code&gt;child.component.ts&lt;/code&gt; as a JavaScript module. This parent-child dependence is only visible between &lt;code&gt;parent.component.ngfactory.js&lt;/code&gt; and &lt;code&gt;child.component.ngfactory.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since the direct compilation result, &lt;code&gt;parent.component.js&lt;/code&gt;, does not refer to either &lt;code&gt;child.component.js&lt;/code&gt; or &lt;code&gt;child.component.ngfactory.js&lt;/code&gt;, it cannot determine when it needs to be recompiled. Therefore, ViewEngine had to recompile the entire application at each build time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Fngfactory-dependency-link.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Fngfactory-dependency-link.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To solve this problem, the Ivy compiler generates the code as a static field of the class. In the generation code, the classes of the directives referenced in the template are included. This makes it easy to determine which files will be affected when that file is changed.&lt;/p&gt;

&lt;p&gt;As you can see, with code generation with Locality, it is only necessary to recompile &lt;code&gt;ParentComponent&lt;/code&gt; when itself or &lt;code&gt;ChildComponent&lt;/code&gt; is changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// parent.component.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChildComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./child.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;ParentComponent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ɵcmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ɵɵdefineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ParentComponent_Template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rf&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;ɵɵelement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app-child&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// Directives depended on by the template&lt;/span&gt;
    &lt;span class="na"&gt;directives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ChildComponent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Runtime compatibility
&lt;/h3&gt;

&lt;p&gt;Another important factor in code generation is runtime compatibility. This is not an issue when compiling an application, but it is critical for compiling a library.&lt;/p&gt;

&lt;p&gt;In an application, the compiler version and the Angular runtime version basically match because the compilation is done at the same time in the application build. However, this is not the same for libraries.&lt;/p&gt;

&lt;p&gt;For libraries published to NPM, it must be considered that the Angular version that compiles the library does not match the Angular version used by the application that uses the library at runtime. A big issue here is the compatibility of the Angular APIs called in the generated code. APIs that existed in the compile-time version may not exist in the runtime version of Angular, or their signatures may have changed. So, &lt;strong&gt;the rules for code generation must be determined by the Angular version of the runtime that executes it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Libraries used locally within monorepo were Ivy compilable because as long as it is in monorepo, it is ensured that the library and the application have the same Angular version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Library compilation
&lt;/h2&gt;

&lt;p&gt;Here is the main topic. First, let’s look at compiling libraries with &lt;code&gt;enableIvy: false&lt;/code&gt;, which is the current recommended setting for v11. Compiling a library with no Ivy is just &lt;strong&gt;inlining the metadata&lt;/strong&gt; collected in the analysis step. The Angular decorator metadata is embedded in the static field as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Flibrary-compilation-ivy-false-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Flibrary-compilation-ivy-false-1.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The library compilation works to convert the metadata into a JavaScript representation that can be published to NPM. However, this is still a metadata and cannot be executed as a component when loaded into an application. It needs to be compiled again based on this metadata. &lt;strong&gt;Angular Compatibility Compiler&lt;/strong&gt; , &lt;code&gt;ngcc&lt;/code&gt;, is the tool to do it.&lt;/p&gt;

&lt;h3&gt;
  
  
  ngcc
&lt;/h3&gt;

&lt;p&gt;As we don’t know whether the application side compiler is Ivy or VE, the only way to keep compatibility is to compile the library code on the application side. This is the reason why &lt;code&gt;ngcc&lt;/code&gt; is run at application build time.&lt;/p&gt;

&lt;p&gt;The compilation result of &lt;code&gt;ngcc&lt;/code&gt; is the same as that of compiling the library directly. The difference is that &lt;code&gt;ngc&lt;/code&gt; uses decorators in TypeScript as metadata, while &lt;code&gt;ngcc&lt;/code&gt; uses &lt;code&gt;.decorators&lt;/code&gt; in JavaScript as metadata.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Flibrary-compilation-ivy-false-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Flibrary-compilation-ivy-false-2.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although &lt;code&gt;ngcc&lt;/code&gt; achieved its purpose to allow libraries to be released to NPM with compatibility, the frequent compilations spoiled the developer experience. Many of you may have felt the frustration of running &lt;code&gt;ngcc&lt;/code&gt; repeatedly every time you installed a library. The &lt;code&gt;ngcc&lt;/code&gt; overwrites the library code in &lt;code&gt;node_modules&lt;/code&gt; installed from NPM and compiles it, so if the contents of &lt;code&gt;node_modules&lt;/code&gt; are changed by the &lt;code&gt;npm install&lt;/code&gt; command, you have to recompile it.&lt;/p&gt;

&lt;p&gt;But originally, &lt;code&gt;ngcc&lt;/code&gt; is a temporary approach until the View Engine support is removed from applications. The Ivy library compiler, which will be explained below, is a new Ivy-native library compilation mechanism that solves the problems clarified by &lt;code&gt;ngcc&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ivy library compilation
&lt;/h3&gt;

&lt;p&gt;The biggest issue with &lt;code&gt;ngcc&lt;/code&gt; was the execution cost of the compilation on the application side. If &lt;code&gt;ngcc&lt;/code&gt; was fast enough, we could have compiled the library just-in-time when the application was compiled, without persisting the compilation results in &lt;code&gt;node_modules&lt;/code&gt;. The execution cost is high, so we want to reduce the number of times and save the results.&lt;/p&gt;

&lt;p&gt;On the other hand, if we finish compiling the library before publishing it, we can build the application faster, but we lose runtime compatibility. The code generation step really needs to be done in the application’s Angular version.&lt;/p&gt;

&lt;p&gt;So Ivy library compilation concept is a set of &lt;strong&gt;mechanism for running only the code generation step rapidly&lt;/strong&gt; after library installation and &lt;strong&gt;mechanism for finishing the analysis step before NPM release&lt;/strong&gt;. The first mechanism is called library &lt;strong&gt;linking&lt;/strong&gt; , and the second mechanism is called &lt;strong&gt;Link-Time Optimization (LTO) compilation&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  LTO compilation (Pre-Publish compilation)
&lt;/h3&gt;

&lt;p&gt;LTO compilation, which is done before publishing to NPM, is a mechanism to complete only the analysis step of the entire compilation and embed the result in JavaScript. As mentioned in the Introduction, when the setting &lt;code&gt;"compilationMode": "partial"&lt;/code&gt; is set, the compiler will perform LTO compilation of the library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"angularCompilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enableIvy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"compilationMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partial"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiled JavaScript contains the following code. It looks similar to the normal compilation result, but the important thing is that the &lt;strong&gt;template is preserved as a string&lt;/strong&gt; and it has &lt;strong&gt;Locality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Flibrary-compilation-ivy-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Flibrary-compilation-ivy-1.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The information obtained from the analysis step is inlined as a &lt;em&gt;declaration&lt;/em&gt;. It includes a list of directives on which it depends, and has a locality that allows it to execute the code generation step with only information in the file. And by deferring the code generation of template functions until they are linked, the library can ensure runtime compatibility.&lt;/p&gt;

&lt;p&gt;Also, the Angular version of the LTO compilation is included. Even if the template is the same, it can be optimized at link time depending on the combination of both the version it is written in and the runtime version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linking libraries
&lt;/h3&gt;

&lt;p&gt;An application that installs an LTO compiled library will link it at the building time just-in-time. The &lt;strong&gt;Linker&lt;/strong&gt; , which does the linking, will generate code based on the declarations from the LTO compilation, and replace them with definitions that can be used by the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Flibrary-compilation-ivy-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-ivy-library-compilation-design-in-depth%2Flibrary-compilation-ivy-2.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unlike &lt;code&gt;ngcc&lt;/code&gt;, which required analysis step, the linking process can be executed independently for each file thanks to Locality of LTO compilation, so it can work as a plugin in module resolution like webpack. In the Angular CLI build, it is implemented as a Babel plugin called &lt;code&gt;AngularLinker&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;The new Ivy library compilation can be summarized as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The library compilation is separated into two parts: before and after NPM release.&lt;/li&gt;
&lt;li&gt;One is the &lt;strong&gt;LTO compile&lt;/strong&gt; process that finishes the decorator analysis before publishing to NPM.&lt;/li&gt;
&lt;li&gt;The other is the &lt;strong&gt;linking&lt;/strong&gt; process, which completes the compilation of the library by generating code at application build time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope this article will help you readers understand how new Ivy library compilation is designed, based on the differences between applications and libraries in compilation, and the issues of &lt;code&gt;ngcc&lt;/code&gt; used today.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>ivy</category>
    </item>
    <item>
      <title>Angular: Using NgRx Store with Redux Toolkit 🚀</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Wed, 16 Dec 2020 12:09:31 +0000</pubDate>
      <link>https://dev.to/lacolaco/angular-using-ngrx-store-with-redux-toolkit-5467</link>
      <guid>https://dev.to/lacolaco/angular-using-ngrx-store-with-redux-toolkit-5467</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Original Post: &lt;a href="https://blog.lacolaco.net/2020/12/angular-using-ngrx-with-redux-toolkit/" rel="noopener noreferrer"&gt;https://blog.lacolaco.net/2020/12/angular-using-ngrx-with-redux-toolkit/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article introduces the idea of combining &lt;a href="https://ngrx.io/guide/store" rel="noopener noreferrer"&gt;&lt;strong&gt;NgRx Store&lt;/strong&gt;&lt;/a&gt;, the de facto standard state management library for Angular applications, with the &lt;a href="https://redux-toolkit.js.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;Redux Toolkit&lt;/strong&gt;&lt;/a&gt;, a library from the Redux team.&lt;/p&gt;

&lt;p&gt;I expect that this will eventually become the solid configuration for Angular applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Redux Toolkit (RTK)?
&lt;/h2&gt;

&lt;p&gt;If you are already familiar with the Redux Toolkit, you can find it in the following “NgRx Store with RTK” section.&lt;/p&gt;

&lt;p&gt;The Redux Toolkit ( &lt;strong&gt;RTK&lt;/strong&gt; ) is the official library of the Redux development team. It provides best practices that match real-world use cases to make it easier and more effective for anyone to use Redux. A major theme of RTK is the reduction of cumbersome boilerplate code that has frequently occurred in Redux in the past. You can get a good overview of this through the Redux Toolkit Basic Tutorial. It is recommended that you read through it first.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://redux-toolkit.js.org/tutorials/basic-tutorial" rel="noopener noreferrer"&gt;https://redux-toolkit.js.org/tutorials/basic-tutorial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ability to create Actions, Action Creators, Reducers, etc. with creating functions is also effective in reducing the existing boilerplate, but the most important thing is the last &lt;code&gt;createSlice&lt;/code&gt; function. Just by looking at the code sample, you can see that the API is quite different from the impression of Redux so far, and the amount of code can be reduced considerably.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://redux-toolkit.js.org/tutorials/basic-tutorial#introducing-createslice" rel="noopener noreferrer"&gt;https://redux-toolkit.js.org/tutorials/basic-tutorial#introducing-createslice&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;increment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the future, Redux will basically be based on this Slice. Most of the existing Redux logic should be able to be solved by &lt;code&gt;createSlice()&lt;/code&gt;, unless you are using it in a very complex way.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This API is the standard approach for writing Redux logic. (&lt;a href="https://redux-toolkit.js.org/api/createSlice" rel="noopener noreferrer"&gt;https://redux-toolkit.js.org/api/createSlice&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The concept of Slice is a new one created by the Redux Toolkit, but its essence is not entirely new. Here is a detailed explanation of Slice.&lt;/p&gt;

&lt;h3&gt;
  
  
  The concept of Slice
&lt;/h3&gt;

&lt;p&gt;“Slice” is an object that encapsulates the Reducer and Action Creators created under the namespace.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;createSlice returns a “slice” object that contains the generated reducer function as a field named reducer, and the generated action creators inside an object called actions. (&lt;a href="https://redux-toolkit.js.org/tutorials/basic-tutorial" rel="noopener noreferrer"&gt;https://redux-toolkit.js.org/tutorials/basic-tutorial&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Creating a slice&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// Auto-generated reducer and action creators&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; Action { type: 'counter/increment' }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are familiar with the Redux &lt;a href="https://github.com/erikras/ducks-modular-redux" rel="noopener noreferrer"&gt;“ducks” pattern&lt;/a&gt;, you will feel a sense of déjà vu when you see Slice, which is the exact representation of the ducks pattern as a type of object. The ducks pattern can be easily implemented by simply exporting each property individually from the return value of &lt;code&gt;createSlice()&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thanks to createSlice, we already have our action creators and the reducer right here in one file. All we have to do is export them separately, and our todos slice file now matches the common “ducks” pattern. (&lt;a href="https://redux-toolkit.js.org/tutorials/intermediate-tutorial" rel="noopener noreferrer"&gt;https://redux-toolkit.js.org/tutorials/intermediate-tutorial&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ducks pattern exports&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason why it is called “Slice” will become clearer when we apply multiple Slices to a single Store. To combine multiple Slices, we will continue to use the &lt;code&gt;combineReducers&lt;/code&gt; function. The Slice is the combination of &lt;code&gt;[name]: namedReducer&lt;/code&gt; in this combine step. Each slice is a thin layer of the whole reducer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-using-ngrx-with-redux-toolkit%2Fslices.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.lacolaco.net%2Fimg%2Fangular-using-ngrx-with-redux-toolkit%2Fslices.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There have been various approaches to dividing the Reducer in this way, and the ducks pattern has been popular. It creates modules that are scoped by namespaces while ensuring atomic state updates through centralized state management infrastructure. The reason why RTK and &lt;code&gt;createSlice()&lt;/code&gt; should be used is that it is easy and anyone can implement the scalable Redux best practices in the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  NgRx Store with RTK
&lt;/h2&gt;

&lt;p&gt;Redux is a framework-agnostic library. But why NgRx Store is widely used for Angular app state management instead of plain Redux?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Because it’s easy to set up in Angular’s DI.&lt;/li&gt;
&lt;li&gt;Because they want to manage state changes with RxJS (Observable)&lt;/li&gt;
&lt;li&gt;Because they want to use TypeScript’s type checking&lt;/li&gt;
&lt;li&gt;Because it requires less boilerplate code than plain Redux&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RTK can also solve the needs of TypeScript-friendliness and simplicity of description, and it also has the sense of security of being a Redux official. So, by using NgRx Store with RTK, we can write state management logic that blends naturally into Angular applications while benefiting from the Redux ecosystem. This is the starting point of my idea, and I am confident that it will work.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;StoreModule.forFeature()&lt;/code&gt; and Slice
&lt;/h3&gt;

&lt;p&gt;In NgRx Store, you can create a “Feature State” by using &lt;code&gt;StoreModule.forFeature()&lt;/code&gt; for lazy loading or simply for separation of concerns. For applications of a large size, it is common to modularize them into Feature States instead of managing everything in the Root State.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;counterFeatureKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./state/counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;StoreModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forFeature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterFeatureKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a Feature State, you need a string that is the key to distinguish the Feature and a Reducer function corresponding to the Feature State. And as mentioned earlier, RTK’s Slice has the same information. In other words, Feature State and Slice are both APIs aimed at modularizing state management, and their essence is almost the same.&lt;/p&gt;

&lt;p&gt;By the way, NgRx Store is a state management library for Angular, based on RxJS, but its core is strongly inspired by Redux.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Store is RxJS powered global state management for Angular applications, inspired by Redux. (&lt;a href="https://ngrx.io/guide/store" rel="noopener noreferrer"&gt;https://ngrx.io/guide/store&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not only the idea but also the interface of Action and Reducer, the principle part of Redux, is the same. So the objects generated by RTK can be directly applied to NgRx Store. In other words, the &lt;strong&gt;key&lt;/strong&gt; and &lt;strong&gt;Reducer&lt;/strong&gt; required for the Feature State can be generated by Slice.&lt;/p&gt;

&lt;p&gt;I will explain the implementation with a simple example. It is a small application, but it has everything you need to integrate NgRx Store with RTK.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/staging-dust-pg930?module=/src/app/counter/counter-slice.ts"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  0. Setup NgRx Store
&lt;/h3&gt;

&lt;p&gt;First, we need to prepare &lt;code&gt;StoreModule.forRoot()&lt;/code&gt; to make &lt;code&gt;Store&lt;/code&gt; available to components and services. If it is fully modularized, there will be no reducer to pass to &lt;code&gt;forRoot()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;BrowserModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StoreModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;({})],&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Create a counter slice
&lt;/h3&gt;

&lt;p&gt;The first thing to do is to create a Slice. Create &lt;code&gt;counter/counter-slice.ts&lt;/code&gt; and use the &lt;code&gt;createSlice()&lt;/code&gt; function to create a Slice object. That’s almost all the code for state management.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createSlice&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Make a “ducks” module
&lt;/h3&gt;

&lt;p&gt;Based on the Slice created in step 1, we will modularize the Slice according to the ducks pattern: default export for Reducer, named export for Action Creator and other objects. Using object destructuring, we can write like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a preference, so if you don’t find the ducks pattern valuable, you can export the Slice object as is.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.Setup &lt;code&gt;StoreModule.forFeature()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;We will use the object exported from &lt;code&gt;counter-slice.ts&lt;/code&gt; to set the Feature State of NgRx. Just call &lt;code&gt;StoreModule.forFeature()&lt;/code&gt; in &lt;code&gt;counter.module.ts&lt;/code&gt; and pass the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;reducer&lt;/code&gt; of the Slice as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;counterFeatureKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./counter-slice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;StoreModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forFeature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterFeatureKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Creating a Feature selector
&lt;/h3&gt;

&lt;p&gt;In the NgRx Store, it is common to use a Feature Selector to retrieve the Feature State from the &lt;code&gt;Store&lt;/code&gt;. This time, &lt;code&gt;counter-slice.ts&lt;/code&gt; itself will create and export a Feature Selector. The type of the Feature State managed by &lt;code&gt;counterSlice&lt;/code&gt; can be retrieved using &lt;code&gt;ReturnType&amp;lt;typeof reducer&amp;gt;&lt;/code&gt;, thanks to RTK’s strong type inference support.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectFeature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createFeatureSelector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Access to Feature State
&lt;/h3&gt;

&lt;p&gt;Finally, refer to the Feature State from the component, dispatch an Action to update it, and you are done. The code in this area is not affected by the RTK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Store&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ngrx/store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./counter-slice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;button (click)="increment()"&amp;gt;INCREMENT&amp;lt;/button&amp;gt;:
    {{ counter$ | async }}`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// Get state&lt;/span&gt;
  &lt;span class="nx"&gt;counter$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;createSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectFeature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Update state&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advantages and disadvantages
&lt;/h2&gt;

&lt;p&gt;This is a brief summary of the advantages and disadvantages of using NgRx Store with RTK.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantage: minimized boilerplate
&lt;/h3&gt;

&lt;p&gt;Compared to the bare Redux, utilities provided by NgRx such as &lt;code&gt;createReducer&lt;/code&gt; and &lt;code&gt;createAction&lt;/code&gt; simplify the description, while &lt;code&gt;createSlice()&lt;/code&gt; reduces waste to the absolute minimum. It not only reduces the amount of code but also hides the combination of multiple APIs in just one &lt;code&gt;createSlice()&lt;/code&gt;, which is very good in terms of ease of remembering how to use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NgRx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createReducer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ngrx/store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[Counter Component] Increment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_counterReducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;_counterReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// Redux Toolkit&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createSlice&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Advantage: Redux Ecosystem
&lt;/h3&gt;

&lt;p&gt;RTK will become a central part of the Redux ecosystem in the near future, and new projects derived from RTK are emerging. For example, the recently released &lt;a href="https://rtk-query-docs.netlify.app/" rel="noopener noreferrer"&gt;RTK Query&lt;/a&gt; is an experimental library that automates the common Redux use case of fetching data and caching the response. RTK-based state management makes it easier to keep up with the evolution of the Redux ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disadvantage: Increased bundle size
&lt;/h3&gt;

&lt;p&gt;The RTK comes with some middleware by default, so the bundle size should be larger than the plain NgRx Store. Tree-shaking will mitigate this, but the increment will not be zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I had the opportunity to introduce my idea on the interoperability between NgRx Store and RTK.&lt;/p&gt;

&lt;p&gt;I put up an issue on the NgRx GitHub repository suggesting how to improve interoperability with RTK, and the NgRx maintainer was very positive, and also Mark Erikson, the Redux maintainer, showed up and welcomed it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ngrx/platform/issues/2809" rel="noopener noreferrer"&gt;https://github.com/ngrx/platform/issues/2809&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1336804656777932803-373" src="https://platform.twitter.com/embed/Tweet.html?id=1336804656777932803"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1336804656777932803-373');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1336804656777932803&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Since the RTK, the Redux ecosystem seems to be gaining momentum in spreading best practices that match real-world use cases. And I found out that there is an option to delegate the core of state management to the Redux official. I think the role of NgRx in combination with RTK will be to connect Redux with Angular’s DI system and reactive programming with RxJS as a bridge. And I believe that this division of responsibilities will become more important in the future.&lt;/p&gt;

&lt;p&gt;The implementation example presented here is just one idea at the moment, and if you can find a better interoperable implementation pattern, I would love to see NgRx Store + RTK made by others. I’m looking forward to your feedback.&lt;/p&gt;

&lt;p&gt;See you.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>ngrx</category>
      <category>statemanagement</category>
      <category>redux</category>
    </item>
    <item>
      <title>Angular: Eliminate Render Blocking Requests の概要</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Thu, 01 Oct 2020 00:10:06 +0000</pubDate>
      <link>https://dev.to/lacolaco/angular-eliminate-render-blocking-requests-46oa</link>
      <guid>https://dev.to/lacolaco/angular-eliminate-render-blocking-requests-46oa</guid>
      <description>&lt;p&gt;Originally published on &lt;a href="https://blog.lacolaco.net/2020/10/angular-eliminate-render-blocking-requests/" rel="noopener noreferrer"&gt;blog.lacolaco.net&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;この記事では Angular CLI チームで現在進行中の “Eliminate Render Blocking Requests” というプロジェクトについてその内容を解説する。 一次ソースは以下のリンク先を参照されたし。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/angular/angular-cli/issues/18730" rel="noopener noreferrer"&gt;[RFC] Eliminate Render Blocking Requests · Issue #18730 · angular/angular-cli&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/angular/angular-cli/issues/17966" rel="noopener noreferrer"&gt;Eliminate render-blocking resources · Issue #17966 · angular/angular-cli&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  概要
&lt;/h2&gt;

&lt;p&gt;このプロジェクトは Angular アプリケーションが依存する CSS について、 &lt;strong&gt;Render-Blocking&lt;/strong&gt; な HTTP リクエストを無くそうというものである。 Render-Blocking なリソースの除去については web.dev の記事を参考にするとよい。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/render-blocking-resources/" rel="noopener noreferrer"&gt;Eliminate render-blocking resources&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;最初のレンダリングに必要な CSS の読み込み時間がなくなることで First Contentful Paint（FCP）のパフォーマンスが改善される見込みだ。&lt;/p&gt;

&lt;p&gt;Angular CLI チームが RFC（Request For Comments）で 提案したのは次のような手法である。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS ファイルの読み込みの非同期化&lt;/li&gt;
&lt;li&gt;Angular Universal SSR や Pre-rendering、App-Shell、通常のクライアントサイドレンダリングでのクリティカル CSS のインライン化&lt;/li&gt;
&lt;li&gt;Google Fonts と Icons のインライン化&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;これらを Angular CLI で特別な設定無しに利用できるようにすることを目的としている。&lt;/p&gt;

&lt;h2&gt;
  
  
  背景
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ng build&lt;/code&gt; コマンドのビルドに使われる &lt;code&gt;styles&lt;/code&gt; の CSS ファイルは基本的にリセット CSS や Theming など、ページ表示の最初に読み込まれることが期待されている。 しかし CSS は &lt;code&gt;styles.css&lt;/code&gt; のような形でバンドルされ、 &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;タグで読み込むことになるため、この &lt;code&gt;styles.css&lt;/code&gt; が肥大化するとページの First Contentful Paint（FCP）が遅くなる原因になる。 とはいえ &lt;code&gt;styles.css&lt;/code&gt; の内容をすべてインライン化するのは HTML ファイルのペイロードサイズを肥大化させてしまう。&lt;/p&gt;

&lt;p&gt;そこで、本当にクリティカルな CSS だけをインライン化し、残りの部分を非同期化することで FCP を改善しようというのが今回の趣旨である。&lt;/p&gt;

&lt;h2&gt;
  
  
  解決案
&lt;/h2&gt;

&lt;p&gt;これらの手法は Angular CLI に合理的な形で組み込めるかどうかはまだ保証できないが、現時点でのアイデアとして提案されているものであり、確定事項ではない。&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS の非同期読み込み
&lt;/h3&gt;

&lt;p&gt;バンドルされた &lt;code&gt;styles.css&lt;/code&gt; が初期レンダリングに必要のないため CSS の読み込みを待たずにレンダリングを始めてよいことをブラウザに伝える。 具体的には &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; タグの &lt;code&gt;media&lt;/code&gt; 属性を使い、印刷などの特殊なユースケースを除いた通常のユースケースでは読み込みを非同期化する。&lt;/p&gt;

&lt;p&gt;Before&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="stylesheet" href="styles.css" /&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link
  rel="stylesheet"
  href="styles.css"
  media="print"
  onload="this.media='all'"
/&amp;gt;
&amp;lt;noscript&amp;gt;&amp;lt;link rel="stylesheet" href="styles.css" /&amp;gt;&amp;lt;/noscript&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;参考: &lt;a href="https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-blocking-css" rel="noopener noreferrer"&gt;レンダリング ブロック CSS  |  Web  |  Google Developers&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS Files Budget
&lt;/h3&gt;

&lt;p&gt;CSS のダウンロードやパースの時間を短縮するため、ファイルサイズに関する新たな Budget を追加する。 実際には参照されないデッドコードの除去や、グローバル CSS ではなく適切なコンポーネントのスタイルへの移動などを促進する。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;anyStyle&lt;/code&gt;: 外部 CSS ファイル個別のサイズ&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allStyle&lt;/code&gt;: すべての外部 CSS ファイルの累計サイズ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;すでに存在する&lt;code&gt;anyComponentSyle&lt;/code&gt; はコンポーネント CSS のファイルサイズを対象としているので全く別物である。&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Fonts と Icons のインライン化
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;https://fonts.googleapis.com/&lt;/code&gt; から最初にダウンロードするフォント読み込みの CSS をインライン化することで HTTP リクエストのラウンドトリップを削減する。 これまでは CSS の読み込みのあとに &lt;code&gt;woff&lt;/code&gt; などのフォントファイルの読み込みが行われていたが、フォントファイルの読み込みだけになる。 また、Angular CLI が参照する browserslist の設定に基づいて最適なフォントフォーマットの決定も自動的に行われる。&lt;/p&gt;

&lt;p&gt;Before&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link
  rel="stylesheet"
  href="https://fonts.googleapis.com/icon?family=Material+Icons"
/&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;style&amp;gt;
  @font-face {
    font-family: 'Material Icons';
    font-style: normal;
    font-weight: 400;
    src: url(https://fonts.gstatic.com/s/materialicons/v55/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2)
      format('woff2');
  }

  .material-icons {
    font-family: 'Material Icons';
    font-weight: normal;
    font-style: normal;
    font-size: 24px;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    white-space: nowrap;
    word-wrap: normal;
    direction: ltr;
  }
&amp;lt;/style&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  クリティカル CSS の抽出
&lt;/h3&gt;

&lt;p&gt;Render-Blocking な CSS だけをインライン化するためには CSS を解析してその部分だけを抽出する必要がある。 これをすでに実現しているプロジェクトとして、&lt;a href="https://github.com/pocketjoso/penthouse" rel="noopener noreferrer"&gt;penthouse&lt;/a&gt;や&lt;a href="https://github.com/GoogleChromeLabs/critters" rel="noopener noreferrer"&gt;critters&lt;/a&gt;、&lt;a href="https://github.com/addyosmani/critical" rel="noopener noreferrer"&gt;critical&lt;/a&gt;などがある。 これらはアプリケーションを一度レンダリングし、そこで参照されたクリティカル CSS を抽出する方法をとっている。&lt;/p&gt;

&lt;p&gt;Google Chrome チームが開発している critters は抽出のためのレンダリングにヘッドレスブラウザではなく JSDOM を用いており、 ビルド時だけでなくランタイムで動作させる選択肢としては上述のツールの中で最適であると考えられる。 ただし、critters は viewport を予測せず、ドキュメントに読み込まれたすべての CSS をインライン化してしまうトレードオフがある。&lt;/p&gt;

&lt;p&gt;また、Angular アプリケーションのユースケースにおいてそれぞれの課題を挙げている。&lt;/p&gt;

&lt;h4&gt;
  
  
  Angular Universal (SSR)
&lt;/h4&gt;

&lt;p&gt;critters は webpack プラグインであるため、Node.js サーバー上で動的にビルドする Angular Universal は利用できない。 したがって、Universal を考慮すれば critters のコア機能だけを Node.js 向けに切り出したものが必要になるだろう。 うまく実現できれば、Universal でビルドした HTML の中にクリティカル CSS をインライン化してクライアントに返すことができる。&lt;/p&gt;

&lt;h4&gt;
  
  
  App-Shell / Pre-rendering
&lt;/h4&gt;

&lt;p&gt;Angular CLI のビルド時にあらかじめ HTML をレンダリングする App-Shell や Universal Pre-rendering のユースケースについては、critters の基本的なアプローチで解決できる。&lt;/p&gt;

&lt;h4&gt;
  
  
  Client Side Rendering （CSR）
&lt;/h4&gt;

&lt;p&gt;クライアントサイドレンダリングのアプリケーションは、Node.js 環境で実行できないため critters のようなツールでの クリティカル CSS 抽出ができない。 しかし Angular コンテキストではないカスタムの CSS 読み込み は &lt;code&gt;index.html&lt;/code&gt; で記述されることが多いため、ビルド時にこれらを抽出してインライン化することでこのケースをカバーする。&lt;/p&gt;

&lt;h2&gt;
  
  
  代替案
&lt;/h2&gt;

&lt;p&gt;以下のアイデアは現時点では有用性が低い、実現可能性が低いなどの理由で採用される見込みの低いものである。&lt;/p&gt;

&lt;h3&gt;
  
  
  明示的なクリティカル CSS 定義
&lt;/h3&gt;

&lt;p&gt;インライン化されるべきクリティカル CSS を開発者がアノテーションし、&lt;a href="https://github.com/mrnocreativity/postcss-critical-split#readme" rel="noopener noreferrer"&gt;postcss-critical-split&lt;/a&gt;のようなツールで抽出するアプローチ。 このアプローチはその CSS がクリティカルであるかを開発者が判断しなければならないという問題と、サードパーティ CSS にはアノテーションできないという欠点があるため却下された。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* critical:start */
header {
  background-color: #1d1d1d;
  font-size: 2em;
}

.aside {
  text-decoration: underline;
}
/* critical:end */

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ヘッドレスブラウザによるクリティカル CSS 抽出
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/pocketjoso/penthouse" rel="noopener noreferrer"&gt;Penthouse&lt;/a&gt; はヘッドレス Chrome を使ってレンダリングしてクリティカル CSS を抽出するため、 Node.js で実行できない CSR のアプリケーションにも適用できる点で優れている。&lt;/p&gt;

&lt;p&gt;ただしこのアプローチはランタイムで実行しなければならない Angular Universal のユースケースでパフォーマンスを落とすため却下された。&lt;/p&gt;

&lt;h3&gt;
  
  
  ルートコンポーネントでのグローバル CSS 読み込み
&lt;/h3&gt;

&lt;p&gt;いわゆる &lt;code&gt;AppComponent&lt;/code&gt; の &lt;code&gt;styles&lt;/code&gt; を使ってグローバル CSS を読み込んでしまうことで コンポーネント CSS として Render-Blocking しない形でインライン化するアプローチ。&lt;/p&gt;

&lt;p&gt;これは App-Shell や Pre-rendering のユースケースにおいて &lt;code&gt;index.html&lt;/code&gt; が &lt;code&gt;styles.css&lt;/code&gt; の内容をすべて含み肥大化してしまう欠点がある。&lt;/p&gt;

&lt;h3&gt;
  
  
  DNS-Prefetch と Preconnect Hints
&lt;/h3&gt;

&lt;p&gt;Google Fonts と Icons の読み込みについて、DNS-Prefetch と Preconnect Hints を活用するアプローチ。 欠点は特に無いが CSS のインライン化のほうがより効果的であると考えている。&lt;/p&gt;

&lt;h2&gt;
  
  
  RFC のフィードバック
&lt;/h2&gt;

&lt;p&gt;RFC を通して集まったフィードバックのまとめは以下の通り。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;この機能はデフォルトで有効であり、オプトアウト可能であるべき&lt;/li&gt;
&lt;li&gt;新しい Size Budget は新プロジェクト、既存プロジェクトの両方に追加されるべき&lt;/li&gt;
&lt;li&gt;CSS ファイルの Budget の追加にあたり、非利用 CSS の除去の手段も一緒に提供されることが望まれている&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  まとめ
&lt;/h2&gt;

&lt;p&gt;リリース時期はまだ未定であるが、Angular アプリケーションのパフォーマンス改善のための大きなプロジェクトである。 v10 で導入された CommonJS インポート時の警告といい、Angular 特有のパフォーマンスというよりは web.dev で取り上げられるようなベストプラクティス的なパフォーマンス改善のアプローチを、Angular CLI のデフォルト機能としてサポートする取り組みに力が入っているようにも見える。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.dev/commonjs-larger-bundles/" rel="noopener noreferrer"&gt;How CommonJS is making your bundles larger&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eliminate Render-Blocking Requests についてはゼロコンフィグ、あるいはほぼ設定不要で使えるべきであるという姿勢が強く見られるため、 完成には時間がかかりそうではあるがぜひ期待したい。&lt;/p&gt;

</description>
      <category>angular</category>
      <category>angularcli</category>
      <category>performance</category>
      <category>japanese</category>
    </item>
    <item>
      <title>Angular: Lightweight Injection Tokenという新しいテクニック</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Wed, 29 Jul 2020 04:57:17 +0000</pubDate>
      <link>https://dev.to/angular-jp/angular-lightweight-injection-token-4fn2</link>
      <guid>https://dev.to/angular-jp/angular-lightweight-injection-token-4fn2</guid>
      <description>&lt;p&gt;最近Angularチームが発見し、Angularライブラリの実装におけるパターンとして普及させようとしているのが、 &lt;strong&gt;Lightweight Injection Token&lt;/strong&gt; というテクニックだ。これはこれまで不可能だった &lt;strong&gt;コンポーネント(ディレクティブ)のTree-Shaking&lt;/strong&gt; を可能にする。本稿ではこの新しいテクニックの概要、そして生まれた経緯や深く知るための参考リンクをまとめる。&lt;/p&gt;

&lt;p&gt;なお、Lightweight Injection Tokenについては公式ドキュメントでも解説される予定であるため、そちらを参照すればいい部分は省略する。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://next.angular.io/guide/lightweight-injection-tokens" rel="noopener noreferrer"&gt;Angular - Optimizing client app size with lightweight injection tokens&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lightweight Injection Tokenの概要
&lt;/h2&gt;

&lt;p&gt;ひとことでいえば、「オプショナルな機能に関連するInjection Tokenとして代替の軽量トークンを使う」ということである。AngularのDIを深く理解していればこれだけでピンと来るかもしれないが、具体例から概要をつかもう。&lt;/p&gt;

&lt;p&gt;あるAngularライブラリが、次のような使い方ができる &lt;code&gt;&amp;lt;lib-card&amp;gt;&lt;/code&gt; コンポーネントを提供している。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;lib-card&amp;gt;&lt;/span&gt;
  Hello World!
&lt;span class="nt"&gt;&amp;lt;/lib-card&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;このコンポーネントは、Contentとして &lt;code&gt;&amp;lt;lib-card-header&amp;gt;&lt;/code&gt; コンポーネントを配置すると、カードのヘッダーとして取り扱う &lt;strong&gt;オプショナル&lt;/strong&gt; な機能があることをイメージしよう。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;lib-card&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;lib-card-header&amp;gt;&lt;/span&gt;Greeting Card&lt;span class="nt"&gt;&amp;lt;/lib-card-header&amp;gt;&lt;/span&gt;
  Hello World!
&lt;span class="nt"&gt;&amp;lt;/lib-card&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ライブラリ側はこのような使い方ができるコンポーネントを実装するとおおよそ次のようになるだろう。 &lt;code&gt;@ContentChild()&lt;/code&gt; を使って &lt;code&gt;CardHeaderComponent&lt;/code&gt; の参照を得る。ただしこのヘッダーを置くかどうかはユーザー次第なので、 &lt;code&gt;CardHeaderComponent|null&lt;/code&gt; という形でnullを許容することになる。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lib-card-header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CardHeaderComponent&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lib-card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CardComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ContentChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CardHeaderComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CardHeaderComponent&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ここで問題になるのが、 &lt;code&gt;CardComponent&lt;/code&gt; から &lt;code&gt;CardHeaderComponent&lt;/code&gt; への参照の持ち方である。 &lt;code&gt;@ContentChild(CardHeaderComponent)&lt;/code&gt; と &lt;code&gt;header: CardHeaderComponent|null&lt;/code&gt; の2箇所で参照を持っているが、この2つは性質が異なる。&lt;/p&gt;

&lt;p&gt;後者の &lt;code&gt;header: CardHeaderComponent|null&lt;/code&gt; は、 &lt;strong&gt;型&lt;/strong&gt; としての参照である。この参照はTypeScriptのコンパイル時型チェックにのみ用いられ、コンパイル後のJavaScriptには残らないため問題にならない。&lt;/p&gt;

&lt;p&gt;問題は前者の &lt;code&gt;@ContentChild(CardHeaderComponent)&lt;/code&gt; だ。これは &lt;strong&gt;値&lt;/strong&gt; としての参照であり、 &lt;code&gt;CardHeaderComponent&lt;/code&gt; というクラスオブジェクトそのものを参照している。それが直接 &lt;code&gt;@ContentChild()&lt;/code&gt; デコレーターに渡されているのだから、 &lt;strong&gt;ユーザーがヘッダーを使おうが使わまいが、この参照は実行時に残る&lt;/strong&gt; 。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@ViewChild()&lt;/code&gt; や &lt;code&gt;@ContentChild()&lt;/code&gt; の走査条件として使われるコンポーネント/ディレクティブのクラス参照はどうしてもTree-Shakingできず、これがAngularライブラリを利用したときの &lt;strong&gt;バンドルサイズの肥大化の原因&lt;/strong&gt; となる。&lt;/p&gt;

&lt;p&gt;これを解決するためのアプローチが、Lightweight Injection Tokenだ。上記の例で &lt;code&gt;@ContentChild()&lt;/code&gt; デコレーターに渡していたクラスを、次のように軽量なオブジェクトを利用したInjection Tokenに置き換える。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Lightweight Injection Token&lt;/span&gt;
&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CardHeaderToken&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lib-card-header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CardHeaderToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useExisting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CardHeaderComponent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;...,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CardHeaderComponent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CardHeaderToken&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lib-card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CardComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ContentChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CardHeaderToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CardHeaderToken&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;まず &lt;code&gt;CardHeaderToken&lt;/code&gt; 抽象クラスを作成し、 &lt;code&gt;CardHeaderComponent&lt;/code&gt; をその具象クラスとする。そしてコンポーネントプロバイダーで &lt;code&gt;CardHeaderToken&lt;/code&gt; に対して自身のクラスオブジェクトを提供する。 &lt;code&gt;CardComponent&lt;/code&gt; ではトークンを &lt;code&gt;@ContentChild()&lt;/code&gt;デコレーターの走査条件とする。&lt;/p&gt;

&lt;p&gt;これにより、 &lt;code&gt;CardComponent&lt;/code&gt; から直接の &lt;code&gt;CardHeaderComponent&lt;/code&gt; への参照はなくなり、ライブラリのユーザーが &lt;code&gt;&amp;lt;lib-card-header&amp;gt;&lt;/code&gt; コンポーネントを呼び出したときだけ &lt;code&gt;CardHeaderToken&lt;/code&gt; に対して &lt;code&gt;CardHeaderComponent&lt;/code&gt; クラスのインスタンスが提供されることになる。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@ContentChild()&lt;/code&gt; や &lt;code&gt;@ViewChild()&lt;/code&gt; の引数としてDIトークンを渡せるようになるのがバージョン 10.1.0からなので、このアプローチが取れるのは &lt;strong&gt;バージョン 10.1.0以降&lt;/strong&gt; になる（ &lt;code&gt;as any&lt;/code&gt; で突破する手法はあるが）。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/commit/97dc85ba5e4eb6cfa741908a04cfccb1459cec9b" rel="noopener noreferrer"&gt;feat(core): support injection token as predicate in queries (#37506) · angular/angular@97dc85b&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  なぜ今なのか、これまでの経緯
&lt;/h2&gt;

&lt;p&gt;この問題は昔からずっと存在したが、実はバージョン8まではそれほど重大な問題ではなかった。なぜかというとバージョン8以前、つまりIvy以前 (ViewEngine, VE) はAOTコンパイルによってテンプレートコンパイルされた結果の生成コードが、もとのコンポーネントとは別のクラス実体をもっていたからだ。&lt;/p&gt;

&lt;p&gt;ViewEngineでは &lt;code&gt;CardComponent&lt;/code&gt; クラスのデコレーターとそのメタデータをもとに &lt;code&gt;CardComponentNgFactory&lt;/code&gt; クラスが生成される。そして、JavaScriptとしてコードサイズが大きいのはほとんどの場合NgFactory側である。&lt;/p&gt;

&lt;p&gt;つまり上記の例でいえば、 たとえ &lt;code&gt;CardComponentNgFactory&lt;/code&gt; クラスが &lt;code&gt;CardHeaderComponent&lt;/code&gt; への参照を持っていたとしても、&lt;code&gt;CardHeaderComponent&lt;/code&gt; そのものが大きくないために問題にならなかったのだ。サイズが大きいのは &lt;code&gt;CardHeaderComponenNgFactory&lt;/code&gt; のほうで、NgFactoryは テンプレート中で &lt;code&gt;&amp;lt;lib-card-header&amp;gt;&lt;/code&gt; を使わない限り参照されないため、不完全ではあるがTree-ShakingできていたのがViewEngine方式だった。&lt;/p&gt;

&lt;p&gt;バージョン9からデフォルトになったIvy方式のAOTコンパイルは、生成コードを &lt;strong&gt;もとのクラスの静的フィールドとして合成する&lt;/strong&gt; 。よって AOTコンパイルすると &lt;code&gt;CardHeaderComponent&lt;/code&gt; そのもののサイズが大きくなり、 &lt;code&gt;CardComponent&lt;/code&gt; に巻き込まれて一緒にバンドルされるサイズが顕著に大きくなる。いままで行なわれていた生成コードのTree-ShakingがIvyによりなくなってしまった。&lt;/p&gt;

&lt;p&gt;つまり、Lightweight Injection TokenはViewEngine時代には顕在化していなかったがIvyによってクリティカルになった問題を解決するために編み出された、 &lt;strong&gt;Ivy時代のAngualrライブラリ実装パターン&lt;/strong&gt; である。&lt;/p&gt;

&lt;p&gt;もっともポピュラーなAngularのコンポーネントライブラリであるAngular Materialではバージョン9リリース時からバンドルサイズの増加が報告されており、その解消の過程でAngularチームが辿り着いた答えである。現在Angular ComponentsチームはAngular Materialの各コンポーネントをLightweight Injection Tokenパターンに置き換える作業を進めている。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/components/issues/19610" rel="noopener noreferrer"&gt;Increased initial main.js bundle size in v9 - mainly due to @angular/material packages · Issue #19610 · angular/components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/components/issues/19576" rel="noopener noreferrer"&gt;Use light-weight injection pattern for optimized tree-shaking/bundle size · Issue #19576 · angular/components&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  コンポーネント以外のLightweight Injection Token
&lt;/h2&gt;

&lt;p&gt;ところで、 &lt;code&gt;@ContentChild()&lt;/code&gt; などの走査条件でなくとも、通常のDIの中でもオプショナルなものについてはLightweight Injection Tokenパターンを使うべきである。 &lt;code&gt;@Optional()&lt;/code&gt; を使っていてもそのトークンの参照は残るためTree-Shakingはできない。コンストラクタDIでは型注釈部分にしか参照がないためコンパイルすれば消えそうに見えるが、コンストラクタ引数の型注釈はAOTコンパイル時に自動的に &lt;code&gt;@Inject()&lt;/code&gt; デコレーターに変換されるため、実体参照をもつのである。つまりこれも &lt;code&gt;@ContentChild()&lt;/code&gt; と全く同じ構造であり、同じ問題をもちうる。ライブラリ作者であればオプショナルなプロバイダーのトークンは可能な限り軽量にしておくべきだろう。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;srv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OptionalService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Same&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;OptionalService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;srv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OptionalService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ちなみにコンポーネントのLightweight Injection Tokenとして &lt;code&gt;InjectionToken&lt;/code&gt; オブジェクトを使うこともできるはずだ。公式ドキュメントでは抽象クラスの例が紹介されているが、どちらが定着するかは今後のコミュニティでの受け入れられ方次第だろう。ただ、トークンの抽象クラスとコンポーネントクラスを継承関係にするとそのままコンポーネントのAPI定義として利用もできるため、おそらくは抽象クラスのほうが便利な場面は多そうだ。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CardHeaderToken&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;InjectionToken&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CardHeaderComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CardHeaderComponent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://angular.io/guide/dependency-injection-providers#non-class-dependencies" rel="noopener noreferrer"&gt;https://angular.io/guide/dependency-injection-providers#non-class-dependencies&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  参考リンク
&lt;/h2&gt;

&lt;p&gt;以下に参考リンクをまとめる。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Misko HeveryによるDesign Doc &lt;a href="https://hackmd.io/@mhevery/SyqDjUlrU" rel="noopener noreferrer"&gt;https://hackmd.io/@mhevery/SyqDjUlrU&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;公式ドキュメントへの追加PR &lt;a href="https://github.com/angular/angular/pull/36144" rel="noopener noreferrer"&gt;https://github.com/angular/angular/pull/36144&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Angular MaterialのIssue &lt;a href="https://github.com/angular/components/issues/19576" rel="noopener noreferrer"&gt;https://github.com/angular/components/issues/19576&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>japanese</category>
    </item>
    <item>
      <title>Angular Elements: Composable Definition Pattern</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Wed, 22 Jul 2020 01:59:46 +0000</pubDate>
      <link>https://dev.to/lacolaco/angular-elements-composable-definition-pattern-15h9</link>
      <guid>https://dev.to/lacolaco/angular-elements-composable-definition-pattern-15h9</guid>
      <description>&lt;p&gt;Assuming a situation we have…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Angular component library project, &lt;code&gt;Lib1Module&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;An Angular Elements library project, &lt;code&gt;Lib1ElementsModule&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;An Angular Elements library project, &lt;code&gt;Lib2ElementsModule&lt;/code&gt; which uses &lt;code&gt;Lib1ElementsModule&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It can be achieved with loading scripts of both Lib1 and Lib2 separately. But composing multiple Angular Elements definition brings some benefits.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unified Angular bootstrapping (better performance)&lt;/li&gt;
&lt;li&gt;Single &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag in HTML (free from loading order problem)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating &lt;code&gt;Lib1ElementsModule&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createCustomElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/elements&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;defineCustomElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;injector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Injector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lib1-button-element&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;createCustomElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Lib1ButtonComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;injector&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Lib1Module&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="c1"&gt;// `entryComponents` is not needed if Ivy is enabled&lt;/span&gt;
  &lt;span class="na"&gt;entryComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Lib1ButtonComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Lib1ElementsModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;injector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Injector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngDoBootstrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;defineCustomElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;injector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use &lt;code&gt;Lib1ElementsModule&lt;/code&gt; , bootstrap it directly. Then &lt;code&gt;ngDoBootstrap()&lt;/code&gt; method will be called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.elements.ts&lt;/span&gt;
&lt;span class="nf"&gt;platformBrowserDynamic&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;bootstrapModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Lib1ElementsModule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating &lt;code&gt;Lib2ElementsModule&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Lib2ElementsModule&lt;/code&gt; enables both Lib1 and Lib2 Angular Elements by composition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createCustomElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/elements&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Lib1ElementsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;defineCustomElements&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;defineLib1Elements&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lib1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;defineCustomElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;injector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Injector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lib2-card-element&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;createCustomElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Lib2CardComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;injector&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Lib2Module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Lib1ElementsModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="c1"&gt;// `entryComponents` is not needed if Ivy is enabled&lt;/span&gt;
  &lt;span class="na"&gt;entryComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Lib2CardComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Lib2ElementsModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;injector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Injector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngDoBootstrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Compose definition&lt;/span&gt;
    &lt;span class="nf"&gt;defineLib1Elements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;injector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;defineCustomElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;injector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>angular</category>
      <category>angularelements</category>
    </item>
    <item>
      <title>Initial Null Problem of AsyncPipe and async data-binding</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Wed, 19 Feb 2020 00:54:03 +0000</pubDate>
      <link>https://dev.to/lacolaco/initial-null-problem-of-asyncpipe-and-async-data-binding-5dom</link>
      <guid>https://dev.to/lacolaco/initial-null-problem-of-asyncpipe-and-async-data-binding-5dom</guid>
      <description>&lt;p&gt;Original Post: &lt;a href="https://blog.lacolaco.net/2020/02/async-pipe-initial-null-problem-en/" rel="noopener noreferrer"&gt;https://blog.lacolaco.net/2020/02/async-pipe-initial-null-problem-en/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angular's &lt;a href="https://angular.io/api/common/AsyncPipe" rel="noopener noreferrer"&gt;AsyncPipe&lt;/a&gt; is a useful feature for template binding of asynchronous data, but it has a big problem since the beginning. That is the "Initial Null Problem".&lt;br&gt;
This article describes the Initial Null Problem of AsyncPipe and its root cause, and discusses new asynchronous data-binding to solve that.&lt;/p&gt;

&lt;p&gt;I recommend you to see also this great article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/angular/handling-observables-with-structural-directives-in-angular-112j"&gt;Handling Observables with Structural Directives in Angular - DEV Community 👩‍💻👨‍💻&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How AsyncPipe works
&lt;/h2&gt;

&lt;p&gt;AsyncPipe is now always used to create general Angular applications. It is often used to subscribe to Observable data and bind its snapshot to a template.&lt;br&gt;
The basic usage is as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div *ngIf="source$ | async as state"&amp;gt;
      {{ state.count }}
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./app.component.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;})));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, how does AsyncPipe bind the value that &lt;code&gt;source$&lt;/code&gt; streams to a template and render it? Take a look at &lt;a href="https://github.com/angular/angular/blob/9.0.1/packages/common/src/pipes/async_pipe.ts#L71" rel="noopener noreferrer"&gt;Implementation of AsyncPipe&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;AsyncPipe has a lot of asynchronous data abstraction code that can handle both Promise and Observable, but the essential code is the following code. Like any other Pipe, it implements the &lt;code&gt;transform()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;|&lt;/span&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;|&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestReturnedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ɵlooseIdentical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestReturnedValue&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestReturnedValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestReturnedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;WrappedValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at the code from the top. The first &lt;code&gt;if (!this._obj)&lt;/code&gt; is the condition when Observable is passed to AsyncPipe for the first time, that is, the initialization process. If &lt;code&gt;this._obj&lt;/code&gt; doesn't exist and &lt;code&gt;obj&lt;/code&gt; does, the pipe subscribes &lt;code&gt;obj&lt;/code&gt;. &lt;code&gt;obj&lt;/code&gt; corresponds to &lt;code&gt;source$&lt;/code&gt; in the  example. The Observable passed to AsyncPipe is executed &lt;code&gt;subscribe()&lt;/code&gt; here.&lt;/p&gt;

&lt;p&gt;The next if statement is for when an Observable has changed from the one you are subscribing. It disposes the current subscription and starts resubscribing.&lt;/p&gt;

&lt;p&gt;And the rest of the code is for returning the latest value &lt;code&gt;this._latestValue&lt;/code&gt; from the subscribed Observable. The returned value will be the value actually used to render the template.&lt;/p&gt;

&lt;p&gt;What you can see here is that &lt;strong&gt;AsyncPipe returns the cached &lt;code&gt;this._latestValue&lt;/code&gt; when the&lt;code&gt;transform()&lt;/code&gt;method is called&lt;/strong&gt;.&lt;br&gt;
This can also be seen in AsyncPipe's &lt;code&gt;_subscribe()&lt;/code&gt; and &lt;code&gt;this._updateLatestValue()&lt;/code&gt; methods. When the value flows into the asynchronous data subscribed by the &lt;code&gt;_subscribe()&lt;/code&gt; method, &lt;code&gt;markForCheck()&lt;/code&gt; of &lt;code&gt;ChangeDetectorRef&lt;/code&gt; is called in the callback. It causes the next &lt;code&gt;transform()&lt;/code&gt; call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;|&lt;/span&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;|&lt;/span&gt;&lt;span class="nx"&gt;EventEmitter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_selectStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_strategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSubscription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_updateLatestValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_updateLatestValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words, AsyncPipe renders templates using the following mechanism.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pipe's &lt;code&gt;transform()&lt;/code&gt; is called in Change Detection&lt;/li&gt;
&lt;li&gt;Start subscribing to the passed Observable&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;this._latestValue&lt;/code&gt; at the time &lt;code&gt;transform()&lt;/code&gt;is called&lt;/li&gt;
&lt;li&gt;When Observable flows new data, update &lt;code&gt;this._latestValue&lt;/code&gt; and trigger Change Detection (back to 1)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;transform()&lt;/code&gt; must return a synchronous value, because the template can only render synchronous values. It can only return a cached snapshot at the time &lt;code&gt;transform()&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;A solid understanding of this should raise a question. That is, "at the start of the subscription, can't the &lt;code&gt;transform()&lt;/code&gt; return a value?" And that is the biggest problem that AsyncPipe has, the "Initial Null Problem". &lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Null Problem
&lt;/h2&gt;

&lt;p&gt;Since &lt;code&gt;this._latestValue&lt;/code&gt; is set by Observable's subscription callback, the value has never been set at the time of &lt;code&gt;transform()&lt;/code&gt; call. However, &lt;code&gt;transform()&lt;/code&gt; must return some value, so it returns a default value.&lt;br&gt;
Let's look again at the beginning of AsyncPipe's &lt;code&gt;transform()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestReturnedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_latestValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;this._latestValue&lt;/code&gt; used in the last two lines has never been set, so the initial value of this field will be used. Its value is &lt;code&gt;null&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AsyncPipe&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnDestroy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PipeTransform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_latestValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_latestReturnedValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words, AsyncPipe always returns &lt;code&gt;null&lt;/code&gt; once before flowing the first value. Even if the original Observable is &lt;code&gt;Observable&amp;lt;State&amp;gt;&lt;/code&gt;, it becomes &lt;code&gt;State | null&lt;/code&gt; through AsyncPipe. This is a problem I call " Initial Null Problem".&lt;/p&gt;

&lt;p&gt;While this problem seems serious, it has been automatically avoided in many cases. This is because &lt;code&gt;*ngIf&lt;/code&gt; and &lt;code&gt;*ngFor&lt;/code&gt;, which are often used with AsyncPipe, ignore the &lt;code&gt;null&lt;/code&gt; returned from AsyncPipe.&lt;/p&gt;

&lt;p&gt;In the following template, the value returned by &lt;code&gt;source$ | async&lt;/code&gt; is evaluated by the NgIf directive, and if it is Truthy, it will be rendered, so if it is &lt;code&gt;null&lt;/code&gt;, it will not go inside &lt;code&gt;*ngIf&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"source$ | async as state"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ state.count }}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, in the following template, the value returned by &lt;code&gt;source$ | async&lt;/code&gt; is evaluated by the NgFor directive and ignored if it is Falsey, so if it is &lt;code&gt;null&lt;/code&gt;, it will not be inside &lt;code&gt;*ngFor&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let item of source$ | async"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ item }}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Through null-safe directives such as &lt;code&gt;*ngIf&lt;/code&gt; and &lt;code&gt;*ngFor&lt;/code&gt;, the Initial Null Problem does not affect the application. The problem is otherwise, that is, passing values directly to the child component's Input via AsyncPipe.&lt;br&gt;
In the following cases, the child component should define a &lt;code&gt;prop&lt;/code&gt; Input type, but you have to consider the possibility of passing &lt;code&gt;null&lt;/code&gt; to it. If &lt;code&gt;prop&lt;/code&gt; is a getter or setter, you can easily imagine a runtime error when trying to access the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;child&lt;/span&gt; &lt;span class="na"&gt;[prop]=&lt;/span&gt;&lt;span class="s"&gt;"source$ | async"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/child&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, one simple best practice can be said.&lt;br&gt;
&lt;strong&gt;AsyncPipe should always be used through a null-safe guard like NgIf or NgFor&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Replace AsyncPipe
&lt;/h2&gt;

&lt;p&gt;From here, I will explore the new asynchronous data-binding that can replace AsyncPipe which has the above-mentioned problem.&lt;/p&gt;

&lt;p&gt;Why AsyncPipe returns &lt;code&gt;null&lt;/code&gt; is Pipe needs to return a synchronous value. The only way to solve the Initial Null Problem is to stop using Pipe for async data.&lt;/p&gt;

&lt;p&gt;So I tried using a directive. I think an approach that accepts an input and a template and renders the template under the control of the directive, is the best replacement for AsyncPipe.&lt;/p&gt;

&lt;p&gt;So I implemented the &lt;code&gt;*rxSubscribe&lt;/code&gt; directive. The sample that actually works is &lt;a href="https://stackblitz.com/edit/github-zg4qep" rel="noopener noreferrer"&gt;here&lt;/a&gt;. It subscribe an Observable with a structural directive as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*rxSubscribe=&lt;/span&gt;&lt;span class="s"&gt;"source$; let state"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ state.count }}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The directive is implemented as follows. What this directive does is&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Subscribe an Observable received by &lt;code&gt;rxSubscribe&lt;/code&gt; Input.&lt;/li&gt;
&lt;li&gt;When the Observable value flows, embed (render) the template for the first time&lt;/li&gt;
&lt;li&gt;When the value after the second time flows, update the context and call &lt;code&gt;markForCheck()&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://github.com/lacolaco/ngivy-rx-subscribe-directive/blob/master/src/app/rx-subscribe.directive.ts" rel="noopener noreferrer"&gt;https://github.com/lacolaco/ngivy-rx-subscribe-directive/blob/master/src/app/rx-subscribe.directive.ts&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Directive&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[rxSubscribe]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RxSubscribeDirective&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnDestroy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;vcRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ViewContainerRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;templateRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TemplateRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RxSubscribeFromContext&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxSubscribe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;source$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;viewRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EmbeddedViewRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RxSubscribeFromContext&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;takeUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onDestroy$&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;viewRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;viewRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vcRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createEmbeddedView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templateRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;$implicit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;viewRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$implicit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;viewRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this approach, the template is not rendered until the value first flows, and re-rendering can be triggered only when the value flows. It solves the Initial Null Problem, and is also CPU-friendly because re-rendering is limited only when necessary.&lt;/p&gt;

&lt;p&gt;By the way, the type of &lt;code&gt;state&lt;/code&gt; in &lt;code&gt;let state&lt;/code&gt;is inferred from the type of &lt;code&gt;source$&lt;/code&gt; exactly if Ivy of Angular v9 or later, and  if &lt;code&gt;strictTemplates&lt;/code&gt; flag is enabled. When you make a mistake use of &lt;code&gt;state&lt;/code&gt;, AOT compiler throws an error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*rxSubscribe=&lt;/span&gt;&lt;span class="s"&gt;"source$; let state"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ state.foo }}  &lt;span class="c"&gt;&amp;lt;!-- compile error: state doesn't have `foo` --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AsyncPipe could always only infer &lt;code&gt;or null&lt;/code&gt; due to the Initial Null Problem, but the structure directive approach can infer the context type exactly from &lt;code&gt;Observable&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I've published this &lt;code&gt;*rxSubscribe&lt;/code&gt; directive as the npm package &lt;strong&gt;&lt;code&gt;@soundng/rx-subscribe&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub &lt;a href="https://github.com/soundng/rx-subscribe" rel="noopener noreferrer"&gt;https://github.com/soundng/rx-subscribe&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NPM &lt;a href="https://www.npmjs.com/package/@soundng/rx-subscribe" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@soundng/rx-subscribe&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Demo &lt;a href="https://stackblitz.com/edit/github-zg4qep-kq9pyw?file=src/app/app.component.html" rel="noopener noreferrer"&gt;https://stackblitz.com/edit/github-zg4qep-kq9pyw?file=src/app/app.component.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AsyncPipe has Initial Null Problem&lt;/li&gt;
&lt;li&gt;Guarding with NgIf or NgFor can avoid the initial null&lt;/li&gt;
&lt;li&gt;Pipe has limitations in handling asynchronous data&lt;/li&gt;
&lt;li&gt;Structural directive approach can solve AsyncPipe problem&lt;/li&gt;
&lt;li&gt;Feedback welcome to &lt;code&gt;@soundng/rx-subscribe&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>rxjs</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>AngularでWeb Bundlesを試す</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Wed, 25 Dec 2019 04:48:53 +0000</pubDate>
      <link>https://dev.to/lacolaco/angular-web-bundles-3a2i</link>
      <guid>https://dev.to/lacolaco/angular-web-bundles-3a2i</guid>
      <description>&lt;p&gt;&lt;a href="https://qiita.com/advent-calendar/2019/angular-2" rel="noopener noreferrer"&gt;Angularアドベントカレンダー #2&lt;/a&gt;の24日目代打記事です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/web-bundles/" rel="noopener noreferrer"&gt;Web Bundles&lt;/a&gt;とは、現在標準化が検討されている新しいWebの仕様です。Webページとそれに紐づくサブリソースをひとつのバンドルとしてパッケージ化することができます。&lt;/p&gt;

&lt;p&gt;この記事ではWeb Bundlesを手元のAngularアプリケーションで試してみたい人向けの手順を紹介します。&lt;/p&gt;

&lt;h2&gt;
  
  
  CLI Builderのインストール
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/lacolaco/ngx-web-bundles" rel="noopener noreferrer"&gt;lacolaco/ngx-web-bundles&lt;/a&gt;というパッケージで、Angular CLI向けのBuilderを作っています。&lt;br&gt;
次のコマンドを実行するだけで、Web Bundleをビルドする準備が整います。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ng add @lacolaco/ngx-web-bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;インストールできたら、 任意のプロジェクトで&lt;code&gt;gen-bundle&lt;/code&gt;コマンドを実行します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ng run &amp;lt;project name&amp;gt;:gen-bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ビルドが終わると&lt;code&gt;index.html&lt;/code&gt;が出力されるdistディレクトリと同じ階層に &lt;code&gt;out.wbn&lt;/code&gt; というファイルが生成されているはずです。このファイルをGoogle ChromeのCanary版で Web Bundlesを有効にしてから開くと、バンドルを展開できるはずです。&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;ngx-web-bundleがやっているのは２つのことです。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ng add&lt;/code&gt; されたときに &lt;code&gt;angular.json&lt;/code&gt; を更新し、 &lt;code&gt;gen-bundle&lt;/code&gt;コマンドを定義する&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gen-bundle&lt;/code&gt;コマンドが実行されたときに処理する&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ng-add時の動き
&lt;/h3&gt;

&lt;p&gt;ng-add時に動くのは次の&lt;code&gt;ngAdd&lt;/code&gt;関数です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lacolaco/ngx-web-bundles/blob/master/schematics/ng-add/index.ts#L15" rel="noopener noreferrer"&gt;https://github.com/lacolaco/ngx-web-bundles/blob/master/schematics/ng-add/index.ts#L15&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;やっていることは次の2つです。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;対象とするプロジェクトを特定する&lt;/li&gt;
&lt;li&gt;プロジェクトの &lt;code&gt;architects&lt;/code&gt; に &lt;code&gt;gen-bundle&lt;/code&gt;を追加する&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;gen-bundle&lt;/code&gt;時の動き
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;gen-bundle&lt;/code&gt;コマンドで動くのは次の&lt;code&gt;build&lt;/code&gt;関数です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lacolaco/ngx-web-bundles/blob/master/index.ts#L51" rel="noopener noreferrer"&gt;https://github.com/lacolaco/ngx-web-bundles/blob/master/index.ts#L51&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;やっていることは次の3つです。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;executeBrowserBuilder&lt;/code&gt; を使って、アプリケーションのビルドをおこなう（&lt;code&gt;ng build&lt;/code&gt;と同じ処理を実行する）&lt;/li&gt;
&lt;li&gt;ビルド後の生成物を &lt;code&gt;wbn&lt;/code&gt; パッケージを使ってバンドル化する&lt;/li&gt;
&lt;li&gt;アプリケーションの生成物を同じ場所にバンドルを出力する&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;バンドル化の処理は次の関数に記述されています。特別に配慮が必要なのはindex.htmlだけで、それ以外はファイルごとに同じ処理をしています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lacolaco/ngx-web-bundles/blob/master/index.ts#L24" rel="noopener noreferrer"&gt;https://github.com/lacolaco/ngx-web-bundles/blob/master/index.ts#L24&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ひとつひとつのやっていることはシンプルです。それらを組み合わせてルールに従って配置すれば簡単にAngular CLI経由で動かせるスクリプトを作成できます。&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AngularでWeb Bundlesを試すなら &lt;code&gt;@lacolaco/ngx-web-bundle&lt;/code&gt; をどうぞ&lt;/li&gt;
&lt;li&gt;自作のスクリプトを&lt;code&gt;ng add&lt;/code&gt;や&lt;code&gt;ng run&lt;/code&gt;に対応させるのは意外に簡単です

&lt;ul&gt;
&lt;li&gt;デバッグはちょっと面倒です&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Web Bundlesについては web.dev/web-bundles/ を参照してください&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>webpackaging</category>
      <category>japanese</category>
    </item>
    <item>
      <title>Angularの追いかけ方</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Tue, 24 Dec 2019 15:00:49 +0000</pubDate>
      <link>https://dev.to/lacolaco/angular-2597</link>
      <guid>https://dev.to/lacolaco/angular-2597</guid>
      <description>&lt;p&gt;&lt;a href="https://qiita.com/advent-calendar/2019/angular-2" rel="noopener noreferrer"&gt;Angular #2 Advent Calendar 2019&lt;/a&gt;の25日目の記事です。&lt;/p&gt;

&lt;p&gt;アドベントカレンダー2枚が埋まるほど日本でのAngularの熱が高まっていることがAngularのGDEとしてとても嬉しいです！&lt;br&gt;
この記事ではAngularについてもっと深く知りたい、学びたいと思っている方々向けに、私が普段からウォッチしている信頼できるリソースを紹介します。&lt;/p&gt;

&lt;h2&gt;
  
  
  Twitter
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/angular" rel="noopener noreferrer"&gt;Angular（@angular）&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;まずはもちろん公式アカウントです。公式アナウンスは基本的にこのアカウントから発信されます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/stephenfluin/lists/angular-gdes" rel="noopener noreferrer"&gt;@stephenfluin/Angular GDEs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angular GDEがまとめられたTwitterリストです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/stephenfluin" rel="noopener noreferrer"&gt;Stephen Fluin（@stephenfluin）&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stephen FluinはAngularチームのDeveloper Advocateです。公式ブログの記事の執筆もおこなっています。彼の&lt;a href="https://fluin.io/blog" rel="noopener noreferrer"&gt;個人ブログ&lt;/a&gt;でもAngularのテクニックなどを投稿しています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/mgechev" rel="noopener noreferrer"&gt;Minko Gechev（@mgechev）&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Minko GechevはAngularチームの開発者です。ツール周りやパフォーマンス改善に役立つTipsをよくツイートしています。ちなみに web.dev/angular の執筆はほとんどMinkoによるものです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/brandontroberts" rel="noopener noreferrer"&gt;Brandon 👨🏿‍💻✍🏿🏀（@brandontroberts）&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/MikeRyanDev" rel="noopener noreferrer"&gt;Mike Ryan（@MikeRyanDev）&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/tim_deschryver" rel="noopener noreferrer"&gt;Tim Deschryver（@tim_deschryver）&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NgRxのメンテナーたちです&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/Michael_Hladky" rel="noopener noreferrer"&gt;Michael Rx Hladky（@Michael_Hladky）&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AngularとRxJSのインテグレーションに興味がある方はぜひMichael Hladkyをフォローするとよいでしょう。刺激的な記事やデモなどを時折公開してくれます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/mhartington" rel="noopener noreferrer"&gt;Mike Hartington（@mhartington）&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ionicチームの開発者です。Ionicのことを知りたければMikeに質問すれば快く答えてくれるでしょう。&lt;/p&gt;

&lt;p&gt;他にもたくさんフォローしてほしいアカウントはあるのですがキリがないので、ここに挙げた彼らのリツイートなどから見つけていくといいでしょう。&lt;/p&gt;

&lt;h2&gt;
  
  
  Blog
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blog.angular.io/" rel="noopener noreferrer"&gt;Angular Blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;公式ブログです。まずはここをウォッチしましょう。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/angular"&gt;https://dev.to/angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angular GDEを中心に信頼できる人たちの記事が集まるdev toのorganizationです。いろんなジャンルやレベルの記事が読めます&lt;/p&gt;

&lt;p&gt;&lt;a href="https://indepth.dev/angular/" rel="noopener noreferrer"&gt;ANGULAR INDEPTH&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angular中上級者なら必読のブログです。決して初心者向けではない濃い記事ばかりが投稿されています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://juristr.com/blog/" rel="noopener noreferrer"&gt;Blogs | juri.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angular GDEの&lt;a href="https://twitter.com/juristr" rel="noopener noreferrer"&gt;Juri Strumpflohner&lt;/a&gt;の個人ブログです。役に立つ記事がよく投稿されるのでぜひ読んでもらいたいです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.softwarearchitekt.at/blog/" rel="noopener noreferrer"&gt;Blog - softwarearchitekt.at&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angular GDEの&lt;a href="https://twitter.com/ManfredSteyer" rel="noopener noreferrer"&gt;Manfred Steyer&lt;/a&gt;のブログです。&lt;br&gt;
ドメイン駆動設計などAngularアプリケーションのアーキテクチャに関する話題が多いので設計に興味があればぜひ読んでもらいたいです。サイトはドイツ語ですがだいたいの記事は英語で書かれてるので大丈夫です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://netbasal.com/@NetanelBasal" rel="noopener noreferrer"&gt;Netanel Basal – Netanel Basal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;状態管理ライブラリの&lt;a href="https://github.com/datorama/akita" rel="noopener noreferrer"&gt;Akita&lt;/a&gt;の作者でもある&lt;a href="https://twitter.com/NetanelBasal" rel="noopener noreferrer"&gt;Netanel Basal&lt;/a&gt;のブログです。ちょっとニッチな機能の使い方など、中級者におすすめの記事がたくさんあります。&lt;/p&gt;

&lt;h2&gt;
  
  
  Change Log
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/blob/master/CHANGELOG.md" rel="noopener noreferrer"&gt;angular/angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular-cli/releases" rel="noopener noreferrer"&gt;angular/angular-cli&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/components/blob/master/CHANGELOG.md" rel="noopener noreferrer"&gt;angular/components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angularのリポジトリの更新を追うならCHANGELOGやリリースを見るのがよいです。&lt;/p&gt;

&lt;h2&gt;
  
  
  Podcast
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/AngularAirPodcast" rel="noopener noreferrer"&gt;AngularAir - YouTube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ほぼ隔週で更新されているビデオpodcastです。Angular GDEの&lt;a href="https://twitter.com/schwarty" rel="noopener noreferrer"&gt;Justin Schwartzenberger&lt;/a&gt;が主催していて、役に立つネタもあれば実験的なネタもあり面白いです。&lt;/p&gt;




&lt;p&gt;年末年始、ぜひAngularを深く学ぶ時間にしてもらえれば幸いです。&lt;/p&gt;

</description>
      <category>angular</category>
      <category>japanese</category>
    </item>
    <item>
      <title>Perspective of Angular in 2020</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Tue, 24 Dec 2019 15:00:16 +0000</pubDate>
      <link>https://dev.to/lacolaco/perspective-of-angular-in-2020-2d0i</link>
      <guid>https://dev.to/lacolaco/perspective-of-angular-in-2020-2d0i</guid>
      <description>&lt;p&gt;&lt;a href="https://qiita.com/advent-calendar/2019/angular" rel="noopener noreferrer"&gt;Angular Advent Calendar 2019&lt;/a&gt;の25日目の記事です。&lt;/p&gt;

&lt;p&gt;この記事は GDG TokyoのDevFest 2019で発表した内容から抜粋、加筆したものです。&lt;br&gt;
2019年も終わりということで、発表では今年一年のAngularの動きを振り返り、来年以降の展望についてまとめました。&lt;br&gt;
この記事では振り返り部分は割愛し、2020年以降のAngularのロードマップについてのみ触れることにします。&lt;br&gt;
全篇をご所望の場合はスライドを直接参照してください。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://bit.ly/2Y5ZfJx" rel="noopener noreferrer"&gt;bit.ly/2Y5ZfJx&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Roadmap in 2020
&lt;/h1&gt;

&lt;p&gt;2020年の間にはv9.0からv11.xまでのリリースが行われる予定です。半年に一度のメジャーバージョンアップは今後も継続されます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kdvcju9i88ru75quoj9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kdvcju9i88ru75quoj9.png" alt="Alt Text" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;v9.0では次のような大きな変更があります。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ivyのデフォルト有効化&lt;/li&gt;
&lt;li&gt;CDK Clipboard APIの提供開始&lt;/li&gt;
&lt;li&gt;CDK Testing Harnessの提供開始&lt;/li&gt;
&lt;li&gt;@angular/{youtube-player, google-maps} パッケージの提供開始&lt;/li&gt;
&lt;li&gt;テンプレート型チェックの厳密化オプション提供開始&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ivyへの移行スケジュール
&lt;/h2&gt;

&lt;p&gt;v9.0では、すべてのアプリケーションでIvyモードでのAoTコンパイルがデフォルト有効になります。&lt;/p&gt;

&lt;p&gt;今後v10.xまではオプトアウトの手段が用意されますが、v11.0を持ってオプトアウトできなくなります。11.0がリリースされる予定の2020年末には、すべてのAngularアプリケーションがIvyによるコンパイルをおこなっていることを目標にしています。&lt;/p&gt;

&lt;h2&gt;
  
  
  CDKの新しいAPI
&lt;/h2&gt;

&lt;p&gt;Clipboard APIは文字列をクリップボードにコピーできるものです。テンプレート内で使えるディレクティブ形式のAPIと、クラス内で使えるサービス形式のAPIの両方が提供されています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnrrwcffpvqe94qupat0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnrrwcffpvqe94qupat0.png" alt="Alt Text" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;コンポーネントのテストをサポートするための &lt;code&gt;ComponentHarness&lt;/code&gt; APIも新しく提供されます。 &lt;code&gt;ComponentHarness&lt;/code&gt; を使うことで、コンポーネントのテストをメンテナンスしやすく記述できます。&lt;/p&gt;

&lt;p&gt;テストしたいコンポーネントに対応するHarnessを定義し、そのHarnessに対するテストを書くことで、テストではコンポーネントの実装の詳細に依存せずに宣言的なテストを書けます。同時にHarnessの実装では &lt;code&gt;DebugElement&lt;/code&gt; や &lt;code&gt;ComponentFixture&lt;/code&gt; などのAPIが使いやすい形に隠蔽されています。Angular Materialのソースコードでは、すべてのコンポーネントがHarnessによるテストに切り替えられています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8icp8ni1ys6zaig71oa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8icp8ni1ys6zaig71oa.png" alt="Alt Text" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular official components
&lt;/h2&gt;

&lt;p&gt;Angular開発チームによる公式コンポーネントライブラリが新たに提供されます。&lt;/p&gt;

&lt;p&gt;v9.0時点ではYouTubeプレイヤーを表示する &lt;code&gt;@angular/youtube-player&lt;/code&gt; パッケージと、 Googleマップを表示する &lt;code&gt;@angular/google-maps&lt;/code&gt; パッケージが提供されます。&lt;/p&gt;

&lt;h2&gt;
  
  
  Strict Template Type-Checking
&lt;/h2&gt;

&lt;p&gt;Ivyコンパイルの有効化によって、テンプレートの隅々まで型チェックできるようになります。しかし後方互換性のためにv9.0においては厳密なテンプレート型チェックはオプションで提供されます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tsconfig.json&lt;/code&gt; の &lt;code&gt;angularCompilerOptions&lt;/code&gt; で &lt;code&gt;strictTemplates&lt;/code&gt; フラグを有効にすると、TypeScriptの strictモードに近い厳密さでテンプレート型チェックがおこなわれます。&lt;/p&gt;

&lt;p&gt;代表的なものでは、イベントハンドラーの &lt;code&gt;$event&lt;/code&gt; 変数の型チェック、Inputの型チェック、コンポーネントメソッドの呼び出し型チェックなどが厳密になります。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7b7i9dgubgiolra8su5e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7b7i9dgubgiolra8su5e.png" alt="Alt Text" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Imagine the Future
&lt;/h1&gt;

&lt;p&gt;v9.0以降のAngularの展望はAngularのValuesを軸にして予想できます。つまり、&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apps that users ❤ to use&lt;/li&gt;
&lt;li&gt;Apps that developers ❤ to build&lt;/li&gt;
&lt;li&gt;Community where everyone feels welcome&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;の3つです。なかでもひとつめの "Apps that users ❤ to use"が2020年の大きな目標になると考えています。&lt;/p&gt;

&lt;p&gt;ng-conf 2019のkeynoteからスライドを引用すると、2018年から2019年にかけて、Angularの主なユースケースはエンタープライズアプリケーションでした。&lt;/p&gt;

&lt;p&gt;エンタープライズアプリケーションは数は多いですが、ひとつひとつのアプリケーションのユーザーはそれほど多くありません。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9kxieapsgx4uxa9p7ol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9kxieapsgx4uxa9p7ol.png" alt="Alt Text" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;エンタープライズアプリケーションの開発を支えるためにAngularが提供しているのは生産性とスケーラビリティです。Angular CLIによるコード生成や事前コンパイル、ビルドやテストの自動化はチーム開発の水準を高めてくれます。HTML/CSSによるUI開発は多くの開発者の慣れ親しんだ技術スタックです。&lt;/p&gt;

&lt;p&gt;静的型チェックや型ベースのDependency Injectionシステムもスケーラビリティが重要な開発ユースケースを支えてきました。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjzwmakacd3l9hrlvm1q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjzwmakacd3l9hrlvm1q.png" alt="Alt Text" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2019年のAngularがIvyを通して取り組んだのは、まだ届いていないユースケースをカバーすることでした。まずはじめに取り組んだのはカジュアルなユースケースです。&lt;/p&gt;

&lt;p&gt;デモやプロトタイプ、教材などユーザー数は少ないものの、何度も高速に、簡単に作る必要のあるアプリケーションです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgufgz6q69l5xye7zham.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgufgz6q69l5xye7zham.png" alt="Alt Text" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;カジュアルなユースケースに求められるのは、開発スピードと軽量性です。&lt;/p&gt;

&lt;p&gt;Ivyコンパイラで改善したTree-Shakingによるバンドルサイズの削減や、1コマンドでPWA化できる &lt;code&gt;@angular/pwa&lt;/code&gt; ツール、さらには1コマンドでデプロイできる &lt;code&gt;ng deploy&lt;/code&gt; コマンドなど、小さなアプリケーションを迅速に開発するためのツールを整えてきました。&lt;/p&gt;

&lt;p&gt;StackblitzやUI Bakeryのようなビジュアルプロトタイピングツールもサードパーティから登場しており、Angularアプリケーションをカジュアルに作り始める道具は揃ってきています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx5nfcgxb59heoorjrfi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx5nfcgxb59heoorjrfi.png" alt="Alt Text" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;そして2020年、Angularが取り組むのは未踏の領域、大衆向けのアプリケーション開発のユースケースです。&lt;/p&gt;

&lt;p&gt;eコマースやニュースサイトのような、コンシューマー向けの巨大な流入を持つユースケースでもAngularの3つのValuesを発揮できる仕組みを研究中です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqyy66hs73cf3p63pb2lc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqyy66hs73cf3p63pb2lc.png" alt="Alt Text" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;コンシューマー向けアプリケーションに求められるのはなんといってもWebパフォーマンスですが、それに加えて変化し続けるニーズに対応しつづけるための柔軟性です。&lt;/p&gt;

&lt;p&gt;SEOやアクセシビリティ、国際化やモバイル対応、オフラインなど考慮すべきことが山のようにあります。このようなユースケースではベストプラクティスに固執するだけでなくプロダクトにとって最適な方法論を選べるように、フレームワーク側も柔軟である必要があります。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F12ruz5xom8737okzr4pj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F12ruz5xom8737okzr4pj.png" alt="Alt Text" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ionic
&lt;/h2&gt;

&lt;p&gt;コンシューマー向けのAngularアプリ開発としてはIonicが大きなシェアを持っています。ハイブリッドモバイルアプリを開発できるIonicはAngular CLIに対応し、 &lt;code&gt;ng add&lt;/code&gt; コマンドで簡単にAngularプロジェクトに組み込めるようになりましたが、IonicはネイティブとのブリッジだけでなくUIコンポーネントライブラリの側面もあります。&lt;/p&gt;

&lt;p&gt;プロダクトのUIをそのまま使い、ハイブリッドアプリに変換するインフラだけ欲しいというニーズのために、Ionicチームは Capacitorというインフラ部分だけのパッケージを提供し、これもまた &lt;code&gt;ng add&lt;/code&gt; コマンドでAngularアプリケーションにインストールできるようにしました。&lt;/p&gt;

&lt;p&gt;また、ビジュアルアプリ開発のためのIonic Studioを使えば、Angularコンポーネントのリアルタイムプレビューや、GUIでのプログラミングも可能です。モバイル向けAngularアプリケーションの開発プラットフォームとしてIonicが急速に成長しています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ho5yqjdmdy63hjbeeey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ho5yqjdmdy63hjbeeey.png" alt="Alt Text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Work in Progress
&lt;/h2&gt;

&lt;p&gt;Angular公式にも取り組んでいるWork in Progressなプロジェクトがいくつかあります。&lt;/p&gt;

&lt;p&gt;ひとつは新しいi18n APIです。これまでのAngularが提供するi18n機能はテンプレート内だけのものでしたが、現在実装中の機能はTypeScriptのコードのなかでも実行時にローカライズができるようになります。国際化が必要なアプリケーションの実装を大いに助けてくれるでしょう。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frmxt5q6k14r17lybky91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frmxt5q6k14r17lybky91.png" alt="Alt Text" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;バンドルサイズのさらなる改善を目的に、コンポーネント単位での遅延読み込みも進行中です。これまではRoutingのページ単位でしたが、コンポーネントごとに遅延読み込みできるような仕組みを検討中です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vk5odoedzggcegelr6y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vk5odoedzggcegelr6y.png" alt="Alt Text" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;最後に、Project Photonを紹介します。ng-conf 2019で発表された研究段階のこのプロジェクトは、AngularアプリケーションにProgressive Hydrationを導入することが目的です。サーバーサイドレンダリングと遅延読み込みを組み合わせ、ユーザーが本当に必要とするまでJavaScriptを実行しないような仕組みを模索しています。詳しくはng-conf 2019のkeynoteを見てください。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F10qtif2uc8zjt8llhhgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F10qtif2uc8zjt8llhhgw.png" alt="Alt Text" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Scully: Static Site Generator
&lt;/h2&gt;

&lt;p&gt;新しい話題として、Angularのための静的サイトジェネレーター &lt;a href="https://github.com/scullyio/scully" rel="noopener noreferrer"&gt;Scully&lt;/a&gt; が公開されました。Scullyは公式製ではなくコミュニティの有志で作られたサードパーティツールです。&lt;/p&gt;

&lt;p&gt;これまでAngularにはGatsbyJSやGridsomeのような静的サイトジェネレーターは存在しなかったため、Scullyを起爆剤としてJAMstackもAngularのユースケースに加わっていくことでしょう。&lt;/p&gt;

&lt;h2&gt;
  
  
  2020年のAngular
&lt;/h2&gt;

&lt;p&gt;2020年のAngularはパフォーマンス改善を続けながら、Ivy導入によって可能となったi18nを始めとするフレームワークAPIの開発・改善を重ねていくことで、これまで弱い部分だったコンシューマー向けのユースケースに手を伸ばしていくことでしょう。&lt;/p&gt;

&lt;p&gt;Valuesの3本軸、ユーザーが愛せるアプリケーション（ユーザー体験）、開発者が愛せるアプリケーション（開発者体験）、そして世界中に広がるコミュニティの力で、これまで以上に魅力的なWeb開発プラットフォームに育っていくと期待しています。&lt;/p&gt;

&lt;p&gt;それでは良いお年を。&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>japanese</category>
    </item>
    <item>
      <title>なぜentryComponentsは非推奨になるのか</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Mon, 04 Nov 2019 03:45:08 +0000</pubDate>
      <link>https://dev.to/angular-jp/entrycomponents-53mo</link>
      <guid>https://dev.to/angular-jp/entrycomponents-53mo</guid>
      <description>&lt;p&gt;この記事では、Angular v9.0にて非推奨となる &lt;code&gt;entryComponents&lt;/code&gt; 機能が、なぜ非推奨になるのかについてできるだけ簡単に解説します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://next.angular.io/guide/deprecations#entrycomponents-and-analyze_for_entry_components-no-longer-required" rel="noopener noreferrer"&gt;Angular - Deprecated APIs and Features&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  はじめに
&lt;/h2&gt;

&lt;p&gt;解説を始める前に、重要な点をあらかじめ書き記しておきます。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;もしIvyをオプトアウトする場合は、 &lt;code&gt;entryComponents&lt;/code&gt; は引き続き必要です。決して削除しないでください。&lt;/li&gt;
&lt;li&gt;いままで &lt;code&gt;entryComponents&lt;/code&gt; 機能を使ったことがない方が新たになにか覚える必要はありません。興味がなければ過去のものとして無視してください。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;entryComponents&lt;/code&gt; とは何なのか
&lt;/h2&gt;

&lt;p&gt;v9.0 で非推奨となる &lt;code&gt;entryComponents&lt;/code&gt; とは何だったのかということをまずは振り返りましょう。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;entryComponents&lt;/code&gt; は多くの場合、 &lt;strong&gt;動的なコンポーネント&lt;/strong&gt; を実現するために利用されます。動的なコンポーネントとは、AngularのテンプレートHTML内に登場せず、コードの実行によって生成されるコンポーネントです。テンプレートHTMLを静的に検査しても宣言が見つからないことから &lt;strong&gt;動的&lt;/strong&gt; と呼ばれます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://angular.jp/guide/dynamic-component-loader" rel="noopener noreferrer"&gt;Angular - 動的コンポーネントローダー&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;もっとも代表的なユースケースはダイアログやモーダルのようなケースです。コンポーネントクラスの処理が実行されることで動的にコンポーネントが表示されます。このようなコンポーネントはテンプレートHTML内に宣言されません。&lt;/p&gt;

&lt;p&gt;たとえばAngular CDKの&lt;a href="https://material.angular.io/cdk/overlay/overview" rel="noopener noreferrer"&gt;Overlay API&lt;/a&gt;を使ってコンポーネントをオーバーレイ上に表示するには次のようなコードを書きます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Overlay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="nf"&gt;openModal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;overlayRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modalPortal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ComponentPortal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyModalComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;overlayRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modalPortal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;このとき、動的に表示したい &lt;code&gt;MyModalComponent&lt;/code&gt; は、 それが宣言される &lt;code&gt;NgModule&lt;/code&gt; の &lt;code&gt;entryComponents&lt;/code&gt; 配列に追加される必要があります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;declarations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyModalComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;entryComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;MyModalComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  なぜ &lt;code&gt;entryComponents&lt;/code&gt; が必要なのか
&lt;/h2&gt;

&lt;p&gt;Angularに慣れている人にとっては、もはや当たり前のように「モーダルを実装するときは &lt;code&gt;entryComponents&lt;/code&gt; 」というルーチンになってしまっているかもしれませんが、そもそもなぜこれが必要なのでしょうか。その理由は、Angular v8までのAoTテンプレートコンパイラと、そのテンプレートコンパイラが生成する実行コードに理由があります。&lt;/p&gt;

&lt;p&gt;ここで以降の説明の簡単のため、v8以前のAoTコンパイラを &lt;strong&gt;ViewEngine&lt;/strong&gt; (VE) コンパイラと呼びます。&lt;/p&gt;

&lt;h3&gt;
  
  
  コンポーネントの生成とComponentFactory
&lt;/h3&gt;

&lt;p&gt;動的コンポーネントの生成には &lt;code&gt;ComponentFactoryResolver&lt;/code&gt; というAPIを使います。このAPIはコンポーネントクラスから、そのコンポーネントに対してAoTコンパイラが生成した &lt;strong&gt;ComponentFactory&lt;/strong&gt; オブジェクトを返すものです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;cfr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ComponentFactoryResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;componentFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cfr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolveComponentFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SomeComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;先ほど紹介したCDKのOverlayやPortalの機能も、この &lt;code&gt;ComponentFactoryResolver&lt;/code&gt; を利用しています。そして、 &lt;code&gt;entryComponents&lt;/code&gt; に追加されたコンポーネントだけがこの &lt;code&gt;resolveComponentFactory&lt;/code&gt; メソッドの引数に使えます。もし追加されていなければ次のようなエラーが表示されます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzy7c5q5wkm1myo9uw6i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzy7c5q5wkm1myo9uw6i.png" width="800" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;つまり、 &lt;code&gt;entryComponents&lt;/code&gt; とは、「あるコンポーネントのComponentFactoryを解決可能にする」ための機能であると言えます。ではなぜ &lt;code&gt;entryComponents&lt;/code&gt; に追加されていないコンポーネントのComponentFactoryは解決できないのでしょうか。すべてのコンポーネントは等価ではないのでしょうか？&lt;/p&gt;

&lt;h3&gt;
  
  
  ViewEngineはTree-shakableなComponentFactoryを生成する
&lt;/h3&gt;

&lt;p&gt;その答えは半分YESです。ViewEngineのAoTコンパイラは &lt;code&gt;NgModule.declarations&lt;/code&gt; 配列に指定されたすべてのコンポーネントのComponentFactoryを生成しています。しかし、それが &lt;code&gt;ComponentFactoryResolver&lt;/code&gt; から解決可能になっていないのです。&lt;/p&gt;

&lt;p&gt;この様子は実際にAoTコンパイルの結果を見るとはっきりとわかります。Angular CLIのプロジェクトであれば、 &lt;code&gt;ngc -p ./tsconfig.app.json&lt;/code&gt; とコマンドを実行すれば &lt;code&gt;tsc-out&lt;/code&gt; ディレクトリにAoTコンパイル結果が出力されます。その中には、すべてのコンポーネントに対して &lt;code&gt;./some.component.ngfactory.js&lt;/code&gt; のような ComponentFactoryの生成コードを見ることができます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhggy68ozlu4b3je6f3bx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhggy68ozlu4b3je6f3bx.png" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;これでViewEngineではどのコンポーネントにもComponentFactoryは存在していることがわかります。しかし、これらのComponentFactoryは &lt;strong&gt;どこからも参照されていません&lt;/strong&gt;。つまりAngular CLI（の内部で使われているwebpack）のビルドでは、不要なコードとしてバンドルに含められないのです。これが、&lt;code&gt;ComponentFactoryResolver&lt;/code&gt; によってComponentFactoryを解決できないコンポーネントがある理由です。バンドルサイズ削減のために、不要なコードを含めない仕組みになっているのです。&lt;/p&gt;

&lt;h3&gt;
  
  
  ComponentとComponentFactoryの分断
&lt;/h3&gt;

&lt;p&gt;しかしこれはおかしい話です。ソースコード中で &lt;code&gt;SomeComponent&lt;/code&gt; を参照しているのだからそのComponentFactoryは必要なコードとしてバンドルに含められるべきです。&lt;/p&gt;

&lt;p&gt;ここがViewEngineの限界です。ViewEngineのAoTコンパイラはComponentFactoryの生成コードを元のコンポーネントクラスとは別のファイルに出力します。つまり、 &lt;code&gt;some.component.ts&lt;/code&gt; に対して &lt;code&gt;some.component.js&lt;/code&gt; と &lt;code&gt;some.component.ngfactory.js&lt;/code&gt; を出力します。したがって、アプリケーションで &lt;code&gt;SomeComponent&lt;/code&gt; への参照があったとしても、 &lt;code&gt;SomeComponent&lt;/code&gt; のComponentFactoryには一切参照が届かないのです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gz0xare75w0zjqhgn5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gz0xare75w0zjqhgn5a.png" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;entryComponents&lt;/code&gt; は &lt;code&gt;ComponentFactoryResolver&lt;/code&gt; をセットアップする
&lt;/h3&gt;

&lt;p&gt;ここでようやく &lt;code&gt;entryComponents&lt;/code&gt; の出番です。 &lt;code&gt;NgModule&lt;/code&gt; の &lt;code&gt;entryComponents&lt;/code&gt; に追加されたコンポーネントのComponentFactoryは、AoTコンパイラが特別に解釈して &lt;code&gt;ComponentFactoryResolver&lt;/code&gt; で解決できるように参照を作ります。その様子は AoTコンパイル後の &lt;code&gt;app.module.ngfactory.js&lt;/code&gt; で見ることができます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifakkkladd5jao4d55p2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifakkkladd5jao4d55p2.png" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AoTコンパイルの生成コードをはじめて見る方は驚くかもしれませんが、今回注目すべき点は2ヶ所。インポート文と &lt;code&gt;ComponentFactoryResolver&lt;/code&gt; のプロバイダ宣言です。見ての通り、 &lt;code&gt;AppModuleNgFactory&lt;/code&gt; から参照されているのは &lt;code&gt;app.component.ngfactory&lt;/code&gt; だけです。そして、 &lt;code&gt;ComponentFactoryResolver&lt;/code&gt; の近くにある配列には &lt;code&gt;AppComponentNgFactory&lt;/code&gt; だけがセットされています。&lt;/p&gt;

&lt;p&gt;それでは、 &lt;code&gt;SomeComponent&lt;/code&gt; を &lt;code&gt;entryComponents&lt;/code&gt; 配列に追加してもう一度AoTコンパイルしてみましょう。 &lt;code&gt;app.module.ngfactory.js&lt;/code&gt; に変化があるはずです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2dvc83l4slmw12dsg1y7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2dvc83l4slmw12dsg1y7.png" width="800" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;新たに &lt;code&gt;some.component.ngfactory&lt;/code&gt; への参照が追加され、&lt;code&gt;ComponentFactoryResolver&lt;/code&gt; の近くにある配列に &lt;code&gt;SomeComponentNgFactory&lt;/code&gt; が追加されています。実はこの配列こそが &lt;code&gt;ComponentFactoryResolver&lt;/code&gt;が解決できるコンポーネントのリストです。&lt;/p&gt;

&lt;p&gt;つまり、&lt;code&gt;entryComponents&lt;/code&gt; によって &lt;code&gt;NgModule&lt;/code&gt; のコンパイル結果に影響を与えることで、動的に利用したいコンポーネントのComponentFactoryがTree-shakingされないように、&lt;code&gt;ComponentFactoryResolver&lt;/code&gt; から解決可能な参照を保持することができるのです。&lt;/p&gt;

&lt;h2&gt;
  
  
  なぜ &lt;code&gt;entryComponents&lt;/code&gt; が非推奨になるのか
&lt;/h2&gt;

&lt;p&gt;ViewEngineにおいて &lt;code&gt;entryComponents&lt;/code&gt; がなぜ必要だったかを簡単に説明しましたが、なぜv9からは非推奨となるのでしょうか。それはViewEngineに変わるAngularの新しい &lt;strong&gt;Ivy&lt;/strong&gt;コンパイラがViewEngineの抱える問題を根本から解決したからです。&lt;/p&gt;

&lt;h3&gt;
  
  
  Ivyは同一ファイルにコード生成する
&lt;/h3&gt;

&lt;p&gt;IvyのAoTコンパイラは元のコンポーネントファイルと同じファイル、しかも同じクラスの静的フィールドとしてコード生成します。実際にAoTコンパイル結果を見てみましょう。v9では次のような生成コードになります。IvyではAoTコンパイルによって追加される独自のファイルは一切ありません。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm6hnxhszetbopt1xdtc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm6hnxhszetbopt1xdtc.png" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;some.component.js&lt;/code&gt; は次のようになっています。3行目にあるのは元の &lt;code&gt;SomeComponent&lt;/code&gt; から &lt;code&gt;@Component&lt;/code&gt; デコレーターが除去されたクラスです。そしてデコレーターの中に定義されていたセレクターやテンプレートなどのメタデータが、 9行目以降のAoTコンパイラによる生成コードに変換されています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tt7v5gv7r59w9t7xwy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tt7v5gv7r59w9t7xwy4.png" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ここで重要なことは、 &lt;code&gt;SomeComponent&lt;/code&gt; のAoTコンパイル後コードが、 &lt;code&gt;SomeComponent&lt;/code&gt; クラスと密に結合していることです。これにより、 &lt;code&gt;SomeComponent&lt;/code&gt; を参照すれば自動的に &lt;code&gt;SomeComponent&lt;/code&gt; のコンポーネント生成に必要なすべての情報を解決できます。&lt;/p&gt;

&lt;p&gt;つまり、 &lt;code&gt;app.module.js&lt;/code&gt; で &lt;code&gt;some.component.js&lt;/code&gt; をインポートしているだけで、 &lt;code&gt;SomeComponent&lt;/code&gt; のComponentFactoryは解決可能になるのです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fes9mle5ytngo7llgdyr8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fes9mle5ytngo7llgdyr8.png" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;これが、 Angular v9でIvyによって &lt;code&gt;entryComponents&lt;/code&gt; が非推奨になる理由です。 &lt;code&gt;entryComponents&lt;/code&gt; の代替となる新たな方法に変わるのではなく、そもそも根本的に&lt;strong&gt;動的コンポーネントと静的コンポーネントを区別する必要がなくなる&lt;/strong&gt;のです。&lt;/p&gt;

&lt;h3&gt;
  
  
  Tree-shakingの問題は？
&lt;/h3&gt;

&lt;p&gt;ここまで読んだ方はもしかすると &lt;code&gt;entryComponents&lt;/code&gt; がなくなることで、ViewEngineと比べてバンドルサイズが増えるのではないかと疑っているかもしれません。確かに、コンポーネントの生成コードだけを考えると、ViewEngineと比べてTree-shaking可能な領域は減っています。しかしIvyではその他のいくつもの改善によってトータルではほとんどのユースケースでバンドルサイズが削減されます。&lt;/p&gt;

&lt;p&gt;もっとも大きな改善は、Angularのテンプレート機能がTree-shakableになることです。詳細は割愛しますが、 &lt;code&gt;[prop]="someValue"&lt;/code&gt; や &lt;code&gt;(eventName)="onEvent($event)"&lt;/code&gt; など、すべてのテンプレートの機能が個別にTree-shakingされます。アプリケーションで一度も使わなかったテンプレート機能はバンドルに含まれません。&lt;/p&gt;

&lt;p&gt;また、コンポーネントと生成コードが同一ファイルになることでクラス定義やimport/exportのオーバーヘッドもなくなり、より少ないコードだけを生成すればよくなりました。また、ViewEngineではコンポーネントが子コンポーネントになる場合とホストコンポーネントになる場合で別の生成関数を定義していましたが、Ivyではひとつの生成関数に統合されるので、これによっても生成コードのサイズは減っています。&lt;/p&gt;

&lt;p&gt;トレードオフはありつつも、Ivyでは差分コンパイルのスピード、バンドルサイズの削減、内部アーキテクチャの単純化などの複合的な視点で、Ivyのアーキテクチャを選択しています。&lt;/p&gt;

&lt;h3&gt;
  
  
  動的コンポーネントを超えた遅延コンポーネントへ
&lt;/h3&gt;

&lt;p&gt;IvyのAoTコンパイラは同一クラスの静的フィールドにComponentFactoryを生成すると説明しました。この変更による恩恵は &lt;code&gt;entryComponents&lt;/code&gt; が不要になるだけではありません。ひとつのコンポーネントに関するコードが1ファイルに含まれることで、Dynamic Importによるコンポーネントの遅延読み込みも将来的には可能になります。&lt;/p&gt;

&lt;p&gt;つまり、次のように動的な &lt;code&gt;import()&lt;/code&gt; 文で取得した &lt;code&gt;SomeComponent&lt;/code&gt; クラスでも &lt;code&gt;ComponentFactoryResolver&lt;/code&gt; で解決できるということです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;cfr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ComponentFactoryResolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./some/some.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cfr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolveComponentFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SomeComponent&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someCompFactory&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someCompFactory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IvyではすべてのコンポーネントのComponentFactoryがバンドルに含められると説明しましたが、それはテンプレートHTMLやTypeScriptコードの中で &lt;strong&gt;静的に&lt;/strong&gt; 参照されている場合だけです。もし &lt;code&gt;SomeComponent&lt;/code&gt; がこの Dynamic Import以外でまったく参照されていなければ、 Angular CLIは &lt;code&gt;SomeComponent&lt;/code&gt; そのものを別バンドルに分離し、遅延読み込み可能にします。モーダル用のコンポーネントであれば、初期読込されるJavaScriptにはコンポーネントを含めず、モーダルを表示するイベントが発生したときに初めて遅延読み込みすればいいわけです。&lt;/p&gt;

&lt;p&gt;このようにViewEngineからIvyにアーキテクチャ変更したことによって、いままでは覚えるしかなかった「Angularではできない」や「Angularではこのようにする」といった慣例的な制約がいくつも取り払われていきます。そして不要になった（陳腐化した）APIは非推奨となっていきます。&lt;/p&gt;

&lt;p&gt;非推奨化は必ずしも代替APIへの置き換えを意味するわけではないということを覚えておきましょう。&lt;/p&gt;

&lt;h2&gt;
  
  
  まとめ
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;v8までのViewEngineでは &lt;code&gt;entryComponents&lt;/code&gt; が無ければComponentFactoryの解決ができなかった&lt;/li&gt;
&lt;li&gt;Ivyではすべてのコンポーネントが常にComponentFactoryを保持しているため、いつでもどのコンポーネントも動的に利用できるようになる&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;entryComponents&lt;/code&gt; の非推奨化は代替APIへの置き換えではなく、そもそも動的コンポーネントと静的コンポーネントの区別が不要になったということである&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ivyについての詳しい話は、 AngularConnect 2019での次のセッションをおすすめします。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=anphffaCZrQ&amp;amp;list=PLAw7NFdKKYpE-f-yMhP2WVmvTH2kBs00s" rel="noopener noreferrer"&gt;Deep Dive into the Angular Compiler | Alex Rickabaugh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=S0o-4yc2n-8&amp;amp;list=PLAw7NFdKKYpE-f-yMhP2WVmvTH2kBs00s&amp;amp;index=26" rel="noopener noreferrer"&gt;How Angular works | Kara Erickson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=EqSRpkMRyY4&amp;amp;list=PLAw7NFdKKYpE-f-yMhP2WVmvTH2kBs00s&amp;amp;index=10" rel="noopener noreferrer"&gt;How we make Angular fast | Miško Hevery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=nQ8oJ1rpwIc&amp;amp;list=PLAw7NFdKKYpE-f-yMhP2WVmvTH2kBs00s&amp;amp;index=7" rel="noopener noreferrer"&gt;The secrets behind Angular’s lightning speed | Max Koretskyi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>ivy</category>
    </item>
    <item>
      <title>Managing Key-Value Constants in TypeScript</title>
      <dc:creator>Suguru Inatomi</dc:creator>
      <pubDate>Tue, 20 Aug 2019 15:24:08 +0000</pubDate>
      <link>https://dev.to/angular/managing-key-value-constants-in-typescript-221g</link>
      <guid>https://dev.to/angular/managing-key-value-constants-in-typescript-221g</guid>
      <description>&lt;p&gt;A lot of applications have a dropdown select menu in a form. Let's imagine a form control like below;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjnninb2oyjr08qxorvs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjnninb2oyjr08qxorvs.gif" alt="Demo" width="760" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Typically, each select menu's item has &lt;strong&gt;ID&lt;/strong&gt; and &lt;strong&gt;label&lt;/strong&gt;. The ID is responsible to communicate with other components, services, or server-side. The label is responsible to display text for users.&lt;/p&gt;

&lt;p&gt;This post explains how to manage constants for the menu items which has ID and mapping for its label. It uses TypeScript's &lt;code&gt;as const&lt;/code&gt; feature which is introduced since v3.4. &lt;/p&gt;

&lt;h2&gt;
  
  
  Define colorIDs Tuple
&lt;/h2&gt;

&lt;p&gt;In TypeScript, a tuple is an array, but its length and items are fixed. You can define a tuple with &lt;code&gt;as const&lt;/code&gt; directive on the array literal. (&lt;code&gt;as const&lt;/code&gt; directive needs TypeScript 3.4+)&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;colors.ts&lt;/code&gt; and define &lt;code&gt;colorIDs&lt;/code&gt; tuple as following;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colorIDs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The type of &lt;code&gt;colorIDs&lt;/code&gt; is not &lt;code&gt;string[]&lt;/code&gt; but &lt;code&gt;['green', 'red', 'blue']&lt;/code&gt; . Its length is absolutely 3 and &lt;code&gt;colorIDs[0]&lt;/code&gt; is always &lt;code&gt;'green'&lt;/code&gt;. This is a tuple!&lt;/p&gt;

&lt;h2&gt;
  
  
  Extract  ColorID Type
&lt;/h2&gt;

&lt;p&gt;A Tuple type can be converted to its item's &lt;strong&gt;union type&lt;/strong&gt;. In this case, you can get &lt;code&gt;'green' | 'red' | 'blue'&lt;/code&gt; type from the tuple.&lt;/p&gt;

&lt;p&gt;Add a line to &lt;code&gt;colors.ts&lt;/code&gt; like below;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colorIDs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ColorID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;colorIDs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// === 'green' | 'red' | 'blue'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Got confusing? Don't worry. It's not magic.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;colorIDs[number]&lt;/code&gt; means "fields which can be access by number", which are &lt;code&gt;'green'&lt;/code&gt; , &lt;code&gt;'red'&lt;/code&gt;, or &lt;code&gt;'blue'&lt;/code&gt; . &lt;/p&gt;

&lt;p&gt;So &lt;code&gt;typeof colorIDs[number]&lt;/code&gt; becomes the union type &lt;code&gt;'green' | 'red' | 'blue'&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Define colorLabels map
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;colorLabels&lt;/code&gt; map is an object like the below;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colorLabels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because &lt;code&gt;colorLabels&lt;/code&gt; has no explicit type, you cannot notice even if you missed to define &lt;code&gt;red&lt;/code&gt; 's label.  &lt;/p&gt;

&lt;p&gt;Let's make sure that &lt;code&gt;colorLabels&lt;/code&gt; has a complete label set of all colors!  &lt;code&gt;ColorID&lt;/code&gt; can help it.&lt;/p&gt;

&lt;p&gt;TypeScript gives us &lt;code&gt;Record&lt;/code&gt; type to define Key-Value map object. The key is &lt;code&gt;ColorID&lt;/code&gt; and the value is string. So &lt;code&gt;colorLabels&lt;/code&gt; 's type should be &lt;code&gt;Record&amp;lt;ColorID, string&amp;gt;&lt;/code&gt; .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colorIDs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ColorID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;colorIDs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colorLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ColorID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you missed to define &lt;code&gt;red&lt;/code&gt; field, TypeScript compiler throw the error on the object. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpfhps1vlkipstow4op9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpfhps1vlkipstow4op9.png" alt="Compiler Error" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By the way, &lt;strong&gt;Angular v8.0+ is compatible with TypeScript v3.4&lt;/strong&gt;. The demo app in the above is the following;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormControl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;colorIDs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;colorLabels&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./colors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;label for="favoriteColor"&amp;gt;Select Favorite Color:&amp;amp;nbsp;&amp;lt;/label&amp;gt;
    &amp;lt;select id="favoriteColor" [formControl]="favoriteColorControl"&amp;gt;
      &amp;lt;option *ngFor="let id of colorIDs" [ngValue]="id"&amp;gt;
        {{ colorLabels[id] }}
      &amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;
    &amp;lt;div&amp;gt;Selected color ID: {{ favoriteColorControl.value }}&amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;colorIDs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;colorIDs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;colorLabels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;colorLabels&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;favoriteColorControl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorIDs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;as const&lt;/code&gt; turns an array into a &lt;strong&gt;tuple&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;typeof colorIDs[number]&lt;/code&gt; returns an &lt;strong&gt;union type&lt;/strong&gt; of its item&lt;/li&gt;
&lt;li&gt;Define an object with &lt;code&gt;Record&amp;lt;ColorID, string&amp;gt;&lt;/code&gt; for keeping a complete field set.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>angular</category>
    </item>
  </channel>
</rss>
