From 750f9e2f7447b6057e91ab0fcbf86c269f04f997 Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Wed, 7 Aug 2019 17:56:23 +0200 Subject: [PATCH 1/2] Simplify preact-cli template injection --- .gitignore | 1 + .prettierignore | 1 + .../cli/lib/lib/webpack/render-html-plugin.js | 32 +++++++++++++++++-- packages/cli/lib/resources/body-end.ejs | 18 +++++++++++ packages/cli/lib/resources/head-end.ejs | 12 +++++++ packages/cli/tests/build.test.js | 10 ++++++ packages/cli/tests/images/build.js | 16 ++++++++++ .../tests/subjects/custom-template-2/index.js | 3 ++ .../subjects/custom-template-2/package.json | 4 +++ .../subjects/custom-template-2/template.html | 12 +++++++ 10 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 packages/cli/lib/resources/body-end.ejs create mode 100644 packages/cli/lib/resources/head-end.ejs create mode 100644 packages/cli/tests/subjects/custom-template-2/index.js create mode 100644 packages/cli/tests/subjects/custom-template-2/package.json create mode 100644 packages/cli/tests/subjects/custom-template-2/template.html diff --git a/.gitignore b/.gitignore index 3bd0e8b70..9135188c6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ tmp-*.json .idea/ .vscode +*.tmp.* diff --git a/.prettierignore b/.prettierignore index 8741598a4..321f64a39 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,4 @@ **/node_modules **/tests/output **/package.json +**/*.ejs diff --git a/packages/cli/lib/lib/webpack/render-html-plugin.js b/packages/cli/lib/lib/webpack/render-html-plugin.js index 7a54bb093..829ef95f2 100644 --- a/packages/cli/lib/lib/webpack/render-html-plugin.js +++ b/packages/cli/lib/lib/webpack/render-html-plugin.js @@ -1,24 +1,50 @@ const { resolve } = require('path'); -const { existsSync } = require('fs'); +const { existsSync, readFileSync, writeFileSync } = require('fs'); const HtmlWebpackExcludeAssetsPlugin = require('html-webpack-exclude-assets-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const prerender = require('./prerender'); const createLoadManifest = require('./create-load-manifest'); const { warn } = require('../../util'); const { info } = require('../../util'); -let template = resolve(__dirname, '../../resources/template.html'); +let defaultTemplate = resolve(__dirname, '../../resources/template.html'); + +function read(path) { + return readFileSync(resolve(__dirname, path), 'utf-8'); +} module.exports = async function(config) { const { cwd, dest, isProd, src } = config; const inProjectTemplatePath = resolve(src, 'template.html'); + let template = defaultTemplate; if (existsSync(inProjectTemplatePath)) { template = inProjectTemplatePath; } + + template = config.template || template; + + let content = read(template); + if (/preact\.headEnd|preact\.bodyEnd/.test(content)) { + const headEnd = read('../../resources/head-end.ejs'); + const bodyEnd = read('../../resources/body-end.ejs'); + content = content + .replace( + /<%\s+preact\.title\s+%>/, + '<%= htmlWebpackPlugin.options.title %>' + ) + .replace(/<%\s+preact\.headEnd\s+%>/, headEnd) + .replace(/<%\s+preact\.bodyEnd\s+%>/, bodyEnd); + + // Unfortunately html-webpack-plugin expects a true file, + // so we'll create a temporary one. + template = resolve(__dirname, 'template.tmp.ejs'); + writeFileSync(template, content); + } + const htmlWebpackConfig = values => { const { url, title, ...routeData } = values; return Object.assign(values, { filename: resolve(dest, url.substring(1), 'index.html'), - template: `!!ejs-loader!${config.template || template}`, + template: `!!ejs-loader!${template}`, minify: isProd && { collapseWhitespace: true, removeScriptTypeAttributes: true, diff --git a/packages/cli/lib/resources/body-end.ejs b/packages/cli/lib/resources/body-end.ejs new file mode 100644 index 000000000..e325d0210 --- /dev/null +++ b/packages/cli/lib/resources/body-end.ejs @@ -0,0 +1,18 @@ +<%= htmlWebpackPlugin.options.ssr() %> +<% if (webpack.assets.filter(entry => entry.name.match(/bundle(\.\w{5})?.esm.js$/)).length > 0) { %> + <% /* Fix for safari < 11 nomodule bug. TODO: Do the following only for safari. */ %> + + + <% + /*Fetch and Promise polyfills are not needed for browsers that support type=module + Please re-evaluate below line if adding more polyfills.*/ + %> + + +<% } else { %> + + +<% } %> + diff --git a/packages/cli/lib/resources/head-end.ejs b/packages/cli/lib/resources/head-end.ejs new file mode 100644 index 000000000..b5bb729aa --- /dev/null +++ b/packages/cli/lib/resources/head-end.ejs @@ -0,0 +1,12 @@ + +<% if (htmlWebpackPlugin.options.manifest.theme_color) { %> + +<% } %> +<% const loadManifest = htmlWebpackPlugin.options.createLoadManifest(compilation.assets, webpack.namedChunkGroups);%> +<% const filesRegexp = htmlWebpackPlugin.options.inlineCss ? /\.(chunk\.\w{5}\.css|js)$/ : /\.(css|js)$/;%> +<% for (const file in loadManifest[htmlWebpackPlugin.options.url]) { %> + <% if (htmlWebpackPlugin.options.preload && file && file.match(filesRegexp)) { %> + <% /* crossorigin for main bundle as that is loaded from `