prerender.mjs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Pre-render the app into static HTML.
  2. // run `npm run generate` and then `dist/static` can be served as a static site.
  3. import fs from 'node:fs';
  4. import path from 'node:path';
  5. import url from 'node:url';
  6. const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
  7. const toAbsolute = (p) => path.resolve(__dirname, p);
  8. const manifest = JSON.parse(fs.readFileSync(toAbsolute('dist/static/ssr-manifest.json'), 'utf-8'));
  9. const template = fs.readFileSync(toAbsolute('dist/static/index.html'), 'utf-8');
  10. const { render } = await import('./dist/server/entry-server.mjs');
  11. const langs = JSON.parse(fs.readFileSync(`src/data/langs.json`), 'utf-8');
  12. const cards = JSON.parse(fs.readFileSync(`src/data/cards.json`), 'utf-8');
  13. const withoutLang = ['/', '/cards/grid', '/cards/list', '/cards/network', '/cards/quiz', '/langs', '/about'];
  14. for (const card of cards) {
  15. withoutLang.push('/card/' + card.id);
  16. }
  17. let paths = [];
  18. paths.push('/');
  19. for (const lang of langs) {
  20. paths = paths.concat(
  21. withoutLang.map((path) => {
  22. return '/' + lang.code + path;
  23. })
  24. );
  25. }
  26. paths = paths.concat(
  27. withoutLang.map((path) => {
  28. return '/' + 'en' + path;
  29. })
  30. );
  31. paths = paths.concat(
  32. withoutLang.map((path) => {
  33. return '/' + 'fr' + path;
  34. })
  35. );
  36. // // determine routes to pre-render from src/pages
  37. // const routesToPrerender = fs
  38. // .readdirSync(toAbsolute('src/pages'))
  39. // .map((file) => {
  40. // const name = file.replace(/\.vue$/, '').toLowerCase()
  41. // return name === 'home' ? `/` : `/${name}`
  42. // })
  43. (async () => {
  44. // pre-render each route...
  45. let k = 0;
  46. for (const url of paths) {
  47. console.log(`> prerendering ${url}`);
  48. const [appHtml, preloadLinks, state, metaTags] = await render(url, manifest);
  49. k += 1;
  50. console.log(`> Rendered ${k}/${paths.length} pages`);
  51. let html = template.replace(`<!--preload-links-->`, preloadLinks).replace(`'<pinia-store>'`, state).replace(`<!--app-html-->`, appHtml);
  52. for (const metaTag in metaTags) {
  53. html = html.replace(metaTag, metaTags[metaTag]);
  54. }
  55. let filePath = `dist/static${url.slice(-1) === '/' ? url + '/index' : url}.html`;
  56. filePath = filePath.replace('//', '/');
  57. fs.mkdirSync(filePath.split('/').slice(0, -1).join('/'), { recursive: true });
  58. fs.writeFileSync(toAbsolute(filePath), html);
  59. console.log('pre-rendered:', filePath);
  60. }
  61. // done, delete ssr manifest
  62. fs.unlinkSync(toAbsolute('dist/static/ssr-manifest.json'));
  63. })();