Skip to content

Commit

Permalink
feat(@nguniversal/builders): enable to transfer assets (Clover)
Browse files Browse the repository at this point in the history
  • Loading branch information
lacolaco committed May 26, 2021
1 parent 094756f commit 52f7b7d
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 32 deletions.
3 changes: 3 additions & 0 deletions integration/clover/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@
"pokemon/charmander",
"pokemon/squirtle",
"pokemon/bulbasaur"
],
"transferAssets": [
"pokemon.json"
]
}
}
Expand Down
26 changes: 4 additions & 22 deletions integration/clover/src/app/pokemon.service.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,15 @@
import { Injectable } from '@angular/core';
import { TransferState, makeStateKey } from '@angular/platform-browser';
import { InMemoryDbService } from 'angular-in-memory-web-api';

@Injectable({
providedIn: 'root',
})
export class PokemonService implements InMemoryDbService {
constructor(private transferState: TransferState) {}
createDb() {
const pokemon = [
{
id: 'pikachu',
name: 'pikachu',
img: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png',
},
{
id: 'bulbasaur',
name: 'bulbasaur',
img: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png',
},
{
id: 'charmander',
name: 'charmander',
img: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/4.png',
},
{
id: 'squirtle',
name: 'squirtle',
img: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/7.png',
},
];
const stateKey = makeStateKey<object[]>('pokemon.json');
const pokemon = this.transferState.get(stateKey, []);

return { pokemon };
}
Expand Down
22 changes: 22 additions & 0 deletions integration/clover/src/assets/pokemon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"id": "pikachu",
"name": "pikachu",
"img": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png"
},
{
"id": "bulbasaur",
"name": "bulbasaur",
"img": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png"
},
{
"id": "charmander",
"name": "charmander",
"img": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/4.png"
},
{
"id": "squirtle",
"name": "squirtle",
"img": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/7.png"
}
]
15 changes: 10 additions & 5 deletions modules/builders/src/static-generator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import {
} from '@angular-devkit/architect';
import { BrowserBuilderOptions, BrowserBuilderOutput } from '@angular-devkit/build-angular';
import { normalizeOptimization } from '@angular-devkit/build-angular/src/utils/normalize-optimization';
import { normalizeAssetPatterns } from '@angular-devkit/build-angular/src/utils/normalize-asset-patterns';
import { augmentAppWithServiceWorker } from '@angular-devkit/build-angular/src/utils/service-worker';
import { normalize, resolve } from '@angular-devkit/core';
import { normalize, Path, resolve } from '@angular-devkit/core';
import JestWorker from 'jest-worker';
import * as ora from 'ora';
import { cpus } from 'os';
Expand All @@ -34,9 +35,9 @@ export async function execute(
context: BuilderContext,
): Promise<BuilderOutput> {
const browserTarget = targetFromTargetString(options.browserTarget);
const browserOptions = ((await context.getTargetOptions(
const browserOptions = (await context.getTargetOptions(
browserTarget,
)) as unknown) as BrowserBuilderOptions;
)) as unknown as BrowserBuilderOptions;
const routes = await getRoutes(options, browserOptions.tsConfig, context);

if (!routes.length) {
Expand All @@ -53,7 +54,7 @@ export async function execute(
return { success, error } as BuilderOutput;
}

const worker = createWorker(browserOptions);
const worker = createWorker(browserOptions, options.transferAssets);
try {
for (const outputPath of outputPaths) {
const spinner = ora(`Prerendering ${routes.length} route(s) to ${outputPath}...`).start();
Expand Down Expand Up @@ -90,13 +91,17 @@ export async function execute(
}
}

function createWorker(browserOptions: BrowserBuilderOptions): JestWorker {
function createWorker(
browserOptions: BrowserBuilderOptions,
transferAssetsPaths: string[] | undefined,
): JestWorker {
const { styles: normalizedStylesOptimization } = normalizeOptimization(
browserOptions.optimization,
);

const setupArgs: WorkerSetupArgs = {
inlineCriticalCss: normalizedStylesOptimization.inlineCritical,
transferAssetsPaths,
};

const maxWorkers = Math.max(Math.min(cpus().length, 6) - 1, 1);
Expand Down
9 changes: 9 additions & 0 deletions modules/builders/src/static-generator/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
"type": "boolean",
"description": "Whether or not the builder should extract routes and guess which paths to render.",
"default": true
},
"transferAssets": {
"type": "array",
"description": "The assets to be transfered before rendering application.",
"items": {
"minItems": 1,
"type": "string",
"uniqueItems": true
}
}
},
"required": ["browserTarget"],
Expand Down
4 changes: 4 additions & 0 deletions modules/builders/src/static-generator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export interface Schema {
* The path to a file containing routes separated by newlines.
*/
routesFile?: string;
/**
* The assets to be transfered before rendering application.
*/
transferAssets?: string[];
/**
* Server target to use for prerendering the app.
*/
Expand Down
2 changes: 2 additions & 0 deletions modules/builders/src/static-generator/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { join } from 'path';

export interface WorkerSetupArgs {
inlineCriticalCss?: boolean;
transferAssetsPaths?: string[];
}

let engine: Engine;
Expand All @@ -27,6 +28,7 @@ export async function render(options: { outputPath: string; route: string }): Pr
const html = await engine.render({
publicPath: outputPath,
inlineCriticalCss: sharedOptions.inlineCriticalCss,
transferAssetsPaths: sharedOptions.transferAssetsPaths,
url: `http://localhost/${route}`,
});

Expand Down
31 changes: 26 additions & 5 deletions modules/common/clover/server/src/server-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface RenderOptions {
headers?: Record<string, string | undefined | string[]>;
url: string;
inlineCriticalCss?: boolean;
transferAssetsPaths?: string[];
htmlFilename?: string;
publicPath: string;
}
Expand Down Expand Up @@ -99,17 +100,29 @@ export class Engine {
}, 30);
});

// Embed assets within transfer state
if (options.transferAssetsPaths) {
const assets = await Promise.all(
options.transferAssetsPaths.map((assetPath) => ({
assetPath,
content: fs.promises.readFile(path.resolve(options.publicPath, assetPath), 'utf-8'),
})),
);
const assetMap = assets.reduce(
(map, asset) => ({ ...map, [asset.assetPath]: asset.content }),
{},
);
const state = JSON.stringify(assetMap);
this.embedTransferState(doc, ngRenderMode.appId, state);
}

await ngRenderMode.getWhenStable();
doc.querySelector('[ng-version]')?.setAttribute('ng-clover', '');

// Add Angular state
const state = ngRenderMode.getSerializedState();
if (state) {
const script = doc.createElement('script');
script.id = `${ngRenderMode.appId}-state`;
script.setAttribute('type', 'application/json');
script.textContent = state;
doc.body.appendChild(script);
this.embedTransferState(doc, ngRenderMode.appId, state);
}

const content = dom.serialize();
Expand Down Expand Up @@ -137,6 +150,14 @@ export class Engine {
}
}

private embedTransferState(doc: Document, appId: string | undefined, state: string) {
const script = doc.createElement('script');
script.id = `${appId}-state`;
script.setAttribute('type', 'application/json');
script.textContent = state;
doc.body.appendChild(script);
}

private async getPrerenderedSnapshot(
publicPath: string,
pathname: string,
Expand Down

0 comments on commit 52f7b7d

Please sign in to comment.