1
0
Fork 0
mirror of https://github.com/betagouv/mon-entreprise synced 2025-02-15 08:15:01 +00:00
mon-entreprise/site/prerender.cjs
Maxime Quandalle 3e1bb91279 Configuration du Rendu coté serveur (SSR)
Désormais nous utilisons un script NodeJS natif pour générer le code
HTML pour le pré-rendu des pages. Cela est plus rapide et plus fiable
que la méthode précédente qui consistait un instrumentaliser un
navigateur (pupetter)
https://github.com/chrisvfritz/prerender-spa-plugin

Cela implique toutefois de faire attention à ne plus utiliser des
variables gloables du navigateur, comme `window`, `document` ou
`location` dans nos scripts. C'est plutôt une bonne pratique, mais il
faudrait sans doute configurer du typage pour détecter ces usages le
plus tôt possible et éviter de créer des erreurs inopinées avec le SSR.
2022-01-31 13:33:07 +01:00

60 lines
1.9 KiB
JavaScript

/* eslint-env node */
// TODO: Move to ESModule. But it was easier to make this script work with
// CommonJS when I wrote it.
// cf. https://github.com/vitejs/vite/blob/133fcea5223263b0ae08ac9a0422b55183ebd266/packages/vite/src/node/build.ts#L495
// cf. https://github.com/vitejs/vite/pull/2157
// TODO: We could use something like https://github.com/Aslemammad/tinypool to
// prerender all pages in parallel (used by vitest). Or move to SSR with a
// lambda and immutable caching.
const { readFileSync, promises: fs } = require('fs')
const path = require('path')
const { render } = require('./dist/server/entry-server.js')
const pagesToPrerender = {
'mon-entreprise': [
'/',
'/créer',
'/gérer',
'/simulateurs',
'/simulateurs/salaire-brut-net',
'/simulateurs/chômage-partiel',
'simulateurs/auto-entrepreneur',
'simulateurs/indépendant',
'simulateurs/dirigeant-sasu',
'simulateurs/artiste-auteur',
'iframes/simulateur-embauche',
'iframes/pamc',
],
infrance: ['/', '/calculators/salary', '/iframes/simulateur-embauche'],
}
const templates = Object.fromEntries(
Object.keys(pagesToPrerender).map((siteName) => [
siteName,
readFileSync(path.join(__dirname, `./dist/${siteName}.html`), 'utf-8'),
])
)
;(async function () {
await Promise.all(
Object.entries(pagesToPrerender).flatMap(([site, urls]) =>
urls.map((url) => prerenderUrl(url, site))
)
)
})()
async function prerenderUrl(url, site) {
const lang = site === 'mon-entreprise' ? 'fr' : 'en'
// TODO: replace helmet meta tags
const { html, styleTags, helmet } = await render(url, lang)
const page = templates[site]
.replace('<!--app-html-->', html)
.replace('<!--app-style-->', styleTags)
.replace(/<title>.*<\/title>/, `<title>${helmet.title.toString()}</title>`)
const dir = path.join(__dirname, 'dist/prerender', site, url)
await fs.mkdir(dir, { recursive: true })
await fs.writeFile(path.join(dir, 'index.html'), page)
}