diff --git a/.gitignore b/.gitignore index a735b0f0bb..5c9cf64a20 100644 --- a/.gitignore +++ b/.gitignore @@ -58,7 +58,7 @@ prerender-static.html # stencil angular/css/ core/css/ -core/hydrated/ +core/hydrate/ core/loader/ core/www/ .stencil/ diff --git a/core/package.json b/core/package.json index 2dc8340627..2aaada22ff 100644 --- a/core/package.json +++ b/core/package.json @@ -26,6 +26,7 @@ "files": [ "dist/", "css/", + "hydrate/", "loader/" ], "dependencies": { @@ -42,6 +43,7 @@ "aws-sdk": "^2.320.0", "chromedriver": "^2.38.3", "clean-css-cli": "^4.1.11", + "domino": "^2.1.3", "fs-extra": "^8.0.1", "jest": "24.8.0", "jest-cli": "24.8.0", @@ -76,7 +78,7 @@ "lint.ts": "tslint --project .", "lint.ts.fix": "tslint --project . --fix", "prerelease": "npm run validate && np prerelease --yolo --any-branch --tag next", - "prerender.e2e": "node scripts/testing/prerender-e2e.js", + "prerender.e2e": "node scripts/testing/prerender.js", "start": "npm run build.css && stencil build --dev --watch --serve", "test": "stencil test --spec --e2e", "test.spec": "stencil test --spec", diff --git a/core/scripts/testing/prerender.js b/core/scripts/testing/prerender.js new file mode 100644 index 0000000000..13d856a1ba --- /dev/null +++ b/core/scripts/testing/prerender.js @@ -0,0 +1,176 @@ +const fs = require('fs'); +const path = require('path'); +const hydrate = require('../../hydrate'); +const domino = require('domino'); + +let prerenderCount = 0; + +async function prerenderPage(srcIndexFilePath) { + const start = Date.now(); + + try { + await prerenderStatic(srcIndexFilePath); + await prerenderHydrated(srcIndexFilePath); + await prerenderDomino(srcIndexFilePath); + console.log(srcIndexFilePath, ` ${Date.now() - start}ms`); + + } catch (e) { + console.error(`Failed:`, srcIndexFilePath, ` ${Date.now() - start}ms`); + throw e; + } +} + +async function prerenderStatic(srcIndexFilePath) { + const dirPath = path.dirname(srcIndexFilePath); + const srcHtml = fs.readFileSync(srcIndexFilePath, 'utf-8'); + const staticFilePath = path.join(dirPath, 'prerender-static.html'); + + const results = await hydrate.renderToString(srcHtml, { + prettyHtml: true, + removeScripts: true + }); + if (results.diagnostics.some(d => d.type === 'error')) { + throw new Error('staticResults:\n' + results.diagnostics.map(d => d.messageText).join('\n')); + } + fs.writeFileSync(staticFilePath, results.html); + + const dstIndexFilePath = path.join(dirPath, 'prerender.html'); + const prerenderIndexHtml = buildPrerenderIndexHtml(results.title); + fs.writeFileSync(dstIndexFilePath, prerenderIndexHtml); + prerenderCount++; +} + +async function prerenderHydrated(srcIndexFilePath) { + const dirPath = path.dirname(srcIndexFilePath); + const srcHtml = fs.readFileSync(srcIndexFilePath, 'utf-8'); + const hydratedFilePath = path.join(dirPath, 'prerender-hydrated.html'); + const results = await hydrate.renderToString(srcHtml, { + prettyHtml: true + }); + if (results.diagnostics.some(d => d.type === 'error')) { + throw new Error('hydrateResults:\n' + staticResults.diagnostics.map(d => d.messageText).join('\n')); + } + fs.writeFileSync(hydratedFilePath, results.html); + prerenderCount++; +} + +async function prerenderDomino(srcIndexFilePath) { + const dirPath = path.dirname(srcIndexFilePath); + const srcHtml = fs.readFileSync(srcIndexFilePath, 'utf-8'); + const dominoFilePath = path.join(dirPath, 'prerender-domino.html'); + const dominoDoc = domino.createDocument(srcHtml, true); + const results = await hydrate.hydrateDocument(dominoDoc); + if (results.diagnostics.some(d => d.type === 'error')) { + throw new Error('dominoResults:\n' + staticResults.diagnostics.map(d => d.messageText).join('\n')); + } + const dominoHtml = dominoDoc.documentElement.outerHTML; + fs.writeFileSync(dominoFilePath, dominoHtml); + prerenderCount++; +} + +function buildPrerenderIndexHtml(title) { + return ` + +
+ +