From 7876f82871142f744020337add102a84daedb208 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sat, 8 Dec 2018 11:21:54 -0800 Subject: [PATCH] fix: build inline script using Rollup (#761) * fix: build inline script using Rollup This reduces code duplication and allows the theme engine to work the same without modifying the code in two places. It does extra extra deps, but I tried to keep them to a minimum. * change code comment * remove unnecessary constant --- .gitignore | 1 + bin/build-inline-script.js | 37 +++- inline-script.js | 23 +-- package-lock.json | 380 ++++++++++++++++++++++++++++++++++- package.json | 3 + routes/_utils/testStorage.js | 6 +- templates/2xx.html | 56 +----- templates/service-worker.js | 1 + 8 files changed, 424 insertions(+), 83 deletions(-) diff --git a/.gitignore b/.gitignore index 2c4a763..d668b5b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ assets/*.css mastodon.log assets/robots.txt /inline-script-checksum.json +/assets/inline-script.js.map diff --git a/bin/build-inline-script.js b/bin/build-inline-script.js index a648097..eacb4d1 100644 --- a/bin/build-inline-script.js +++ b/bin/build-inline-script.js @@ -4,20 +4,41 @@ import crypto from 'crypto' import fs from 'fs' import pify from 'pify' import path from 'path' -import { themes } from '../routes/_static/themes.js' -import { fromPairs } from 'lodash-es' +import { rollup } from 'rollup' +import { terser } from 'rollup-plugin-terser' +import replace from 'rollup-plugin-replace' +import fromPairs from 'lodash-es/fromPairs' +import { themes } from '../routes/_static/themes' const readFile = pify(fs.readFile.bind(fs)) const writeFile = pify(fs.writeFile.bind(fs)) +const themeColors = fromPairs(themes.map(_ => ([_.name, _.color]))) + async function main () { let inlineScriptPath = path.join(__dirname, '../inline-script.js') - let code = await readFile(inlineScriptPath, 'utf8') - code = code.replace('process.env.THEME_COLORS', JSON.stringify(fromPairs(themes.map(_ => ([_.name, _.color]))))) - code = `(function () {'use strict'\n${code}})()` + let bundle = await rollup({ + input: inlineScriptPath, + plugins: [ + replace({ + 'process.browser': true, + 'process.env.THEME_COLORS': JSON.stringify(themeColors) + }), + terser({ + mangle: true, + compress: true + }) + ] + }) + let { code, map } = await bundle.generate({ + format: 'iife', + sourcemap: true + }) - let checksum = crypto.createHash('sha256').update(code).digest('base64') + let fullCode = `${code}\n//# sourceMappingURL=inline-script.js.map` + + let checksum = crypto.createHash('sha256').update(fullCode).digest('base64') let checksumFilepath = path.join(__dirname, '../inline-script-checksum.json') await writeFile(checksumFilepath, JSON.stringify({ checksum }), 'utf8') @@ -26,9 +47,11 @@ async function main () { let html2xxFile = await readFile(html2xxFilepath, 'utf8') html2xxFile = html2xxFile.replace( /[\s\S]+/, - '' + '' ) await writeFile(html2xxFilepath, html2xxFile, 'utf8') + + await writeFile(path.resolve(__dirname, '../assets/inline-script.js.map'), map.toString(), 'utf8') } main().catch(err => { diff --git a/inline-script.js b/inline-script.js index 6b7c1b4..9d4ba3c 100644 --- a/inline-script.js +++ b/inline-script.js @@ -1,30 +1,19 @@ // For perf reasons, this script is run inline to quickly set certain styles. // To allow CSP to work correctly, we also calculate a sha256 hash during // the build process and write it to inline-script-checksum.json. + +import { testHasLocalStorageOnce } from './routes/_utils/testStorage' +import { switchToTheme } from './routes/_utils/themeEngine' + window.__themeColors = process.env.THEME_COLORS -const hasLocalStorage = (() => { - try { - // iOS safari throws here if cookies are disabled - let unused = localStorage.length // eslint-disable-line - return true - } catch (e) { - return false - } -})() +const hasLocalStorage = testHasLocalStorageOnce() if (hasLocalStorage && localStorage.store_currentInstance && localStorage.store_instanceThemes) { let safeParse = (str) => str === 'undefined' ? undefined : JSON.parse(str) let theme = safeParse(localStorage.store_instanceThemes)[safeParse(localStorage.store_currentInstance)] if (theme && theme !== 'default') { - let link = document.createElement('link') - link.rel = 'stylesheet' - link.href = `/theme-${theme}.css` - // inserting before the offline