Buildless Angular app in single HTML file
概要
Skypack で提供されている ESM 形式の npm パッケージを、ブラウザの JavaScript から直接 import
することによって Anguar を動作させることができた。
実際のコード
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Buildless Angular app</title> <script type="module"> import "https://cdn.skypack.dev/zone.js"; import { Subject } from "https://cdn.skypack.dev/rxjs@7"; import { filter, share, switchMap, } from "https://cdn.skypack.dev/rxjs@7/operators"; import { Component, Inject, Injectable, NgModule } from "https://cdn.skypack.dev/@angular/core@12"; import { BrowserModule } from "https://cdn.skypack.dev/@angular/platform-browser@12"; import { platformBrowserDynamic } from "https://cdn.skypack.dev/@angular/platform-browser-dynamic@12"; import { HttpClient, HttpClientModule, } from "https://cdn.skypack.dev/@angular/common@12/http"; class AppService { static annotations = [new Injectable()]; static parameters = [[new Inject(HttpClient)]]; constructor(httpClient) { this.httpClient = httpClient; } static base = "https://jsonplaceholder.typicode.com"; getUsers() { return this.httpClient.get(`${AppService.base}/users`); } getPosts(userId) { return this.httpClient.get(`${AppService.base}/posts`, { params: { userId }, }); } } class AppComponent { static annotations = [ new Component({ selector: "app-root", template: ` <h4>Show Posts</h4> <label> Select User: <select (change)="selectedUserId$.next($event.target.value)"> <option></option> <option *ngFor="let user of users$ | async" [value]="user.id"> @{{user.username}}: {{user.name}} </option> </select> </label> <ul> <li *ngFor="let post of posts$ | async"> {{post.title}} </li> </ul> <p> Powered by <a href="https://jsonplaceholder.typicode.com/" target="_blank"> JSONPlaceholder </a> </p> `, }), ]; static parameters = [[new Inject(AppService)]]; constructor(appService) { this.appService = appService; this.users$ = appService.getUsers().pipe(share()); } selectedUserId$ = new Subject(); posts$ = this.selectedUserId$.pipe( filter((userId) => userId > 0), switchMap((userId) => this.appService.getPosts(userId)), share() ); } class AppModule { static annotations = [ new NgModule({ declarations: [AppComponent], imports: [BrowserModule, HttpClientModule], providers: [AppService], bootstrap: [AppComponent], }), ]; } await platformBrowserDynamic().bootstrapModule(AppModule); </script> </head> <body> <app-root></app-root> </body> </html>