From b3ff9eb7aa376524feecbe685746210a72e81c28 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Mon, 1 Nov 2021 10:34:14 -0700 Subject: [PATCH] misc(build): use rollup to build lighthouse-core bundles (#12771) --- build/banner.txt | 7 - build/build-bundle.js | 273 +++++++++--------- build/build-lightrider-bundles.js | 7 +- build/rollup-plugins.js | 6 + clients/devtools-entry.js | 7 + clients/lightrider/lightrider-entry.js | 6 + .../smokehouse/lighthouse-runners/bundle.js | 6 +- lighthouse-cli/test/smokehouse/smokehouse.js | 2 +- .../metrics/lantern-total-blocking-time.js | 7 +- lighthouse-core/computed/metrics/tbt-utils.js | 57 ++++ .../computed/metrics/total-blocking-time.js | 56 +--- lighthouse-core/config/config-helpers.js | 30 +- .../fraggle-rock/gather/base-gatherer.js | 7 +- .../dobetterweb/response-compression.js | 1 + lighthouse-core/lib/asset-saver.js | 5 +- lighthouse-core/lib/lh-env.js | 2 + lighthouse-core/lib/tappable-rects.js | 23 +- lighthouse-core/runner.js | 2 +- .../metrics/total-blocking-time-test.js | 21 +- lighthouse-logger/index.js | 3 +- package.json | 13 +- report/clients/standalone.js | 2 - .../renderer/element-screenshot-renderer.js | 4 +- shared/localization/format.js | 13 +- .../lighthouse-successful-run-expected.txt | 84 +++--- types/rollup-plugin-postprocess.d.ts | 10 + yarn.lock | 185 +++++------- 27 files changed, 427 insertions(+), 412 deletions(-) delete mode 100644 build/banner.txt create mode 100644 lighthouse-core/computed/metrics/tbt-utils.js create mode 100644 types/rollup-plugin-postprocess.d.ts diff --git a/build/banner.txt b/build/banner.txt deleted file mode 100644 index 49f4660c541c..000000000000 --- a/build/banner.txt +++ /dev/null @@ -1,7 +0,0 @@ -<%= _.startCase(pkg.name) %> v<%= pkg.version %> <%= pkg.COMMIT_HASH %> (<%= moment().format('MMMM Do YYYY') %>) - -<%= pkg.description %> - -@homepage <%= pkg.homepage %> -@author <%= pkg.author %> -@license <%= pkg.license %> diff --git a/build/build-bundle.js b/build/build-bundle.js index 2baace0a7cbb..be723f3cf5a4 100644 --- a/build/build-bundle.js +++ b/build/build-bundle.js @@ -12,25 +12,15 @@ const fs = require('fs'); const path = require('path'); -const assert = require('assert').strict; -const mkdir = fs.promises.mkdir; -const LighthouseRunner = require('../lighthouse-core/runner.js'); -const exorcist = require('exorcist'); -const browserify = require('browserify'); -const terser = require('terser'); - -const inlineFs = require('./plugins/browserify-inline-fs.js'); +const rollup = require('rollup'); +const rollupPlugins = require('./rollup-plugins.js'); +const Runner = require('../lighthouse-core/runner.js'); +const {LH_ROOT} = require('../root.js'); const COMMIT_HASH = require('child_process') .execSync('git rev-parse HEAD') .toString().trim(); -const audits = LighthouseRunner.getAuditList() - .map(f => './lighthouse-core/audits/' + f.replace(/\.js$/, '')); - -const gatherers = LighthouseRunner.getGathererList() - .map(f => './lighthouse-core/gather/gatherers/' + f.replace(/\.js$/, '')); - // HACK: manually include the lighthouse-plugin-publisher-ads audits. /** @type {Array} */ // @ts-expect-error @@ -45,144 +35,167 @@ const isLightrider = file => path.basename(file).includes('lightrider'); // Set to true for source maps. const DEBUG = false; +const today = (() => { + const date = new Date(); + const year = new Intl.DateTimeFormat('en', {year: 'numeric'}).format(date); + const month = new Intl.DateTimeFormat('en', {month: 'short'}).format(date); + const day = new Intl.DateTimeFormat('en', {day: '2-digit'}).format(date); + return `${month} ${day} ${year}`; +})(); +const pkg = JSON.parse(fs.readFileSync(LH_ROOT + '/package.json', 'utf-8')); +const banner = ` +/** + * Lighthouse v${pkg.version} ${COMMIT_HASH} (${today}) + * + * ${pkg.description} + * + * @homepage ${pkg.homepage} + * @author ${pkg.author} + * @license ${pkg.license} + */ +`.trim(); + /** - * Browserify starting at the file at entryPath. Contains entry-point-specific - * ignores (e.g. for DevTools or the extension) to trim the bundle depending on - * the eventual use case. + * Bundle starting at entryPath, writing the minified result to distPath. * @param {string} entryPath * @param {string} distPath + * @param {{minify: boolean}=} opts * @return {Promise} */ -async function browserifyFile(entryPath, distPath) { - let bundle = browserify(entryPath, {debug: DEBUG}); - - bundle - .plugin('browserify-banner', { - pkg: Object.assign({COMMIT_HASH}, require('../package.json')), - file: require.resolve('./banner.txt'), - }) - // Transform `fs.readFileSync`, etc into inline strings. - .transform(inlineFs({verbose: DEBUG})) - // Strip everything out of package.json includes except for the version. - .transform('package-json-versionify'); - - // scripts will need some additional transforms, ignores and requires… - bundle.ignore('source-map') - .ignore('debug/node') - .ignore('intl') - .ignore('intl-pluralrules') - .ignore('raven') - .ignore('pako/lib/zlib/inflate.js'); - - // Don't include the desktop protocol connection. - bundle.ignore(require.resolve('../lighthouse-core/gather/connections/cri.js')); - - // Don't include the stringified report in DevTools - see devtools-report-assets.js - // Don't include in Lightrider - HTML generation isn't supported, so report assets aren't needed. - if (isDevtools(entryPath) || isLightrider(entryPath)) { - bundle.ignore(require.resolve('../report/generator/report-assets.js')); +async function build(entryPath, distPath, opts = {minify: true}) { + if (fs.existsSync(LH_ROOT + '/lighthouse-logger/node_modules')) { + throw new Error('delete `lighthouse-logger/node_modules` because it messes up rollup bundle'); } - // Don't include locales in DevTools. - if (isDevtools(entryPath)) { - bundle.ignore(require.resolve('../shared/localization/locales.js')); - } + // List of paths (absolute / relative to config-helpers.js) to include + // in bundle and make accessible via config-helpers.js `requireWrapper`. + const dynamicModulePaths = [ + ...Runner.getGathererList().map(gatherer => `../gather/gatherers/${gatherer}`), + ...Runner.getAuditList().map(gatherer => `../audits/${gatherer}`), + ]; - // Expose the audits, gatherers, and computed artifacts so they can be dynamically loaded. - // Exposed path must be a relative path from lighthouse-core/config/config-helpers.js (where loading occurs). - const corePath = './lighthouse-core/'; - const driverPath = `${corePath}gather/`; - audits.forEach(audit => { - bundle = bundle.require(audit, {expose: audit.replace(corePath, '../')}); - }); - gatherers.forEach(gatherer => { - bundle = bundle.require(gatherer, {expose: gatherer.replace(driverPath, '../gather/')}); - }); - - // HACK: manually include the lighthouse-plugin-publisher-ads audits. + // Include lighthouse-plugin-publisher-ads. if (isDevtools(entryPath) || isLightrider(entryPath)) { - bundle.require('lighthouse-plugin-publisher-ads'); + dynamicModulePaths.push('lighthouse-plugin-publisher-ads'); pubAdsAudits.forEach(pubAdAudit => { - bundle = bundle.require(pubAdAudit); + dynamicModulePaths.push(pubAdAudit); }); } - // browerify's url shim doesn't work with .URL in node_modules, - // and within robots-parser, it does `var URL = require('url').URL`, so we expose our own. - // @see https://github.com/GoogleChrome/lighthouse/issues/5273 - const pathToURLShim = require.resolve('../lighthouse-core/lib/url-shim.js'); - bundle = bundle.require(pathToURLShim, {expose: 'url'}); - - let bundleStream = bundle.bundle(); + const bundledMapEntriesCode = dynamicModulePaths.map(modulePath => { + const pathNoExt = modulePath.replace('.js', ''); + return `['${pathNoExt}', require('${modulePath}')]`; + }).join(',\n'); - // Make sure path exists. - await mkdir(path.dirname(distPath), {recursive: true}); - await new Promise((resolve, reject) => { - const writeStream = fs.createWriteStream(distPath); - writeStream.on('finish', resolve); - writeStream.on('error', reject); + /** @type {Record} */ + const shimsObj = {}; - // Extract the inline source map to an external file. - if (DEBUG) bundleStream = bundleStream.pipe(exorcist(`${distPath}.map`)); - bundleStream.pipe(writeStream); - }); + const modulesToIgnore = [ + 'intl-pluralrules', + 'intl', + 'pako/lib/zlib/inflate.js', + 'raven', + 'source-map', + 'ws', + require.resolve('../lighthouse-core/gather/connections/cri.js'), + ]; - if (isDevtools(distPath)) { - let code = fs.readFileSync(distPath, 'utf-8'); - // Add a comment for TypeScript, but not if in DEBUG mode so that source maps are not affected. - // See lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js - if (!DEBUG) { - code = '// @ts-nocheck - Prevent tsc stepping into any required bundles.\n' + code; - } + // Don't include the stringified report in DevTools - see devtools-report-assets.js + // Don't include in Lightrider - HTML generation isn't supported, so report assets aren't needed. + if (isDevtools(entryPath) || isLightrider(entryPath)) { + modulesToIgnore.push(require.resolve('../report/generator/report-assets.js')); + } - // DevTools build system expects `globalThis` rather than setting global variables. - assert.ok(code.includes('\nrequire='), 'missing browserify require stub'); - code = code.replace('\nrequire=', '\nglobalThis.require='); - assert.ok(!code.includes('\nrequire='), 'contained unexpected browserify require stub'); + // Don't include locales in DevTools. + if (isDevtools(entryPath)) { + shimsObj['./locales.js'] = 'export default {}'; + } - fs.writeFileSync(distPath, code); + for (const modulePath of modulesToIgnore) { + shimsObj[modulePath] = 'export default {}'; } -} -/** - * Minify a javascript file, in place. - * @param {string} filePath - */ -async function minifyScript(filePath) { - const code = fs.readFileSync(filePath, 'utf-8'); - const result = await terser.minify(code, { - ecma: 2019, - output: { - comments: /^!|Prevent tsc/, - max_line_len: 1000, - }, - // The config relies on class names for gatherers. - keep_classnames: true, - // Runtime.evaluate errors if function names are elided. - keep_fnames: true, - sourceMap: DEBUG && { - content: JSON.parse(fs.readFileSync(`${filePath}.map`, 'utf-8')), - url: path.basename(`${filePath}.map`), - }, + shimsObj[require.resolve('../package.json')] = + `export const version = ${JSON.stringify(require('../package.json').version)}`; + + const bundle = await rollup.rollup({ + input: entryPath, + context: 'globalThis', + plugins: [ + rollupPlugins.replace({ + delimiters: ['', ''], + values: { + '/* BUILD_REPLACE_BUNDLED_MODULES */': `[\n${bundledMapEntriesCode},\n]`, + '__dirname': (id) => `'${path.relative(LH_ROOT, path.dirname(id))}'`, + '__filename': (id) => `'${path.relative(LH_ROOT, id)}'`, + // This package exports to default in a way that causes Rollup to get confused, + // resulting in MessageFormat being undefined. + 'require(\'intl-messageformat\').default': 'require(\'intl-messageformat\')', + // Rollup doesn't replace this, so let's manually change it to false. + 'require.main === module': 'false', + // TODO: Use globalThis directly. + 'global.isLightrider': 'globalThis.isLightrider', + 'global.isDevtools': 'globalThis.isDevtools', + }, + }), + rollupPlugins.alias({ + entries: { + 'debug': require.resolve('debug/src/browser.js'), + 'lighthouse-logger': require.resolve('../lighthouse-logger/index.js'), + 'url': require.resolve('../lighthouse-core/lib/url-shim.js'), + }, + }), + rollupPlugins.shim({ + ...shimsObj, + // Allows for plugins to import lighthouse. + 'lighthouse': ` + import Audit from '${require.resolve('../lighthouse-core/audits/audit.js')}'; + export {Audit}; + `, + }), + rollupPlugins.json(), + rollupPlugins.inlineFs({verbose: false}), + rollupPlugins.commonjs({ + // https://github.com/rollup/plugins/issues/922 + ignoreGlobal: true, + }), + rollupPlugins.nodePolyfills(), + rollupPlugins.nodeResolve({preferBuiltins: true}), + // Rollup sees the usages of these functions in page functions (ex: see AnchorElements) + // and treats them as globals. Because the names are "taken" by the global, Rollup renames + // the actual functions (getNodeDetails$1). The page functions expect a certain name, so + // here we undo what Rollup did. + rollupPlugins.postprocess([ + [/getBoundingClientRect\$1/, 'getBoundingClientRect'], + [/getElementsInDocument\$1/, 'getElementsInDocument'], + [/getNodeDetails\$1/, 'getNodeDetails'], + [/getRectCenterPoint\$1/, 'getRectCenterPoint'], + [/isPositionFixed\$1/, 'isPositionFixed'], + ]), + opts.minify && rollupPlugins.terser({ + ecma: 2019, + output: { + comments: (node, comment) => { + const text = comment.value; + if (text.includes('The Lighthouse Authors') && comment.line > 1) return false; + return /@ts-nocheck - Prevent tsc|@preserve|@license|@cc_on|^!/i.test(text); + }, + max_line_len: 1000, + }, + // The config relies on class names for gatherers. + keep_classnames: true, + // Runtime.evaluate errors if function names are elided. + keep_fnames: true, + }), + ], }); - if (result.code) { - fs.writeFileSync(filePath, result.code); - } - if (DEBUG && typeof result.map === 'string') { - fs.writeFileSync(`${filePath}.map`, result.map); - } -} - -/** - * Browserify starting at entryPath, writing the minified result to distPath. - * @param {string} entryPath - * @param {string} distPath - * @return {Promise} - */ -async function build(entryPath, distPath) { - await browserifyFile(entryPath, distPath); - await minifyScript(distPath); + await bundle.write({ + file: distPath, + banner, + format: 'iife', + sourcemap: DEBUG, + }); } /** diff --git a/build/build-lightrider-bundles.js b/build/build-lightrider-bundles.js index cc3869e89244..3fcf2ca760f3 100644 --- a/build/build-lightrider-bundles.js +++ b/build/build-lightrider-bundles.js @@ -23,15 +23,12 @@ const generatorFilename = `./report/generator/report-generator.js`; const entrySourceName = 'lightrider-entry.js'; const entryDistName = 'lighthouse-lr-bundle.js'; -fs.mkdirSync(path.dirname(distDir), {recursive: true}); +fs.mkdirSync(distDir, {recursive: true}); -/** - * Browserify and minify entry point. - */ function buildEntryPoint() { const inFile = `${sourceDir}/${entrySourceName}`; const outFile = `${distDir}/${entryDistName}`; - return bundleBuilder.build(inFile, outFile); + return bundleBuilder.build(inFile, outFile, {minify: false}); } /** diff --git a/build/rollup-plugins.js b/build/rollup-plugins.js index 866645fa13b3..9335253174b4 100644 --- a/build/rollup-plugins.js +++ b/build/rollup-plugins.js @@ -16,9 +16,12 @@ function rollupPluginTypeCoerce(module) { return module; } +const alias = rollupPluginTypeCoerce(require('@rollup/plugin-alias')); const commonjs = rollupPluginTypeCoerce(require('@rollup/plugin-commonjs')); +const json = rollupPluginTypeCoerce(require('@rollup/plugin-json')); const nodePolyfills = rollupPluginTypeCoerce(require('rollup-plugin-polyfill-node')); const {nodeResolve} = require('@rollup/plugin-node-resolve'); +const postprocess = require('@stadtlandnetz/rollup-plugin-postprocess'); const replace = rollupPluginTypeCoerce(require('rollup-plugin-replace')); // @ts-expect-error: no published types. const shim = require('rollup-plugin-shim'); @@ -28,10 +31,13 @@ const typescript = rollupPluginTypeCoerce(require('@rollup/plugin-typescript')); const inlineFs = require('./plugins/rollup-plugin-inline-fs.js'); module.exports = { + alias, commonjs, inlineFs, + json, nodePolyfills, nodeResolve, + postprocess, replace, shim, terser, diff --git a/clients/devtools-entry.js b/clients/devtools-entry.js index 6869e00f2dd2..21299cf96139 100644 --- a/clients/devtools-entry.js +++ b/clients/devtools-entry.js @@ -5,6 +5,8 @@ */ 'use strict'; +/* global globalThis */ + const lighthouse = require('../lighthouse-core/index.js'); const RawProtocol = require('../lighthouse-core/gather/connections/raw.js'); const log = require('lighthouse-logger'); @@ -14,6 +16,11 @@ const constants = require('../lighthouse-core/config/constants.js'); /** @typedef {import('../lighthouse-core/gather/connections/connection.js')} Connection */ +// Rollup seems to overlook some references to `Buffer`, so it must be made explicit. +// (`parseSourceMapFromDataUrl` breaks without this) +/** @type {BufferConstructor} */ +globalThis.Buffer = require('buffer').Buffer; + /** * Returns a config, which runs only certain categories. * Varies the config to use based on device. diff --git a/clients/lightrider/lightrider-entry.js b/clients/lightrider/lightrider-entry.js index 9778337533f5..8859c2072efb 100644 --- a/clients/lightrider/lightrider-entry.js +++ b/clients/lightrider/lightrider-entry.js @@ -5,6 +5,8 @@ */ 'use strict'; +/* global globalThis */ + const lighthouse = require('../../lighthouse-core/index.js'); const LHError = require('../../lighthouse-core/lib/lh-error.js'); @@ -19,6 +21,10 @@ const LR_PRESETS = { /** @typedef {import('../../lighthouse-core/gather/connections/connection.js')} Connection */ +// Rollup seems to overlook some references to `Buffer`, so it must be made explicit. +// (`parseSourceMapFromDataUrl` breaks without this) +globalThis.Buffer = require('buffer').Buffer; + /** * Run lighthouse for connection and provide similar results as in CLI. * diff --git a/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js b/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js index 41d0689b1458..395312680f19 100644 --- a/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +++ b/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js @@ -11,9 +11,12 @@ * Currently uses `lighthouse-dt-bundle.js`. */ +import fs from 'fs'; + import ChromeLauncher from 'chrome-launcher'; import ChromeProtocol from '../../../../lighthouse-core/gather/connections/cri.js'; +import {LH_ROOT} from '../../../../root.js'; const originalRequire = global.require; if (typeof globalThis === 'undefined') { @@ -22,8 +25,7 @@ if (typeof globalThis === 'undefined') { } // Load bundle, which creates a `global.runBundledLighthouse`. -// @ts-ignore - file exists if `yarn build-all` is run, but not used for types anyways. -import '../../../../dist/lighthouse-dt-bundle.js'; // eslint-disable-line +eval(fs.readFileSync(LH_ROOT + '/dist/lighthouse-dt-bundle.js', 'utf-8')); global.require = originalRequire; diff --git a/lighthouse-cli/test/smokehouse/smokehouse.js b/lighthouse-cli/test/smokehouse/smokehouse.js index cef142c01cf0..59c616aa3fa4 100644 --- a/lighthouse-cli/test/smokehouse/smokehouse.js +++ b/lighthouse-cli/test/smokehouse/smokehouse.js @@ -215,7 +215,7 @@ function logChildProcessError(localConsole, err) { localConsole.adoptStdStrings(err); } - localConsole.log(log.redify('Error: ') + err.message); + localConsole.log(log.redify('Error: ') + err + '\n' + err.stack); } /** diff --git a/lighthouse-core/computed/metrics/lantern-total-blocking-time.js b/lighthouse-core/computed/metrics/lantern-total-blocking-time.js index 082625327cbf..0bff853cf216 100644 --- a/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +++ b/lighthouse-core/computed/metrics/lantern-total-blocking-time.js @@ -10,6 +10,7 @@ const LanternMetric = require('./lantern-metric.js'); const BaseNode = require('../../lib/dependency-graph/base-node.js'); const LanternFirstContentfulPaint = require('./lantern-first-contentful-paint.js'); const LanternInteractive = require('./lantern-interactive.js'); +const {BLOCKING_TIME_THRESHOLD, calculateSumOfBlockingTime} = require('./tbt-utils.js'); /** @typedef {BaseNode.Node} Node */ @@ -66,9 +67,7 @@ class LanternTotalBlockingTime extends LanternMetric { ? extras.interactiveResult.optimisticEstimate.timeInMs : extras.interactiveResult.pessimisticEstimate.timeInMs; - // Require here to resolve circular dependency. - const TotalBlockingTime = require('./total-blocking-time.js'); - const minDurationMs = TotalBlockingTime.BLOCKING_TIME_THRESHOLD; + const minDurationMs = BLOCKING_TIME_THRESHOLD; const events = LanternTotalBlockingTime.getTopLevelEvents( simulation.nodeTimings, @@ -76,7 +75,7 @@ class LanternTotalBlockingTime extends LanternMetric { ); return { - timeInMs: TotalBlockingTime.calculateSumOfBlockingTime( + timeInMs: calculateSumOfBlockingTime( events, fcpTimeInMs, interactiveTimeMs diff --git a/lighthouse-core/computed/metrics/tbt-utils.js b/lighthouse-core/computed/metrics/tbt-utils.js new file mode 100644 index 000000000000..657d9a976216 --- /dev/null +++ b/lighthouse-core/computed/metrics/tbt-utils.js @@ -0,0 +1,57 @@ +/** + * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +const BLOCKING_TIME_THRESHOLD = 50; + +/** + * @param {Array<{start: number, end: number, duration: number}>} topLevelEvents + * @param {number} startTimeMs + * @param {number} endTimeMs + * @return {number} + */ +function calculateSumOfBlockingTime(topLevelEvents, startTimeMs, endTimeMs) { + if (endTimeMs <= startTimeMs) return 0; + + const threshold = BLOCKING_TIME_THRESHOLD; + let sumBlockingTime = 0; + for (const event of topLevelEvents) { + // Early exit for small tasks, which should far outnumber long tasks. + if (event.duration < threshold) continue; + + // We only want to consider tasks that fall in our time range (FCP and TTI for navigations). + // FCP is picked as the lower bound because there is little risk of user input happening + // before FCP so Long Queuing Qelay regions do not harm user experience. Developers should be + // optimizing to reach FCP as fast as possible without having to worry about task lengths. + if (event.end < startTimeMs) continue; + + // TTI is picked as the upper bound because we want a well defined end point for page load. + if (event.start > endTimeMs) continue; + + // We first perform the clipping, and then calculate Blocking Region. So if we have a 150ms + // task [0, 150] and FCP happens midway at 50ms, we first clip the task to [50, 150], and then + // calculate the Blocking Region to be [100, 150]. The rational here is that tasks before FCP + // are unimportant, so we care whether the main thread is busy more than 50ms at a time only + // after FCP. + const clippedStart = Math.max(event.start, startTimeMs); + const clippedEnd = Math.min(event.end, endTimeMs); + const clippedDuration = clippedEnd - clippedStart; + if (clippedDuration < threshold) continue; + + // The duration of the task beyond 50ms at the beginning is considered the Blocking Region. + // Example: + // [ 250ms Task ] + // | First 50ms | Blocking Region (200ms) | + sumBlockingTime += clippedDuration - threshold; + } + + return sumBlockingTime; +} + +module.exports = { + BLOCKING_TIME_THRESHOLD, + calculateSumOfBlockingTime, +}; diff --git a/lighthouse-core/computed/metrics/total-blocking-time.js b/lighthouse-core/computed/metrics/total-blocking-time.js index c9d26cd5bd00..017444ef706a 100644 --- a/lighthouse-core/computed/metrics/total-blocking-time.js +++ b/lighthouse-core/computed/metrics/total-blocking-time.js @@ -10,6 +10,7 @@ const ComputedMetric = require('./metric.js'); const TraceProcessor = require('../../lib/tracehouse/trace-processor.js'); const LanternTotalBlockingTime = require('./lantern-total-blocking-time.js'); const TimetoInteractive = require('./interactive.js'); +const {calculateSumOfBlockingTime} = require('./tbt-utils.js'); /** * @fileoverview This audit determines Total Blocking Time. @@ -25,57 +26,6 @@ const TimetoInteractive = require('./interactive.js'); * to smaller improvements to main thread responsiveness. */ class TotalBlockingTime extends ComputedMetric { - /** - * @return {number} - */ - static get BLOCKING_TIME_THRESHOLD() { - return 50; - } - - /** - * @param {Array<{start: number, end: number, duration: number}>} topLevelEvents - * @param {number} startTimeMs - * @param {number} endTimeMs - * @return {number} - */ - static calculateSumOfBlockingTime(topLevelEvents, startTimeMs, endTimeMs) { - if (endTimeMs <= startTimeMs) return 0; - - const threshold = TotalBlockingTime.BLOCKING_TIME_THRESHOLD; - let sumBlockingTime = 0; - for (const event of topLevelEvents) { - // Early exit for small tasks, which should far outnumber long tasks. - if (event.duration < threshold) continue; - - // We only want to consider tasks that fall in our time range (FCP and TTI for navigations). - // FCP is picked as the lower bound because there is little risk of user input happening - // before FCP so Long Queuing Qelay regions do not harm user experience. Developers should be - // optimizing to reach FCP as fast as possible without having to worry about task lengths. - if (event.end < startTimeMs) continue; - - // TTI is picked as the upper bound because we want a well defined end point for page load. - if (event.start > endTimeMs) continue; - - // We first perform the clipping, and then calculate Blocking Region. So if we have a 150ms - // task [0, 150] and FCP happens midway at 50ms, we first clip the task to [50, 150], and then - // calculate the Blocking Region to be [100, 150]. The rational here is that tasks before FCP - // are unimportant, so we care whether the main thread is busy more than 50ms at a time only - // after FCP. - const clippedStart = Math.max(event.start, startTimeMs); - const clippedEnd = Math.min(event.end, endTimeMs); - const clippedDuration = clippedEnd - clippedStart; - if (clippedDuration < threshold) continue; - - // The duration of the task beyond 50ms at the beginning is considered the Blocking Region. - // Example: - // [ 250ms Task ] - // | First 50ms | Blocking Region (200ms) | - sumBlockingTime += clippedDuration - threshold; - } - - return sumBlockingTime; - } - /** * @param {LH.Artifacts.MetricComputationData} data * @param {LH.Artifacts.ComputedContext} context @@ -100,7 +50,7 @@ class TotalBlockingTime extends ComputedMetric { const interactiveTimeMs = (await TimetoInteractive.request(metricData, context)).timing; return { - timing: TotalBlockingTime.calculateSumOfBlockingTime( + timing: calculateSumOfBlockingTime( events, firstContentfulPaint, interactiveTimeMs @@ -108,7 +58,7 @@ class TotalBlockingTime extends ComputedMetric { }; } else { return { - timing: TotalBlockingTime.calculateSumOfBlockingTime( + timing: calculateSumOfBlockingTime( events, 0, data.processedTrace.timestamps.traceEnd diff --git a/lighthouse-core/config/config-helpers.js b/lighthouse-core/config/config-helpers.js index 1dbb0d0c6a64..a5138a3f6169 100644 --- a/lighthouse-core/config/config-helpers.js +++ b/lighthouse-core/config/config-helpers.js @@ -203,6 +203,18 @@ function expandAuditShorthand(audit) { } } +/** @type {Map} */ +const bundledModules = new Map(/* BUILD_REPLACE_BUNDLED_MODULES */); + +/** + * Wraps `require` with an entrypoint for bundled dynamic modules. + * See build-bundle.js + * @param {string} requirePath + */ +function requireWrapper(requirePath) { + return bundledModules.get(requirePath) || require(requirePath); +} + /** * @param {string} gathererPath * @param {Array} coreGathererList @@ -218,7 +230,7 @@ function requireGatherer(gathererPath, coreGathererList, configDir) { requirePath = resolveModulePath(gathererPath, configDir, 'gatherer'); } - const GathererClass = /** @type {GathererConstructor} */ (require(requirePath)); + const GathererClass = /** @type {GathererConstructor} */ (requireWrapper(requirePath)); return { instance: new GathererClass(), @@ -228,14 +240,13 @@ function requireGatherer(gathererPath, coreGathererList, configDir) { } /** - * * @param {string} auditPath * @param {Array} coreAuditList * @param {string=} configDir * @return {LH.Config.AuditDefn['implementation']} */ function requireAudit(auditPath, coreAuditList, configDir) { -// See if the audit is a Lighthouse core audit. + // See if the audit is a Lighthouse core audit. const auditPathJs = `${auditPath}.js`; const coreAudit = coreAuditList.find(a => a === auditPathJs); let requirePath = `../audits/${auditPath}`; @@ -244,14 +255,14 @@ function requireAudit(auditPath, coreAuditList, configDir) { // This is for pubads bundling. requirePath = auditPath; } else { - // Otherwise, attempt to find it elsewhere. This throws if not found. + // Otherwise, attempt to find it elsewhere. This throws if not found. const absolutePath = resolveModulePath(auditPath, configDir, 'audit'); // Use a relative path so bundler can easily expose it. requirePath = path.relative(__dirname, absolutePath); } } - return require(requirePath); + return requireWrapper(requirePath); } /** @@ -313,7 +324,6 @@ function resolveSettings(settingsJson = {}, overrides = undefined) { return settingsWithFlags; } - /** * @param {LH.Config.Json} configJSON * @param {string | undefined} configDir @@ -332,7 +342,7 @@ function mergePlugins(configJSON, configDir, flags) { const pluginPath = isBundledEnvironment() ? pluginName : resolveModulePath(pluginName, configDir, 'plugin'); - const rawPluginJson = require(pluginPath); + const rawPluginJson = requireWrapper(pluginPath); const pluginJson = ConfigPlugin.parsePlugin(rawPluginJson, pluginName); configJSON = mergeConfigFragment(configJSON, pluginJson); @@ -569,12 +579,12 @@ function deepCloneConfigJson(json) { module.exports = { deepClone, deepCloneConfigJson, - mergeOptionsOfItems, mergeConfigFragment, mergeConfigFragmentArrayByKey, + mergeOptionsOfItems, mergePlugins, - resolveSettings, - resolveGathererToDefn, resolveAuditsToDefns, + resolveGathererToDefn, resolveModulePath, + resolveSettings, }; diff --git a/lighthouse-core/fraggle-rock/gather/base-gatherer.js b/lighthouse-core/fraggle-rock/gather/base-gatherer.js index 901192beb9f9..337a99a5a3ec 100644 --- a/lighthouse-core/fraggle-rock/gather/base-gatherer.js +++ b/lighthouse-core/fraggle-rock/gather/base-gatherer.js @@ -62,8 +62,13 @@ class FRGatherer { * @return {keyof LH.GathererArtifacts} */ get name() { + let name = this.constructor.name; + // Rollup will mangle class names in an known way–just trim until `$`. + if (name.includes('$')) { + name = name.substr(0, name.indexOf('$')); + } // @ts-expect-error - assume that class name has been added to LH.GathererArtifacts. - return this.constructor.name; + return name; } /** diff --git a/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js b/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js index 45a0fb0d37c8..249b0f9f7605 100644 --- a/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js +++ b/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js @@ -10,6 +10,7 @@ */ 'use strict'; +const {Buffer} = require('buffer'); const FRGatherer = require('../../../fraggle-rock/gather/base-gatherer.js'); const URL = require('../../../lib/url-shim.js'); const Sentry = require('../../../lib/sentry.js'); diff --git a/lighthouse-core/lib/asset-saver.js b/lighthouse-core/lib/asset-saver.js index 23c29e8b0d86..57859af26c5f 100644 --- a/lighthouse-core/lib/asset-saver.js +++ b/lighthouse-core/lib/asset-saver.js @@ -16,7 +16,10 @@ const Metrics = require('./traces/pwmetrics-events.js'); const NetworkAnalysisComputed = require('../computed/network-analysis.js'); const LoadSimulatorComputed = require('../computed/load-simulator.js'); const LHError = require('../lib/lh-error.js'); -const pipeline = promisify(stream.pipeline); +// TODO(esmodules): Rollup does not support `promisfy` or `stream.pipeline`. Bundled files +// don't need anything in this file except for `stringifyReplacer`, so a check for +// truthiness before using is enough. +const pipeline = promisify && promisify(stream.pipeline); const artifactsFilename = 'artifacts.json'; const traceSuffix = '.trace.json'; diff --git a/lighthouse-core/lib/lh-env.js b/lighthouse-core/lib/lh-env.js index ec0bf6c494d5..fac8fd29ab47 100644 --- a/lighthouse-core/lib/lh-env.js +++ b/lighthouse-core/lib/lh-env.js @@ -5,6 +5,8 @@ */ 'use strict'; +const process = require('process'); + module.exports = { // NODE_ENV is set to test by jest and by smokehouse CLI runner // CI as a catchall for everything we do in GitHub Actions diff --git a/lighthouse-core/lib/tappable-rects.js b/lighthouse-core/lib/tappable-rects.js index 3af779b8cd4a..73566ec3c830 100644 --- a/lighthouse-core/lib/tappable-rects.js +++ b/lighthouse-core/lib/tappable-rects.js @@ -5,14 +5,7 @@ */ 'use strict'; -const { - filterOutRectsContainedByOthers, - filterOutTinyRects, - rectsTouchOrOverlap, - rectContainsPoint, - getBoundingRect, - getRectCenterPoint, -} = require('./rect-helpers.js'); +const RectHelpers = require('./rect-helpers.js'); /** * Merge client rects together and remove small ones. This may result in a larger overall @@ -23,8 +16,8 @@ const { function getTappableRectsFromClientRects(clientRects) { // 1x1px rect shouldn't be reason to treat the rect as something the user should tap on. // Often they're made invisble in some obscure way anyway, and only exist for e.g. accessibiliity. - clientRects = filterOutTinyRects(clientRects); - clientRects = filterOutRectsContainedByOthers(clientRects); + clientRects = RectHelpers.filterOutTinyRects(clientRects); + clientRects = RectHelpers.filterOutRectsContainedByOthers(clientRects); clientRects = mergeTouchingClientRects(clientRects); return clientRects; } @@ -68,17 +61,17 @@ function mergeTouchingClientRects(clientRects) { const rectsLineUpVertically = almostEqual(crA.left, crB.left) || almostEqual(crA.right, crB.right); const canMerge = - rectsTouchOrOverlap(crA, crB) && + RectHelpers.rectsTouchOrOverlap(crA, crB) && (rectsLineUpHorizontally || rectsLineUpVertically); if (canMerge) { - const replacementClientRect = getBoundingRect([crA, crB]); - const mergedRectCenter = getRectCenterPoint(replacementClientRect); + const replacementClientRect = RectHelpers.getBoundingRect([crA, crB]); + const mergedRectCenter = RectHelpers.getRectCenterPoint(replacementClientRect); if ( !( - rectContainsPoint(crA, mergedRectCenter) || - rectContainsPoint(crB, mergedRectCenter) + RectHelpers.rectContainsPoint(crA, mergedRectCenter) || + RectHelpers.rectContainsPoint(crB, mergedRectCenter) ) ) { // Don't merge because the new shape is too different from the diff --git a/lighthouse-core/runner.js b/lighthouse-core/runner.js index 80e40ecbf175..5d67558de45b 100644 --- a/lighthouse-core/runner.js +++ b/lighthouse-core/runner.js @@ -20,6 +20,7 @@ const URL = require('./lib/url-shim.js'); const Sentry = require('./lib/sentry.js'); const generateReport = require('../report/generator/report-generator.js').generateReport; const LHError = require('./lib/lh-error.js'); +const {version: lighthouseVersion} = require('../package.json'); /** @typedef {import('./gather/connections/connection.js')} Connection */ /** @typedef {import('./lib/arbitrary-equality-map.js')} ArbitraryEqualityMap */ @@ -112,7 +113,6 @@ class Runner { } // Entering: conclusion of the lighthouse result object - const lighthouseVersion = require('../package.json').version; // Use version from gathering stage. // If accessibility gatherer didn't run or errored, it won't be in credits. diff --git a/lighthouse-core/test/computed/metrics/total-blocking-time-test.js b/lighthouse-core/test/computed/metrics/total-blocking-time-test.js index 92ae6d18c6c0..e76fda39d017 100644 --- a/lighthouse-core/test/computed/metrics/total-blocking-time-test.js +++ b/lighthouse-core/test/computed/metrics/total-blocking-time-test.js @@ -8,6 +8,7 @@ const TotalBlockingTime = require('../../../computed/metrics/total-blocking-time.js'); const trace = require('../../fixtures/traces/progressive-app-m60.json'); const devtoolsLog = require('../../fixtures/traces/progressive-app-m60.devtools.log.json'); +const {calculateSumOfBlockingTime} = require('../../../computed/metrics/tbt-utils.js'); /* eslint-env jest */ @@ -52,7 +53,7 @@ describe('Metrics: TotalBlockingTime', () => { const interactiveTimeMs = 4000; expect( - TotalBlockingTime.calculateSumOfBlockingTime(events, fcpTimeMs, interactiveTimeMs) + calculateSumOfBlockingTime(events, fcpTimeMs, interactiveTimeMs) ).toBe(0); }); @@ -68,7 +69,7 @@ describe('Metrics: TotalBlockingTime', () => { const interactiveTimeMs = 2500; expect( - TotalBlockingTime.calculateSumOfBlockingTime(events, fcpTimeMs, interactiveTimeMs) + calculateSumOfBlockingTime(events, fcpTimeMs, interactiveTimeMs) ).toBe(150); }); @@ -87,7 +88,7 @@ describe('Metrics: TotalBlockingTime', () => { ]; expect( - TotalBlockingTime.calculateSumOfBlockingTime(events, fcpTimeMs, interactiveTimeMs) + calculateSumOfBlockingTime(events, fcpTimeMs, interactiveTimeMs) ).toBe(10); // 0ms + 10ms. }); @@ -99,21 +100,21 @@ describe('Metrics: TotalBlockingTime', () => { const interactiveTimeMs = 2000; expect( - TotalBlockingTime.calculateSumOfBlockingTime( + calculateSumOfBlockingTime( [{start: 1951, end: 2100, duration: 149}], fcpTimeMs, interactiveTimeMs ) ).toBe(0); // Duration after clipping is 49, which is < 50. expect( - TotalBlockingTime.calculateSumOfBlockingTime( + calculateSumOfBlockingTime( [{start: 1950, end: 2100, duration: 150}], fcpTimeMs, interactiveTimeMs ) ).toBe(0); // Duration after clipping is 50, so time after 50ms is 0ms. expect( - TotalBlockingTime.calculateSumOfBlockingTime( + calculateSumOfBlockingTime( [{start: 1949, end: 2100, duration: 151}], fcpTimeMs, interactiveTimeMs @@ -126,21 +127,21 @@ describe('Metrics: TotalBlockingTime', () => { const interactiveTimeMs = 2000; expect( - TotalBlockingTime.calculateSumOfBlockingTime( + calculateSumOfBlockingTime( [{start: 900, end: 1049, duration: 149}], fcpTimeMs, interactiveTimeMs ) ).toBe(0); // Duration after clipping is 49, which is < 50. expect( - TotalBlockingTime.calculateSumOfBlockingTime( + calculateSumOfBlockingTime( [{start: 900, end: 1050, duration: 150}], fcpTimeMs, interactiveTimeMs ) ).toBe(0); // Duration after clipping is 50, so time after 50ms is 0ms. expect( - TotalBlockingTime.calculateSumOfBlockingTime( + calculateSumOfBlockingTime( [{start: 900, end: 1051, duration: 151}], fcpTimeMs, interactiveTimeMs @@ -157,7 +158,7 @@ describe('Metrics: TotalBlockingTime', () => { const events = [{start: 500, end: 3000, duration: 2500}]; expect( - TotalBlockingTime.calculateSumOfBlockingTime(events, fcpTimeMs, interactiveTimeMs) + calculateSumOfBlockingTime(events, fcpTimeMs, interactiveTimeMs) ).toBe(0); }); }); diff --git a/lighthouse-logger/index.js b/lighthouse-logger/index.js index f4f02c6bebac..f98575a21cae 100644 --- a/lighthouse-logger/index.js +++ b/lighthouse-logger/index.js @@ -5,13 +5,14 @@ */ 'use strict'; +const process = require('process'); const debug = require('debug'); const marky = require('marky'); const EventEmitter = require('events').EventEmitter; const isWindows = process.platform === 'win32'; -// process.browser is set when browserify'd via the `process` npm module +// @ts-expect-error: process.browser is set via Rollup. const isBrowser = process.browser; const colors = { diff --git a/package.json b/package.json index e69ed4d7ca24..40f0000b1384 100644 --- a/package.json +++ b/package.json @@ -95,9 +95,16 @@ }, "devDependencies": { "@build-tracker/cli": "^1.0.0-beta.15", + "@firebase/app-types": "0.3.1", + "@firebase/auth-types": "0.3.2", + "@firebase/util": "0.2.1", + "@rollup/plugin-alias": "^3.1.2", "@rollup/plugin-commonjs": "^20.0.0", + "@rollup/plugin-dynamic-import-vars": "^1.1.1", + "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-typescript": "^8.2.5", + "@stadtlandnetz/rollup-plugin-postprocess": "^1.1.0", "@testing-library/preact": "^2.0.1", "@testing-library/preact-hooks": "^1.1.0", "@types/archiver": "^2.1.2", @@ -107,7 +114,6 @@ "@types/cpy": "^5.1.0", "@types/eslint": "^4.16.6", "@types/estree": "^0.0.50", - "@types/exorcist": "^0.4.5", "@types/gh-pages": "^2.0.0", "@types/google.analytics": "0.0.39", "@types/jest": "^24.0.9", @@ -133,7 +139,6 @@ "angular": "^1.7.4", "archiver": "^3.0.0", "browserify": "^17.0.0", - "browserify-banner": "^1.0.15", "c8": "^7.4.0", "chalk": "^2.4.1", "chrome-devtools-frontend": "1.0.922924", @@ -148,7 +153,6 @@ "eslint-plugin-import": "^2.24.2", "eslint-plugin-local-rules": "0.1.0", "event-target-shim": "^6.0.2", - "exorcist": "^1.0.1", "firebase": "^9.0.2", "gh-pages": "^2.0.1", "glob": "^7.1.3", @@ -163,13 +167,12 @@ "mime-types": "^2.1.30", "node-fetch": "^2.6.1", "npm-run-posix-or-windows": "^2.0.2", - "package-json-versionify": "^1.0.4", "pako": "^2.0.3", "preact": "^10.5.14", "pretty-json-stringify": "^0.0.2", "puppeteer": "^10.2.0", "resolve": "^1.20.0", - "rollup": "^2.50.6", + "rollup": "^2.52.7", "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-polyfill-node": "^0.7.0", "rollup-plugin-replace": "^2.2.0", diff --git a/report/clients/standalone.js b/report/clients/standalone.js index 91ca556ba8c3..feb746127839 100644 --- a/report/clients/standalone.js +++ b/report/clients/standalone.js @@ -18,8 +18,6 @@ import {Logger} from '../renderer/logger.js'; import {ReportRenderer} from '../renderer/report-renderer.js'; import {ReportUIFeatures} from '../renderer/report-ui-features.js'; -// Used by standalone.html -// eslint-disable-next-line no-unused-vars function __initLighthouseReport__() { const dom = new DOM(document); const renderer = new ReportRenderer(dom); diff --git a/report/renderer/element-screenshot-renderer.js b/report/renderer/element-screenshot-renderer.js index 9b6f723536ab..c55b3f2bb31c 100644 --- a/report/renderer/element-screenshot-renderer.js +++ b/report/renderer/element-screenshot-renderer.js @@ -51,7 +51,7 @@ function clamp(value, min, max) { /** * @param {Rect} rect */ -function getRectCenterPoint(rect) { +function getElementRectCenterPoint(rect) { return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2, @@ -68,7 +68,7 @@ export class ElementScreenshotRenderer { * @param {Size} screenshotSize */ static getScreenshotPositions(elementRectSC, elementPreviewSizeSC, screenshotSize) { - const elementRectCenter = getRectCenterPoint(elementRectSC); + const elementRectCenter = getElementRectCenterPoint(elementRectSC); // Try to center clipped region. const screenshotLeftVisibleEdge = clamp( diff --git a/shared/localization/format.js b/shared/localization/format.js index 993ce58b56d7..6b6e4e45a132 100644 --- a/shared/localization/format.js +++ b/shared/localization/format.js @@ -7,11 +7,13 @@ const fs = require('fs'); -const MessageFormat = require('intl-messageformat').default; +const MessageFormat = require('intl-messageformat'); const {isObjectOfUnknownValues, isObjectOrArrayOfUnknownValues} = require('../type-verifiers.js'); /** Contains available locales with messages. May be an empty object if bundled. */ -const LOCALE_MESSAGES = require('./locales.js'); +/** @type {import('./locales')} */ +// @ts-expect-error TODO(esmodules): remove when file is es modules. +const LOCALE_MESSAGES = require('./locales.js').default || require('./locales.js'); const DEFAULT_LOCALE = 'en-US'; @@ -93,7 +95,7 @@ function collectAllCustomElementsFromICU(icuElements, seenElementsById = new Map * Returns a copy of the `values` object, with the values formatted based on how * they will be used in their icuMessage, e.g. KB or milliseconds. The original * object is unchanged. - * @param {MessageFormat} messageFormatter + * @param {MessageFormat.IntlMessageFormat} messageFormatter * @param {Readonly>} values * @param {string} lhlMessage Used for clear error logging. * @return {Record} @@ -171,7 +173,10 @@ function formatMessage(message, values = {}, locale) { // When using accented english, force the use of a different locale for number formatting. const localeForMessageFormat = (locale === 'en-XA' || locale === 'en-XL') ? 'de-DE' : locale; - const formatter = new MessageFormat(message, localeForMessageFormat, formats); + // This package is not correctly bundled by Rollup. + /** @type {typeof MessageFormat.IntlMessageFormat} */ + const MessageFormatCtor = MessageFormat.IntlMessageFormat || MessageFormat; + const formatter = new MessageFormatCtor(message, localeForMessageFormat, formats); // Preformat values for the message format like KB and milliseconds. const valuesForMessageFormat = _preformatValues(formatter, values, message); diff --git a/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-successful-run-expected.txt b/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-successful-run-expected.txt index 5ff53bb9ae8e..2dc03125b7bb 100644 --- a/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-successful-run-expected.txt +++ b/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-successful-run-expected.txt @@ -93,7 +93,7 @@ Gathering in-page: SourceMaps Gathering in-page: FullPageScreenshot Gathering trace Gathering devtoolsLog & network records -Computing artifact: NetworkRecords +Computing artifact: NetworkRecords$I Running afterPass methods Gathering: CSSUsage Gathering: JsUsage @@ -120,8 +120,8 @@ Getting browser version Gathering: TapTargets Gathering: Accessibility Gathering: TraceElements -Computing artifact: ProcessedTrace -Computing artifact: ProcessedNavigation +Computing artifact: ProcessedTrace$f +Computing artifact: ProcessedNavigation$7 Gathering: InspectorIssues Gathering: SourceMaps Gathering: FullPageScreenshot @@ -141,7 +141,7 @@ Navigating to http://127.0.0.1:8000/devtools/lighthouse/resources/lighthouse-bas Running pass methods Gathering in-page: ServiceWorker Gathering devtoolsLog & network records -Computing artifact: NetworkRecords +Computing artifact: NetworkRecords$I Running afterPass methods Gathering: ServiceWorker Disconnecting from browser... @@ -152,50 +152,50 @@ Auditing: Registers a service worker that controls page and `start_url` Auditing: Has a `` tag with `width` or `initial-scale` Computing artifact: ViewportMeta Auditing: First Contentful Paint -Computing artifact: FirstContentfulPaint -Computing artifact: LanternFirstContentfulPaint -Computing artifact: PageDependencyGraph -Computing artifact: LoadSimulator -Computing artifact: NetworkAnalysis +Computing artifact: FirstContentfulPaint$3 +Computing artifact: LanternFirstContentfulPaint$6 +Computing artifact: PageDependencyGraph$a +Computing artifact: LoadSimulator$a +Computing artifact: NetworkAnalysis$1 Auditing: Largest Contentful Paint -Computing artifact: LargestContentfulPaint -Computing artifact: LanternLargestContentfulPaint +Computing artifact: LargestContentfulPaint$2 +Computing artifact: LanternLargestContentfulPaint$1 Auditing: First Meaningful Paint -Computing artifact: FirstMeaningfulPaint -Computing artifact: LanternFirstMeaningfulPaint +Computing artifact: FirstMeaningfulPaint$2 +Computing artifact: LanternFirstMeaningfulPaint$2 Auditing: Speed Index -Computing artifact: SpeedIndex -Computing artifact: LanternSpeedIndex -Computing artifact: Speedline +Computing artifact: SpeedIndex$2 +Computing artifact: LanternSpeedIndex$2 +Computing artifact: Speedline$4 Auditing: Screenshot Thumbnails Auditing: Final Screenshot -Computing artifact: Screenshots +Computing artifact: Screenshots$1 Auditing: Total Blocking Time -Computing artifact: TotalBlockingTime -Computing artifact: LanternTotalBlockingTime -Computing artifact: LanternInteractive +Computing artifact: TotalBlockingTime$2 +Computing artifact: LanternTotalBlockingTime$1 +Computing artifact: LanternInteractive$4 Auditing: Max Potential First Input Delay -Computing artifact: MaxPotentialFID -Computing artifact: LanternMaxPotentialFID +Computing artifact: MaxPotentialFID$2 +Computing artifact: LanternMaxPotentialFID$1 Auditing: Cumulative Layout Shift -Computing artifact: CumulativeLayoutShift +Computing artifact: CumulativeLayoutShift$2 Auditing: No browser errors logged to the console Auditing: Initial server response time was short -Computing artifact: MainResource +Computing artifact: MainResource$g Auditing: Time to Interactive -Computing artifact: Interactive +Computing artifact: Interactive$4 Auditing: User Timing marks and measures -Computing artifact: UserTimings +Computing artifact: UserTimings$1 Auditing: Avoid chaining critical requests -Computing artifact: CriticalRequestChains +Computing artifact: CriticalRequestChains$2 Auditing: Avoid multiple page redirects Auditing: Web app manifest and service worker meet the installability requirements -Computing artifact: ManifestValues +Computing artifact: ManifestValues$4 Auditing: Provides a valid `apple-touch-icon` Auditing: Configured for a custom splash screen -Computing artifact: ManifestValues +Computing artifact: ManifestValues$4 Auditing: Sets a theme color for the address bar. -Computing artifact: ManifestValues +Computing artifact: ManifestValues$4 Auditing: Manifest has a maskable icon Auditing: Content is sized correctly for the viewport Auditing: Displays images with correct aspect ratio @@ -203,7 +203,7 @@ Auditing: Serves images with appropriate resolution Auditing: Fonts with `font-display: optional` are preloaded Auditing: Avoids deprecated APIs Auditing: Minimizes main-thread work -Computing artifact: MainThreadTasks +Computing artifact: MainThreadTasks$7 Auditing: JavaScript execution time Auditing: Preload key requests Auditing: Preconnect to required origins @@ -214,9 +214,9 @@ Auditing: Network Round Trip Times Auditing: Server Backend Latencies Auditing: Tasks Auditing: Metrics -Computing artifact: TimingSummary +Computing artifact: TimingSummary$1 Auditing: Performance budget -Computing artifact: ResourceSummary +Computing artifact: ResourceSummary$2 Auditing: Timing budget Auditing: Keep request counts low and transfer sizes small Auditing: Minimize third-party usage @@ -234,7 +234,7 @@ Auditing: Ensure CSP is effective against XSS attacks Auditing: Full-page screenshot Auditing: Script Treemap Data Computing artifact: JSBundles -Computing artifact: ModuleDuplication +Computing artifact: ModuleDuplication$2 Auditing: Site works cross-browser Auditing: Page transitions don't feel like they block on the network Auditing: Each page has a URL @@ -296,8 +296,8 @@ Auditing: Uses efficient cache policy on static assets Auditing: Avoids enormous network payloads Auditing: Defer offscreen images Auditing: Eliminate render-blocking resources -Computing artifact: UnusedCSS -Computing artifact: FirstContentfulPaint +Computing artifact: UnusedCSS$3 +Computing artifact: FirstContentfulPaint$3 Auditing: Minify CSS Auditing: Minify JavaScript Auditing: Reduce unused CSS @@ -307,10 +307,10 @@ Auditing: Serve images in next-gen formats Auditing: Efficiently encode images Auditing: Enable text compression Auditing: Properly size images -Computing artifact: ImageRecords +Computing artifact: ImageRecords$1 Auditing: Use video formats for animated content Auditing: Remove duplicate modules in JavaScript bundles -Computing artifact: ModuleDuplication +Computing artifact: ModuleDuplication$2 Computing artifact: JSBundles Auditing: Avoid serving legacy JavaScript to modern browsers Auditing: Page has the HTML doctype @@ -339,10 +339,10 @@ Auditing: Document avoids plugins Auditing: Document has a valid `rel=canonical` Auditing: Structured data is valid Auditing: No long tasks blocking ad-related network requests -Computing artifact: LongTasks +Computing artifact: LongTasks$1 Auditing: Minimal render-blocking resources found Auditing: Ad request waterfall -Computing artifact: AdRequestTime +Computing artifact: AdRequestTime$1 Computing artifact: LanternAdRequestTime Auditing: First bid request time Computing artifact: BidRequestTime @@ -352,7 +352,7 @@ Auditing: No ad found at the very top of the viewport Auditing: Few or no ads loaded outside viewport Auditing: Ad tag is loaded asynchronously Auditing: Ads not blocked by load events -Computing artifact: TraceOfTab +Computing artifact: TraceOfTab$1 Auditing: No bottleneck requests found Auditing: No duplicate tags found Auditing: Latency of first ad render @@ -364,7 +364,7 @@ Auditing: Ad tag is loaded over HTTPS Auditing: Ad scripts are loaded statically Auditing: Header bidding is parallelized Auditing: Tag load time -Computing artifact: TagLoadTime +Computing artifact: TagLoadTime$1 Computing artifact: LanternTagLoadTime Auditing: Ad density is within recommended range Auditing: Cumulative ad shift diff --git a/types/rollup-plugin-postprocess.d.ts b/types/rollup-plugin-postprocess.d.ts new file mode 100644 index 000000000000..b68c5fdcb252 --- /dev/null +++ b/types/rollup-plugin-postprocess.d.ts @@ -0,0 +1,10 @@ +/** + * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +declare module '@stadtlandnetz/rollup-plugin-postprocess' { + function postprocess(args: Array<[RegExp, string]>): void; + export = postprocess; +} diff --git a/yarn.lock b/yarn.lock index 67e44e43abf3..4000c1acae29 100644 --- a/yarn.lock +++ b/yarn.lock @@ -597,6 +597,11 @@ "@firebase/util" "1.3.0" tslib "^2.1.0" +"@firebase/app-types@0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.3.1.tgz#df4e79c38f759e606a421e866cecb7da4577b606" + integrity sha512-DjdBY3dC6w7bIcTiGjBm2wNbWml3HA5JdIwOntrhRkmxSGWMxdkd4PxPFqAj3OES47PAUjcU/4lKW6/TJYB18g== + "@firebase/app-types@0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f" @@ -635,6 +640,11 @@ resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886" integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw== +"@firebase/auth-types@0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.3.2.tgz#fc636084eb82cb098e4e76efc5fffd315e22abdd" + integrity sha512-u3Xbe9l90NDCdjb3G4O/oczKf6Q8bJe4rcRMCPva+Rr1dbjhTaYwHhtVYUqY3c64TPwcYT0+ahCEYmwfDmfsZA== + "@firebase/auth@0.17.2": version "0.17.2" resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.17.2.tgz#54ad76cfdc2f6d1201fb780365cf7d362586f3c6" @@ -879,6 +889,13 @@ node-fetch "2.6.1" tslib "^2.1.0" +"@firebase/util@0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-0.2.1.tgz#b59a2fbf14fce21401cbebf776a3e0260b591380" + integrity sha512-KPNcIK5+bUUBMII87NqGu+tRUnMcY95xujS2z0QyAfoQCKe11DMHICv3M6uweiLSXqdQwrMTyFtiql1q+0UOYQ== + dependencies: + tslib "1.9.0" + "@firebase/util@1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.3.0.tgz#e71113bdd5073e9736ceca665b54d9f6df232b20" @@ -1212,6 +1229,13 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= +"@rollup/plugin-alias@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-alias/-/plugin-alias-3.1.2.tgz#c585b05be4a7782d269c69d13def56f44e417772" + integrity sha512-wzDnQ6v7CcoRzS0qVwFPrFdYA4Qlr+ookA217Y2Z3DPZE1R8jrFNM3jvGgOf6o6DMjbnQIn5lCIJgHPe1Bt3uw== + dependencies: + slash "^3.0.0" + "@rollup/plugin-commonjs@^20.0.0": version "20.0.0" resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-20.0.0.tgz#3246872dcbcb18a54aaa6277a8c7d7f1b155b745" @@ -1225,6 +1249,16 @@ magic-string "^0.25.7" resolve "^1.17.0" +"@rollup/plugin-dynamic-import-vars@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-dynamic-import-vars/-/plugin-dynamic-import-vars-1.1.1.tgz#d72142fd9e450bcf5e17624adf4f4d4c25d7daec" + integrity sha512-PqdfEKlsyPx0hPSSuOigCHgrQbOLW+y09KRRCFeWiBBnkuh4LlV6mfrDefmLQijj8XCWzyLct2rK+q89qvRp7A== + dependencies: + "@rollup/pluginutils" "^3.1.0" + estree-walker "^2.0.1" + globby "^11.0.1" + magic-string "^0.25.7" + "@rollup/plugin-inject@^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-4.0.2.tgz#55b21bb244a07675f7fdde577db929c82fc17395" @@ -1234,6 +1268,13 @@ estree-walker "^1.0.1" magic-string "^0.25.5" +"@rollup/plugin-json@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.1.0.tgz#54e09867ae6963c593844d8bd7a9c718294496f3" + integrity sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw== + dependencies: + "@rollup/pluginutils" "^3.0.8" + "@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" @@ -1254,7 +1295,7 @@ "@rollup/pluginutils" "^3.1.0" resolve "^1.17.0" -"@rollup/pluginutils@^3.0.4", "@rollup/pluginutils@^3.1.0": +"@rollup/pluginutils@^3.0.4", "@rollup/pluginutils@^3.0.8", "@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== @@ -1282,6 +1323,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@stadtlandnetz/rollup-plugin-postprocess@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@stadtlandnetz/rollup-plugin-postprocess/-/rollup-plugin-postprocess-1.1.0.tgz#b754df3b315f1ba1af0ae2ca4ccad047f71086b0" + integrity sha512-mj3Da2lsAX4+7V8AEQLrVDf1c9wTT9QFm8AZaYdnaU82cLEN9Xix9m27w6m5leVxXFpMWnOnRVq14HF/8/1/eQ== + dependencies: + magic-string "^0.25.7" + "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -1434,13 +1482,6 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== -"@types/exorcist@^0.4.5": - version "0.4.5" - resolved "https://registry.yarnpkg.com/@types/exorcist/-/exorcist-0.4.5.tgz#613244b12490f5108f808589bc12b28450264eb8" - integrity sha1-YTJEsSSQ9RCPgIWJvBKyhFAmTrg= - dependencies: - "@types/through" "*" - "@types/filesystem@*": version "0.0.32" resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.32.tgz#307df7cc084a2293c3c1a31151b178063e0a8edf" @@ -1671,13 +1712,6 @@ resolved "https://registry.yarnpkg.com/@types/tabulator-tables/-/tabulator-tables-4.9.1.tgz#4fbc5465960598308260f50f840d610bcc8ffa3a" integrity sha512-BfHDeVDfLF5H0HYFQ3ZEfv7J43sD8dw8fhci8juRB5uc0xQWboDd6f1hgLOwQioYhO9vWZEAWfuD6c1wl9qzmw== -"@types/through@*": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.29.tgz#72943aac922e179339c651fa34a4428a4d722f93" - integrity sha512-9a7C5VHh+1BKblaYiq+7Tfc+EOmjMdZaD1MYtkQjSoxgB69tBjW98ry6SKsi4zEIWztLOMRuL87A3bdT/Fc/4w== - dependencies: - "@types/node" "*" - "@types/tough-cookie@*": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40" @@ -2393,18 +2427,6 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4: inherits "^2.0.1" safe-buffer "^5.0.1" -browserify-banner@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/browserify-banner/-/browserify-banner-1.0.15.tgz#cd9f252472974781de96b4fef07d67c9ce308700" - integrity sha512-xXmWMFn9nBl93m56czUOGxIi5DDV6fZy8+N6NhZhgoYGSNZLjJ/9cwfgLR50S4rB+hTSooWONO4a38Q0zYOwFA== - dependencies: - convert-source-map "^1.6.0" - lodash "^4.17.15" - moment "^2.24.0" - offset-sourcemap-lines "^1.0.1" - ono "^5.0.2" - through2 "^3.0.1" - browserify-cipher@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" @@ -2424,11 +2446,6 @@ browserify-des@^1.0.0: inherits "^2.0.1" safe-buffer "^5.1.2" -browserify-package-json@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-package-json/-/browserify-package-json-1.0.1.tgz#98dde8aa5c561fd6d3fe49bbaa102b74b396fdea" - integrity sha1-mN3oqlxWH9bT/km7qhArdLOW/eo= - browserify-rsa@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" @@ -3161,7 +3178,7 @@ conventional-commits-parser@^2.0.0: through2 "^2.0.0" trim-off-newlines "^1.0.0" -convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== @@ -4080,16 +4097,6 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= -exorcist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/exorcist/-/exorcist-1.0.1.tgz#79316e3c4885845490f7bb405c0e5b5db1167c52" - integrity sha1-eTFuPEiFhFSQ97tAXA5bXbEWfFI= - dependencies: - is-stream "~1.1.0" - minimist "0.0.5" - mkdirp "~0.5.1" - mold-source-map "~0.4.0" - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -4448,7 +4455,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^2.3.2, fsevents@~2.3.1: +fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -4665,7 +4672,7 @@ globals@^13.6.0: dependencies: type-fest "^0.20.2" -globby@^11.0.3: +globby@^11.0.1, globby@^11.0.3: version "11.0.4" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== @@ -5385,11 +5392,6 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-stream@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - is-string@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" @@ -6449,7 +6451,7 @@ lodash.union@^4.6.0: resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= -lodash@4.x, lodash@^4.0.0, lodash@^4.1.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.2.1, lodash@^4.7.0: +lodash@4.x, lodash@^4.0.0, lodash@^4.1.0, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.2.1, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -6681,11 +6683,6 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.5.tgz#d7aa327bcecf518f9106ac6b8f003fa3bcea8566" - integrity sha1-16oye87PUY+RBqxrjwA/o7zqhWY= - minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -6709,7 +6706,7 @@ mkdirp@1.x: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -6742,19 +6739,6 @@ module-deps@^6.2.3: through2 "^2.0.0" xtend "^4.0.0" -mold-source-map@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/mold-source-map/-/mold-source-map-0.4.0.tgz#cf67e0b31c47ab9badb5c9c25651862127bb8317" - integrity sha1-z2fgsxxHq5uttcnCVlGGISe7gxc= - dependencies: - convert-source-map "^1.1.0" - through "~2.2.7" - -moment@^2.24.0: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -6967,13 +6951,6 @@ object.values@^1.1.4: define-properties "^1.1.3" es-abstract "^1.18.2" -offset-sourcemap-lines@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/offset-sourcemap-lines/-/offset-sourcemap-lines-1.0.1.tgz#5854dff74b73fc06efcb61d7b721a8113d99be92" - integrity sha1-WFTf90tz/Abvy2HXtyGoET2ZvpI= - dependencies: - source-map "^0.5.0" - once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -6988,11 +6965,6 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -ono@^5.0.2: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ono/-/ono-5.1.0.tgz#8cafa7e56afa2211ad63dd2eb798427e64f1a070" - integrity sha512-GgqRIUWErLX4l9Up0khRtbrlH8Fyj59A0nKv8V6pWEto38aUgnOGOOF7UmgFFLzFnDSc8REzaTXOc0hqEe7yIw== - open@^6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" @@ -7103,13 +7075,6 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== -package-json-versionify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/package-json-versionify/-/package-json-versionify-1.0.4.tgz#5860587a944873a6b7e6d26e8e51ffb22315bf17" - integrity sha1-WGBYepRIc6a35tJujlH/siMVvxc= - dependencies: - browserify-package-json "^1.0.0" - package-json@^6.3.0: version "6.5.0" resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" @@ -7684,15 +7649,6 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" -"readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -7706,6 +7662,15 @@ readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -7959,12 +7924,12 @@ rollup-pluginutils@^2.6.0, rollup-pluginutils@^2.8.1: dependencies: estree-walker "^0.6.1" -rollup@^2.50.6: - version "2.50.6" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.50.6.tgz#24e2211caf9031081656e98a5e5e94d3b5e786e2" - integrity sha512-6c5CJPLVgo0iNaZWWliNu1Kl43tjP9LZcp6D/tkf2eLH2a9/WeHxg9vfTFl8QV/2SOyaJX37CEm9XuGM0rviUg== +rollup@^2.52.7: + version "2.56.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.56.3.tgz#b63edadd9851b0d618a6d0e6af8201955a77aeff" + integrity sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg== optionalDependencies: - fsevents "~2.3.1" + fsevents "~2.3.2" run-parallel@^1.1.9: version "1.1.10" @@ -8699,23 +8664,11 @@ through2@^2.0.0, through2@^2.0.2: readable-stream "~2.3.6" xtend "~4.0.1" -through2@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" - integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== - dependencies: - readable-stream "2 || 3" - through@2, "through@>=2.2.7 <3", through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -through@~2.2.7: - version "2.2.7" - resolved "https://registry.yarnpkg.com/through/-/through-2.2.7.tgz#6e8e21200191d4eb6a99f6f010df46aa1c6eb2bd" - integrity sha1-bo4hIAGR1OtqmfbwEN9Gqhxusr0= - timed-out@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -8861,7 +8814,7 @@ tsconfig-paths@^3.11.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.8.1: +tslib@1.9.0, tslib@^1.8.1: version "1.9.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==