From 291f42c71ed1d64c783a2d60ab2e2d43c8168d72 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Fri, 6 Aug 2021 16:22:40 -0700 Subject: [PATCH 01/15] wip --- build/build-treemap.js | 37 +++++++++-------- build/gh-pages-app.js | 24 ++++++++++- lighthouse-treemap/app/src/main.js | 21 ++++++++-- lighthouse-treemap/app/src/package.json | 4 ++ lighthouse-treemap/app/src/util.js | 55 +++++++++++-------------- lighthouse-treemap/tsconfig.json | 3 ++ lighthouse-treemap/types/treemap.d.ts | 12 +++--- package.json | 1 + yarn.lock | 52 ++++++++++++++++++++++- 9 files changed, 148 insertions(+), 61 deletions(-) create mode 100644 lighthouse-treemap/app/src/package.json diff --git a/build/build-treemap.js b/build/build-treemap.js index 9860c91514d3..f9176798eb5e 100644 --- a/build/build-treemap.js +++ b/build/build-treemap.js @@ -56,24 +56,25 @@ async function run() { fs.readFileSync(require.resolve('tabulator-tables/dist/css/tabulator.min.css'), 'utf8'), {path: 'styles/*'}, ], - javascripts: [ - /* eslint-disable max-len */ - fs.readFileSync(require.resolve('idb-keyval/dist/idb-keyval-min.js'), 'utf8'), - fs.readFileSync(require.resolve('event-target-shim/umd'), 'utf8'), - fs.readFileSync(require.resolve('webtreemap-cdt'), 'utf8'), - fs.readFileSync(require.resolve('tabulator-tables/dist/js/tabulator_core.js'), 'utf8'), - fs.readFileSync(require.resolve('tabulator-tables/dist/js/modules/sort.js'), 'utf8'), - fs.readFileSync(require.resolve('tabulator-tables/dist/js/modules/format.js'), 'utf8'), - fs.readFileSync(require.resolve('tabulator-tables/dist/js/modules/resize_columns.js'), 'utf8'), - fs.readFileSync(require.resolve('pako/dist/pako_inflate.js'), 'utf-8'), - /* eslint-enable max-len */ - buildStrings(), - {path: '../../dist/report/treemap.js'}, - {path: '../../lighthouse-viewer/app/src/drag-and-drop.js'}, - {path: '../../lighthouse-viewer/app/src/github-api.js'}, - {path: '../../lighthouse-viewer/app/src/firebase-auth.js'}, - {path: 'src/**/*'}, - ], + javascripts: 'src/main.js', + // javascripts: [ + // /* eslint-disable max-len */ + // fs.readFileSync(require.resolve('idb-keyval/dist/idb-keyval-min.js'), 'utf8'), + // fs.readFileSync(require.resolve('event-target-shim/umd'), 'utf8'), + // fs.readFileSync(require.resolve('webtreemap-cdt'), 'utf8'), + // fs.readFileSync(require.resolve('tabulator-tables/dist/js/tabulator_core.js'), 'utf8'), + // fs.readFileSync(require.resolve('tabulator-tables/dist/js/modules/sort.js'), 'utf8'), + // fs.readFileSync(require.resolve('tabulator-tables/dist/js/modules/format.js'), 'utf8'), + // fs.readFileSync(require.resolve('tabulator-tables/dist/js/modules/resize_columns.js'), 'utf8'), + // fs.readFileSync(require.resolve('pako/dist/pako_inflate.js'), 'utf-8'), + // /* eslint-enable max-len */ + // buildStrings(), + // {path: '../../dist/report/treemap.js'}, + // {path: '../../lighthouse-viewer/app/src/drag-and-drop.js'}, + // {path: '../../lighthouse-viewer/app/src/github-api.js'}, + // {path: '../../lighthouse-viewer/app/src/firebase-auth.js'}, + // {path: 'src/**/*'}, + // ], assets: [ {path: 'images/**/*'}, {path: 'debug.json'}, diff --git a/build/gh-pages-app.js b/build/gh-pages-app.js index 06268cc5a54a..9a29e5a9245b 100644 --- a/build/gh-pages-app.js +++ b/build/gh-pages-app.js @@ -7,6 +7,12 @@ const fs = require('fs'); const path = require('path'); +const rollup = require('rollup'); +const commonjs = + // @ts-expect-error types are wrong. + /** @type {import('rollup-plugin-commonjs').default} */ (require('rollup-plugin-commonjs')); +const {terser: rollupTerser} = require('rollup-plugin-terser'); +const {nodeResolve} = require('@rollup/plugin-node-resolve'); const cpy = require('cpy'); const ghPages = require('gh-pages'); const glob = require('glob'); @@ -45,7 +51,7 @@ const license = `/* * @property {Source} html * @property {Record=} htmlReplacements Needle -> Replacement mapping, used on html source. * @property {Source[]} stylesheets - * @property {Source[]} javascripts + * @property {Source[]|Source} javascripts * @property {Array<{path: string}>} assets List of paths to copy. Glob-able, maintains directory structure. */ @@ -148,6 +154,22 @@ class GhPagesApp { } async _compileJs() { + if (!Array.isArray(this.opts.javascripts)) { + const input = typeof this.opts.javascripts === 'string' ? + this.opts.javascripts : + this.opts.javascripts.path; + const bundle = await rollup.rollup({ + input: path.join(this.opts.appDir, input), + plugins: [ + nodeResolve(), + commonjs(), + // rollupTerser(), + ], + }); + const {output} = await bundle.generate({format: 'iife'}); + return output[0].code; + } + // Current Lighthouse version as a global variable. const versionJs = `window.LH_CURRENT_VERSION = '${lighthousePackage.version}';`; diff --git a/lighthouse-treemap/app/src/main.js b/lighthouse-treemap/app/src/main.js index 602c92ba1a90..2f5517c24bcf 100644 --- a/lighthouse-treemap/app/src/main.js +++ b/lighthouse-treemap/app/src/main.js @@ -9,7 +9,22 @@ /* eslint-env browser */ -/* globals I18n webtreemap strings TreemapUtil TextEncoding Tabulator Cell Row DragAndDrop Logger GithubApi */ +/* globals I18n webtreemap strings Tabulator Cell Row */ + +import 'idb-keyval/dist/idb-keyval-min.js'; +import 'event-target-shim/umd'; +import 'webtreemap-cdt'; +import 'tabulator-tables/dist/js/tabulator_core.js'; +import 'tabulator-tables/dist/js/modules/sort.js'; +import 'tabulator-tables/dist/js/modules/format.js'; +import 'tabulator-tables/dist/js/modules/resize_columns.js'; +import 'pako/dist/pako_inflate.js'; +import {TreemapUtil} from './util.js'; +import DragAndDrop from '../../../lighthouse-viewer/app/src/drag-and-drop.js'; +import GithubApi from '../../../lighthouse-viewer/app/src/github-api.js'; +import GithubApi from '../../../lighthouse-viewer/app/src/github-api.js'; +import {Logger} from '../../../report/renderer/logger.js'; +import {TextEncoding} from '../../../report/renderer/text-encoding.js'; const DUPLICATED_MODULES_IGNORE_THRESHOLD = 1024; const DUPLICATED_MODULES_IGNORE_ROOT_RATIO = 0.01; @@ -707,7 +722,7 @@ function injectOptions(options) { * @param {LhlMessages} localeMessages */ function getStrings(localeMessages) { - const strings = /** @type {TreemapUtil['UIStrings']} */ ({}); + const strings = /** @type {typeof TreemapUtil['UIStrings']} */ ({}); for (const varName of Object.keys(localeMessages)) { const key = /** @type {keyof typeof TreemapUtil['UIStrings']} */ (varName); @@ -777,7 +792,7 @@ class LighthouseTreemap { for (const node of document.querySelectorAll('[data-i18n]')) { // These strings are guaranteed to (at least) have a default English string in TreemapUtil.UIStrings, // so this cannot be undefined as long as `report-ui-features.data-i18n` test passes. - const i18nAttr = /** @type {keyof TreemapUtil['UIStrings']} */ ( + const i18nAttr = /** @type {keyof typeof TreemapUtil['UIStrings']} */ ( node.getAttribute('data-i18n')); node.textContent = TreemapUtil.i18n.strings[i18nAttr]; } diff --git a/lighthouse-treemap/app/src/package.json b/lighthouse-treemap/app/src/package.json new file mode 100644 index 000000000000..bd346284783c --- /dev/null +++ b/lighthouse-treemap/app/src/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "//": "Any directory that uses `import ... from` or `export ...` must be type module. Temporary file until root package.json is type: module" +} \ No newline at end of file diff --git a/lighthouse-treemap/app/src/util.js b/lighthouse-treemap/app/src/util.js index 0e07dc17e649..e89f21bd3f6a 100644 --- a/lighthouse-treemap/app/src/util.js +++ b/lighthouse-treemap/app/src/util.js @@ -11,7 +11,30 @@ /** @template {string} T @typedef {import('typed-query-selector/parser').ParseSelector} ParseSelector */ /** @template T @typedef {import('../../../report/renderer/i18n').I18n} I18n */ -class TreemapUtil { +export class TreemapUtil { + /** @type {I18n} */ + // @ts-expect-error: Is set in main. + static i18n = null; + + static UIStrings = { + /** Label for a button that alternates between showing or hiding a table. */ + toggleTableButtonLabel: 'Toggle Table', + /** Text for an option in a dropdown menu. When selected, the app shows information for all scripts that were found in a web page. */ + allScriptsDropdownLabel: 'All Scripts', + /** Label for a table column where the values are URLs, JS module names, or arbitrary identifiers. For simplicity, just 'name' is used. */ + tableColumnName: 'Name', + /** Label for column giving the size of a file in bytes. */ + resourceBytesLabel: 'Resource Bytes', + /** Label for a value associated with how many bytes of a script are not executed. */ + unusedBytesLabel: 'Unused Bytes', + /** Label for a column where the values represent how much of a file is used bytes vs unused bytes (coverage). */ + coverageColumnName: 'Coverage', + /** Label for a button that shows everything (or rather, does not highlight any specific mode such as: unused bytes, duplicate bytes, etc). */ + allLabel: 'All', + /** Label for a button that highlights information about duplicate modules (aka: files, javascript resources that were included twice by a web page). */ + duplicateModulesLabel: 'Duplicate Modules', + }; + /** * @param {LH.Treemap.Node} node * @param {(node: NodeWithElement, path: string[]) => void} fn @@ -191,33 +214,3 @@ TreemapUtil.COLOR_HUES = [ 15.9, 199.5, ]; - -/** @type {I18n} */ -// @ts-expect-error: Is set in main. -TreemapUtil.i18n = null; - -TreemapUtil.UIStrings = { - /** Label for a button that alternates between showing or hiding a table. */ - toggleTableButtonLabel: 'Toggle Table', - /** Text for an option in a dropdown menu. When selected, the app shows information for all scripts that were found in a web page. */ - allScriptsDropdownLabel: 'All Scripts', - /** Label for a table column where the values are URLs, JS module names, or arbitrary identifiers. For simplicity, just 'name' is used. */ - tableColumnName: 'Name', - /** Label for column giving the size of a file in bytes. */ - resourceBytesLabel: 'Resource Bytes', - /** Label for a value associated with how many bytes of a script are not executed. */ - unusedBytesLabel: 'Unused Bytes', - /** Label for a column where the values represent how much of a file is used bytes vs unused bytes (coverage). */ - coverageColumnName: 'Coverage', - /** Label for a button that shows everything (or rather, does not highlight any specific mode such as: unused bytes, duplicate bytes, etc). */ - allLabel: 'All', - /** Label for a button that highlights information about duplicate modules (aka: files, javascript resources that were included twice by a web page). */ - duplicateModulesLabel: 'Duplicate Modules', -}; - -// node export for testing. -if (typeof module !== 'undefined' && module.exports) { - module.exports = TreemapUtil; -} else { - self.TreemapUtil = TreemapUtil; -} diff --git a/lighthouse-treemap/tsconfig.json b/lighthouse-treemap/tsconfig.json index 1a9fc35cbb8b..e314ed468270 100644 --- a/lighthouse-treemap/tsconfig.json +++ b/lighthouse-treemap/tsconfig.json @@ -5,4 +5,7 @@ "types", "../types", ], + "compilerOptions": { + "esModuleInterop": true + } } diff --git a/lighthouse-treemap/types/treemap.d.ts b/lighthouse-treemap/types/treemap.d.ts index 2eb2a2fdf180..a4502d551cda 100644 --- a/lighthouse-treemap/types/treemap.d.ts +++ b/lighthouse-treemap/types/treemap.d.ts @@ -38,12 +38,12 @@ declare global { render(el: HTMLElement, data: any, options: WebTreeMapOptions): void; sort(data: any): void; }; - var TreemapUtil: typeof _TreemapUtil; - var TextEncoding: typeof _TextEncoding; - var Logger: typeof _Logger; - var DragAndDrop: typeof _DragAndDrop; - var GithubApi: typeof _GithubApi; - var FirebaseAuth: typeof _FirebaseAuth; + // var TreemapUtil: typeof _TreemapUtil; + // var TextEncoding: typeof _TextEncoding; + // var Logger: typeof _Logger; + // var DragAndDrop: typeof _DragAndDrop; + // var GithubApi: typeof _GithubApi; + // var FirebaseAuth: typeof _FirebaseAuth; var firebase: Required; var idbKeyval: typeof import('idb-keyval'); var strings: Record; diff --git a/package.json b/package.json index 7801ab252bfa..be7f0b8700fd 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "@firebase/app-types": "0.3.1", "@firebase/auth-types": "0.3.2", "@firebase/util": "0.2.1", + "@rollup/plugin-node-resolve": "^13.0.4", "@types/archiver": "^2.1.2", "@types/browserify": "^12.0.36", "@types/chrome": "^0.0.60", diff --git a/yarn.lock b/yarn.lock index db828ef853b9..e2ce263fce4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -763,6 +763,27 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" +"@rollup/plugin-node-resolve@^13.0.4": + version "13.0.4" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz#b10222f4145a019740acb7738402130d848660c0" + integrity sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -892,7 +913,7 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*": +"@types/estree@*", "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== @@ -1081,6 +1102,13 @@ resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.1.tgz#9b7cdae9cdc8b1a7020ca7588018dac64c770866" integrity sha512-5/bJS/uGB5kmpRrrAWXQnmyKlv+4TlPn4f+A2NBa93p+mt6Ht+YcNGkQKf8HMx28a9hox49ZXShtbGqZkk41Sw== +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + "@types/semver@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" @@ -1984,6 +2012,11 @@ buffer@^5.2.1, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +builtin-modules@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" + integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -3433,6 +3466,11 @@ estree-walker@^0.6.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -4646,6 +4684,11 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= + is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" @@ -6621,6 +6664,11 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +picomatch@^2.2.2: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + picomatch@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" @@ -7135,7 +7183,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.17.0, resolve@^1.20.0, resolve@^1.4.0: +resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.4.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== From 642a32657a7dd5bdfb8f60b51709e78563676f00 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Fri, 6 Aug 2021 16:52:43 -0700 Subject: [PATCH 02/15] first pass --- build/build-report.js | 15 ------ build/build-viewer.js | 6 +-- build/gh-pages-app.js | 47 +++++++++++++++---- lighthouse-viewer/app/index.html | 3 -- lighthouse-viewer/app/src/drag-and-drop.js | 6 +-- lighthouse-viewer/app/src/firebase-auth.js | 7 +-- lighthouse-viewer/app/src/github-api.js | 12 ++--- .../app/src/lighthouse-report-viewer.js | 17 ++++--- lighthouse-viewer/app/src/main.js | 5 +- lighthouse-viewer/app/src/package.json | 4 ++ lighthouse-viewer/app/src/psi-api.js | 10 +--- .../app/src/viewer-ui-features.js | 11 ++--- lighthouse-viewer/tsconfig.json | 1 + lighthouse-viewer/types/viewer.d.ts | 15 +----- report/clients/viewer.js | 27 ----------- 15 files changed, 72 insertions(+), 114 deletions(-) create mode 100644 lighthouse-viewer/app/src/package.json delete mode 100644 report/clients/viewer.js diff --git a/build/build-report.js b/build/build-report.js index 881cd9165188..6ef655a1870b 100644 --- a/build/build-report.js +++ b/build/build-report.js @@ -41,20 +41,6 @@ async function buildPsiReport() { }); } -async function buildViewerReport() { - const bundle = await rollup.rollup({ - input: 'report/clients/viewer.js', - plugins: [ - commonjs(), - ], - }); - - await bundle.write({ - file: 'dist/report/viewer.js', - format: 'iife', - }); -} - async function buildTreemapReport() { const bundle = await rollup.rollup({ input: 'report/clients/treemap.js', @@ -95,6 +81,5 @@ if (require.main === module) { module.exports = { buildStandaloneReport, buildPsiReport, - buildViewerReport, buildTreemapReport, }; diff --git a/build/build-viewer.js b/build/build-viewer.js index feb46833a537..aeb345fdefa9 100644 --- a/build/build-viewer.js +++ b/build/build-viewer.js @@ -9,7 +9,6 @@ const fs = require('fs'); const browserify = require('browserify'); const GhPagesApp = require('./gh-pages-app.js'); const {minifyFileTransform} = require('./build-utils.js'); -const {buildViewerReport} = require('./build-report.js'); const htmlReportAssets = require('../report/report-assets.js'); const {LH_ROOT} = require('../root.js'); @@ -32,8 +31,6 @@ async function run() { }); }); - await buildViewerReport(); - const app = new GhPagesApp({ name: 'viewer', appDir: `${LH_ROOT}/lighthouse-viewer/app`, @@ -49,8 +46,7 @@ async function run() { await generatorJsPromise, fs.readFileSync(require.resolve('idb-keyval/dist/idb-keyval-min.js'), 'utf8'), fs.readFileSync(require.resolve('pako/dist/pako_inflate.js'), 'utf-8'), - {path: '../../dist/report/viewer.js'}, - {path: 'src/*'}, + {path: 'src/main.js', rollup: true}, ], assets: [ {path: 'images/**/*'}, diff --git a/build/gh-pages-app.js b/build/gh-pages-app.js index 06268cc5a54a..9456151ca589 100644 --- a/build/gh-pages-app.js +++ b/build/gh-pages-app.js @@ -7,6 +7,12 @@ const fs = require('fs'); const path = require('path'); +const rollup = require('rollup'); +const commonjs = + // @ts-expect-error types are wrong. + /** @type {import('rollup-plugin-commonjs').default} */ (require('rollup-plugin-commonjs')); +const {terser: rollupTerser} = require('rollup-plugin-terser'); +const {nodeResolve} = require('@rollup/plugin-node-resolve'); const cpy = require('cpy'); const ghPages = require('gh-pages'); const glob = require('glob'); @@ -35,7 +41,7 @@ const license = `/* /** * Literal string (representing JS, CSS, etc...), or an object with a path, which would * be interpreted relative to opts.appDir and be glob-able. - * @typedef {{path: string} | string} Source + * @typedef {{path: string, rollup?: boolean} | string} Source */ /** @@ -83,10 +89,10 @@ class GhPagesApp { fs.mkdirSync(this.distDir, {recursive: true}); // Ensure dist is present, else rmdir will throw. COMPAT: when dropping Node 12, replace with fs.rm(p, {force: true}) fs.rmdirSync(this.distDir, {recursive: true}); - const html = this._compileHtml(); + const html = await this._compileHtml(); safeWriteFile(`${this.distDir}/index.html`, html); - const css = this._compileCss(); + const css = await this._compileCss(); safeWriteFile(`${this.distDir}/styles/bundled.css`, css); const bundledJs = await this._compileJs(); @@ -116,13 +122,16 @@ class GhPagesApp { /** * @param {Source[]} sources + * @return {Promise} */ - _resolveSourcesList(sources) { + async _resolveSourcesList(sources) { const result = []; for (const source of sources) { if (typeof source === 'string') { result.push(source); + } else if (source.rollup) { + result.push(await this._rollupSource(`${this.opts.appDir}/${source.path}`)); } else { result.push(...loadFiles(`${this.opts.appDir}/${source.path}`)); } @@ -131,8 +140,27 @@ class GhPagesApp { return result; } - _compileHtml() { - let htmlSrc = this._resolveSourcesList([this.opts.html])[0]; + /** + * @param {string} input + * @return {Promise} + */ + async _rollupSource(input) { + const plugins = [ + nodeResolve(), + commonjs(), + ]; + if (!process.env.DEBUG) plugins.push(rollupTerser()); + const bundle = await rollup.rollup({ + input, + plugins, + }); + const {output} = await bundle.generate({format: 'iife'}); + return output[0].code; + } + + async _compileHtml() { + const resolvedSources = await this._resolveSourcesList([this.opts.html]); + let htmlSrc = resolvedSources[0]; if (this.opts.htmlReplacements) { for (const [key, value] of Object.entries(this.opts.htmlReplacements)) { @@ -143,8 +171,9 @@ class GhPagesApp { return htmlSrc; } - _compileCss() { - return this._resolveSourcesList(this.opts.stylesheets).join('\n'); + async _compileCss() { + const resolvedSources = await this._resolveSourcesList(this.opts.stylesheets); + return resolvedSources.join('\n'); } async _compileJs() { @@ -154,7 +183,7 @@ class GhPagesApp { const contents = [ `"use strict";`, versionJs, - ...this._resolveSourcesList(this.opts.javascripts), + ...await this._resolveSourcesList(this.opts.javascripts), ]; if (process.env.DEBUG) return contents.join('\n'); diff --git a/lighthouse-viewer/app/index.html b/lighthouse-viewer/app/index.html index 9783c8d122ba..19f6ecbc595a 100644 --- a/lighthouse-viewer/app/index.html +++ b/lighthouse-viewer/app/index.html @@ -59,9 +59,6 @@

Lighthouse Report Viewer

-