Skip to content

Commit 83031e2

Browse files
committed
Render apps assets instead of building it with webpack
1 parent 592cca3 commit 83031e2

File tree

10 files changed

+75
-98
lines changed

10 files changed

+75
-98
lines changed

dotcom-rendering/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
"@types/express": "5.0.1",
6868
"@types/he": "1.2.0",
6969
"@types/html-minifier-terser": "7.0.2",
70-
"@types/html-webpack-plugin": "3.2.9",
7170
"@types/jest": "29.5.14",
7271
"@types/jsdom": "21.1.1",
7372
"@types/k6": "0.52.0",
@@ -123,7 +122,6 @@
123122
"find": "0.3.0",
124123
"he": "1.2.0",
125124
"html-minifier-terser": "7.2.0",
126-
"html-webpack-plugin": "5.6.4",
127125
"is-mobile": "3.1.1",
128126
"jest": "29.7.0",
129127
"jest-environment-jsdom": "29.7.0",

dotcom-rendering/scripts/deploy/build-riffraff-bundle.mjs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,6 @@ const copyFrontendStatic = () => {
124124
},
125125
);
126126

127-
log(' - copying rendered-items-assets.html => assets');
128-
const renderedItemsAssetsHtmlJob = cpy(
129-
path.resolve(source, 'rendered-items-assets.html'),
130-
dest,
131-
{ nodir: true },
132-
);
133-
134127
log(' - copying stats => assets');
135128
const statsToAssetsJob = cpy(
136129
path.resolve(source, 'stats'),
@@ -140,12 +133,7 @@ const copyFrontendStatic = () => {
140133
},
141134
);
142135

143-
return [
144-
staticJob,
145-
distToAssetsJob,
146-
renderedItemsAssetsHtmlJob,
147-
statsToAssetsJob,
148-
];
136+
return [staticJob, distToAssetsJob, statsToAssetsJob];
149137
};
150138

151139
const copyRiffRaff = () => {

dotcom-rendering/scripts/deploy/riff-raff.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ deployments:
2222
value: max-age=3600 # one hour in seconds
2323
# assume all other assets are hashed and never change,
2424
# even though this is not the case–e.g. icons
25-
- pattern: rendered-items-assets\.html$
26-
value: public, max-age=3600
2725
- pattern: .*
2826
value: public, max-age=315360000, immutable # one year in seconds
2927
prefixStack: false

dotcom-rendering/src/lib/fonts-css.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type FontFamily =
88

99
type FontStyle = 'normal' | 'italic';
1010

11-
interface FontDisplay {
11+
export interface FontDisplay {
1212
family: FontFamily;
1313
woff2: string;
1414
woff: string;
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { createHash } from 'node:crypto';
2+
import { isString } from '@guardian/libs';
3+
import CleanCSS from 'clean-css';
4+
import { type RequestHandler } from 'express';
5+
import { renderToString } from 'react-dom/server';
6+
import { generateScriptTags, getPathFromManifest } from '../lib/assets';
7+
import {
8+
type FontDisplay,
9+
fontList,
10+
rawFontsCssWithClassNames,
11+
} from '../lib/fonts-css';
12+
import { makePrefetchHeader } from './lib/header';
13+
14+
export const handleAppsAssets: RequestHandler = (req, res) => {
15+
const clientScripts = [
16+
getPathFromManifest('client.apps', 'index.js'),
17+
].filter(isString);
18+
19+
const scriptTags = generateScriptTags([...clientScripts]);
20+
const html = buildHtml(scriptTags);
21+
res.status(200).set('Link', makePrefetchHeader(clientScripts)).send(html);
22+
};
23+
24+
type Props = {
25+
fontList: FontDisplay[];
26+
};
27+
28+
export const buildHtml = (scriptTags: string[]) => {
29+
const fontAssetsCss = new CleanCSS()
30+
.minify(rawFontsCssWithClassNames)
31+
.styles.trim();
32+
33+
const body = renderToString(<AssetsPage fontList={fontList} />);
34+
35+
return `<!doctype html>
36+
<html lang='en'>
37+
<head>
38+
<title>Rendered Items Assets Html</title>
39+
<meta name='description' content='' />
40+
<meta charset='utf-8'>
41+
<meta http-equiv='Content-Security-Policy' content='sha256-${assetHash(
42+
fontAssetsCss,
43+
)}'>
44+
<style>
45+
${fontAssetsCss}
46+
</style>
47+
${scriptTags.join('\n')}
48+
49+
<body>
50+
${body}
51+
</body>
52+
</html>`;
53+
};
54+
55+
const assetHash = (asset: string) =>
56+
createHash('sha256').update(asset).digest('base64');
57+
58+
export const AssetsPage = ({ fontList: fonts }: Props) => {
59+
return (
60+
<>
61+
{fonts.map((font) => (
62+
<div key={font.uniqueName} className={font.uniqueName}>
63+
.
64+
</div>
65+
))}
66+
</>
67+
);
68+
};

dotcom-rendering/src/server/server.dev.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import nodePath from 'node:path';
2-
import { type Handler, Router, static as static_ } from 'express';
1+
import { type Handler, Router } from 'express';
32
import { pages } from '../devServer/routers/pages';
43
import { targets } from '../devServer/routers/targets';
54
import { handleAllEditorialNewslettersPage } from './handler.allEditorialNewslettersPage.web';
@@ -13,6 +12,7 @@ import {
1312
handleBlocks,
1413
handleInteractive,
1514
} from './handler.article.web';
15+
import { handleAppsAssets } from './handler.assets.apps';
1616
import { handleEditionsCrossword } from './handler.editionsCrossword';
1717
import { handleFront, handleTagPage } from './handler.front.web';
1818
import {
@@ -120,10 +120,7 @@ renderer.post('/FootballTablesPage', handleFootballTablesPage);
120120
renderer.post('/CricketMatchPage', handleCricketMatchPage);
121121
renderer.post('/FootballMatchSummaryPage', handleFootballMatchPage);
122122

123-
renderer.get(
124-
'/assets',
125-
static_(nodePath.resolve(__dirname, '../dist/rendered-items-assets.html')),
126-
);
123+
renderer.get('/assets/rendered-items-assets', handleAppsAssets);
127124

128125
const router = Router();
129126
router.use('/pages', pages);

dotcom-rendering/src/server/server.prod.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import path from 'node:path';
21
import compression from 'compression';
32
import type { ErrorRequestHandler, Request, Response } from 'express';
43
import express from 'express';
@@ -15,6 +14,7 @@ import {
1514
handleBlocks,
1615
handleInteractive,
1716
} from './handler.article.web';
17+
import { handleAppsAssets } from './handler.assets.apps';
1818
import { handleEditionsCrossword } from './handler.editionsCrossword';
1919
import { handleFront, handleTagPage } from './handler.front.web';
2020
import {
@@ -86,11 +86,7 @@ export const prodServer = (): void => {
8686
app.post('/AppsBlocks', logRenderTime, handleAppsBlocks);
8787
app.post('/EditionsCrossword', logRenderTime, handleEditionsCrossword);
8888

89-
app.get('/assets/rendered-items-assets.html', (req, res) => {
90-
res.sendFile(
91-
path.resolve(__dirname, './dist/rendered-items-assets.html'),
92-
);
93-
});
89+
app.get('/assets/rendered-items-assets', handleAppsAssets);
9490

9591
// All params to error handlers must be declared for express to identify them as error middleware
9692
// https://expressjs.com/en/api.html#:~:text=Error%2Dhandling%20middleware%20always,see%3A%20Error%20handling

dotcom-rendering/webpack/rendered-items-assets-template.html

Lines changed: 0 additions & 17 deletions
This file was deleted.

dotcom-rendering/webpack/webpack.config.client.js

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
const { createHash } = require('node:crypto');
2-
const path = require('node:path');
3-
const CleanCSS = require('clean-css');
4-
const HtmlWebpackPlugin = require('html-webpack-plugin');
51
const webpack = require('webpack');
62
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
7-
const {
8-
fontList,
9-
rawFontsCssWithClassNames,
10-
} = require('../src/lib/fonts-css.ts');
113
const swcConfig = require('./.swcrc.json');
124
const { getBrowserTargets } = require('./browser-targets');
135
const { svgr } = require('./svg.cjs');
@@ -69,17 +61,6 @@ const getLoaders = (build) => {
6961
}
7062
};
7163

72-
const fontAssetsCss = new CleanCSS()
73-
.minify(rawFontsCssWithClassNames)
74-
.styles.trim();
75-
76-
const assetHash = (asset) =>
77-
createHash('sha256').update(asset).digest('base64');
78-
79-
const fontDivsHtml = fontList
80-
.map((font) => `<div class="${font.uniqueName}">.</div>`)
81-
.join('\n');
82-
8364
/**
8465
* @param {{ build: Build }} options
8566
* @returns {import('webpack').Configuration}
@@ -132,32 +113,6 @@ module.exports = ({ build }) => ({
132113
new WebpackManifestPlugin({
133114
fileName: `manifest.${build}.json`,
134115
}),
135-
...(build === 'client.apps'
136-
? [
137-
new HtmlWebpackPlugin({
138-
excludeChunks: ['debug'],
139-
meta: {
140-
'Content-Security-Policy': {
141-
'http-equiv': 'Content-Security-Policy',
142-
content: `style-src 'sha256-${assetHash(
143-
fontAssetsCss,
144-
)}';`,
145-
},
146-
},
147-
filename: 'rendered-items-assets.html',
148-
minify: true,
149-
template: path.resolve(
150-
__dirname,
151-
'rendered-items-assets-template.html',
152-
),
153-
inject: false,
154-
templateParameters: {
155-
styles: fontAssetsCss,
156-
bodyContent: fontDivsHtml,
157-
},
158-
}),
159-
]
160-
: []),
161116
...(build === 'client.apps' || build === 'client.editionsCrossword'
162117
? [
163118
new webpack.optimize.LimitChunkCountPlugin({

pnpm-lock.yaml

Lines changed: 0 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)