lighthouse 9.5.0-dev.20221205 → 9.5.0-dev.20221207

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/index.js CHANGED
@@ -11,7 +11,6 @@ import {CriConnection} from './legacy/gather/connections/cri.js';
11
11
  import {Config} from './legacy/config/config.js';
12
12
  import UrlUtils from './lib/url-utils.js';
13
13
  import {Driver} from './legacy/gather/driver.js';
14
- import {initializeConfig} from './config/config.js';
15
14
  import {UserFlow, auditGatherSteps} from './user-flow.js';
16
15
  import {ReportGenerator} from '../report/generator/report-generator.js';
17
16
  import {startTimespanGather} from './gather/timespan-runner.js';
@@ -64,7 +63,7 @@ async function legacyNavigation(url, flags = {}, configJSON, userConnection) {
64
63
  flags.logLevel = flags.logLevel || 'error';
65
64
  log.setLevel(flags.logLevel);
66
65
 
67
- const config = await generateLegacyConfig(configJSON, flags);
66
+ const config = await Config.fromJson(configJSON, flags);
68
67
  const computedCache = new Map();
69
68
  const options = {config, computedCache};
70
69
  const connection = userConnection || new CriConnection(flags.port, flags.hostname);
@@ -146,34 +145,6 @@ async function auditFlowArtifacts(flowArtifacts, config) {
146
145
  return await auditGatherSteps(gatherSteps, {name, config});
147
146
  }
148
147
 
149
- /**
150
- * Generate a Lighthouse Config.
151
- * @param {LH.Config.Json=} configJson Configuration for the Lighthouse run. If
152
- * not present, the default config is used.
153
- * @param {LH.Flags=} flags Optional settings for the Lighthouse run. If present,
154
- * they will override any settings in the config.
155
- * @param {LH.Gatherer.GatherMode=} gatherMode Gather mode used to collect artifacts. If present
156
- * the config may override certain settings based on the mode.
157
- * @return {Promise<LH.Config.FRConfig>}
158
- */
159
- async function generateConfig(configJson, flags = {}, gatherMode = 'navigation') {
160
- const {config} = await initializeConfig(gatherMode, configJson, flags);
161
- return config;
162
- }
163
-
164
- /**
165
- * Generate a legacy Lighthouse Config.
166
- * @deprecated
167
- * @param {LH.Config.Json=} configJson Configuration for the Lighthouse run. If
168
- * not present, the default config is used.
169
- * @param {LH.Flags=} flags Optional settings for the Lighthouse run. If present,
170
- * they will override any settings in the config.
171
- * @return {Promise<Config>}
172
- */
173
- function generateLegacyConfig(configJson, flags) {
174
- return Config.fromJson(configJson, flags);
175
- }
176
-
177
148
  function getAuditList() {
178
149
  return Runner.getAuditList();
179
150
  }
@@ -194,8 +165,6 @@ export {
194
165
  snapshot,
195
166
  generateReport,
196
167
  auditFlowArtifacts,
197
- generateConfig,
198
- generateLegacyConfig,
199
168
  getAuditList,
200
169
  traceCategories,
201
170
  };
@@ -27,9 +27,11 @@ const {promisify} = util;
27
27
  // https://nodejs.org/api/stream.html#streams-promises-api
28
28
  const pipeline = promisify && promisify(stream.pipeline);
29
29
 
30
+ const optionsFilename = 'options.json';
30
31
  const artifactsFilename = 'artifacts.json';
31
32
  const traceSuffix = '.trace.json';
32
33
  const devtoolsLogSuffix = '.devtoolslog.json';
34
+ const stepDirectoryRegex = /^step(\d+)$/;
33
35
 
34
36
  /**
35
37
  * @typedef {object} PreparedAssets
@@ -65,6 +67,9 @@ function loadArtifacts(basePath) {
65
67
  const passName = filename.replace(devtoolsLogSuffix, '');
66
68
  const devtoolsLog = JSON.parse(fs.readFileSync(path.join(basePath, filename), 'utf8'));
67
69
  artifacts.devtoolsLogs[passName] = devtoolsLog;
70
+ if (passName === 'defaultPass') {
71
+ artifacts.DevtoolsLog = devtoolsLog;
72
+ }
68
73
  });
69
74
 
70
75
  // load traces
@@ -74,6 +79,9 @@ function loadArtifacts(basePath) {
74
79
  const trace = JSON.parse(file);
75
80
  const passName = filename.replace(traceSuffix, '');
76
81
  artifacts.traces[passName] = Array.isArray(trace) ? {traceEvents: trace} : trace;
82
+ if (passName === 'defaultPass') {
83
+ artifacts.Trace = artifacts.traces[passName];
84
+ }
77
85
  });
78
86
 
79
87
  if (Array.isArray(artifacts.Timing)) {
@@ -84,6 +92,52 @@ function loadArtifacts(basePath) {
84
92
  return artifacts;
85
93
  }
86
94
 
95
+ /**
96
+ * @param {string} basePath
97
+ * @return {LH.UserFlow.FlowArtifacts}
98
+ */
99
+ function loadFlowArtifacts(basePath) {
100
+ log.log('Reading flow artifacts from disk:', basePath);
101
+
102
+ if (!fs.existsSync(basePath)) {
103
+ throw new Error('No saved flow artifacts found at ' + basePath);
104
+ }
105
+
106
+ /** @type {LH.UserFlow.FlowArtifacts} */
107
+ const flowArtifacts = JSON.parse(
108
+ fs.readFileSync(path.join(basePath, optionsFilename), 'utf-8')
109
+ );
110
+
111
+ const filenames = fs.readdirSync(basePath);
112
+
113
+ flowArtifacts.gatherSteps = [];
114
+ for (const filename of filenames) {
115
+ const regexResult = stepDirectoryRegex.exec(filename);
116
+ if (!regexResult) continue;
117
+
118
+ const index = Number(regexResult[1]);
119
+ if (!Number.isFinite(index)) continue;
120
+
121
+ const stepPath = path.join(basePath, filename);
122
+ if (!fs.lstatSync(stepPath).isDirectory()) continue;
123
+
124
+ /** @type {LH.UserFlow.GatherStep} */
125
+ const gatherStep = JSON.parse(
126
+ fs.readFileSync(path.join(stepPath, optionsFilename), 'utf-8')
127
+ );
128
+ gatherStep.artifacts = loadArtifacts(stepPath);
129
+
130
+ flowArtifacts.gatherSteps[index] = gatherStep;
131
+ }
132
+
133
+ const missingStepIndex = flowArtifacts.gatherSteps.findIndex(gatherStep => !gatherStep);
134
+ if (missingStepIndex !== -1) {
135
+ throw new Error(`Could not find step with index ${missingStepIndex} at ${basePath}`);
136
+ }
137
+
138
+ return flowArtifacts;
139
+ }
140
+
87
141
  /**
88
142
  * A replacer function for JSON.stingify of the artifacts. Used to serialize objects that
89
143
  * JSON won't normally handle.
@@ -99,6 +153,54 @@ function stringifyReplacer(key, value) {
99
153
  return value;
100
154
  }
101
155
 
156
+ /**
157
+ * Saves flow artifacts with the following file structure:
158
+ * flow/ -- Directory specified by `basePath`.
159
+ * options.json -- Flow options (e.g. flow name, flags).
160
+ * step0/ -- Directory containing artifacts for the first step.
161
+ * options.json -- First step's options (e.g. step flags).
162
+ * artifacts.json -- First step's artifacts except the DevTools log and trace.
163
+ * defaultPass.devtoolslog.json -- First step's DevTools log.
164
+ * defaultPass.trace.json -- First step's trace.
165
+ * step1/ -- Directory containing artifacts for the second step.
166
+ *
167
+ * @param {LH.UserFlow.FlowArtifacts} flowArtifacts
168
+ * @param {string} basePath
169
+ * @return {Promise<void>}
170
+ */
171
+ async function saveFlowArtifacts(flowArtifacts, basePath) {
172
+ const status = {msg: 'Saving flow artifacts', id: 'lh:assetSaver:saveArtifacts'};
173
+ log.time(status);
174
+ fs.mkdirSync(basePath, {recursive: true});
175
+
176
+ // Delete any previous artifacts in this directory.
177
+ const filenames = fs.readdirSync(basePath);
178
+ for (const filename of filenames) {
179
+ if (stepDirectoryRegex.test(filename) || filename === optionsFilename) {
180
+ fs.rmSync(`${basePath}/${filename}`, {recursive: true});
181
+ }
182
+ }
183
+
184
+ const {gatherSteps, ...flowOptions} = flowArtifacts;
185
+ for (let i = 0; i < gatherSteps.length; ++i) {
186
+ const {artifacts, ...stepOptions} = gatherSteps[i];
187
+ const stepPath = path.join(basePath, `step${i}`);
188
+ await saveArtifacts(artifacts, stepPath);
189
+ fs.writeFileSync(
190
+ path.join(stepPath, optionsFilename),
191
+ JSON.stringify(stepOptions, stringifyReplacer, 2) + '\n'
192
+ );
193
+ }
194
+
195
+ fs.writeFileSync(
196
+ path.join(basePath, optionsFilename),
197
+ JSON.stringify(flowOptions, stringifyReplacer, 2) + '\n'
198
+ );
199
+
200
+ log.log('Flow artifacts saved to disk in folder:', basePath);
201
+ log.timeEnd(status);
202
+ }
203
+
102
204
  /**
103
205
  * Save artifacts object mostly to single file located at basePath/artifacts.json.
104
206
  * Also save the traces & devtoolsLogs to their own files
@@ -120,7 +222,10 @@ async function saveArtifacts(artifacts, basePath) {
120
222
  }
121
223
  }
122
224
 
123
- const {traces, devtoolsLogs, ...restArtifacts} = artifacts;
225
+ // `DevtoolsLog` and `Trace` will always be the 'defaultPass' version.
226
+ // We don't need to save them twice, so extract them here.
227
+ // eslint-disable-next-line no-unused-vars
228
+ const {traces, devtoolsLogs, DevtoolsLog, Trace, ...restArtifacts} = artifacts;
124
229
 
125
230
  // save traces
126
231
  for (const [passName, trace] of Object.entries(traces)) {
@@ -332,8 +437,10 @@ function normalizeTimingEntries(timings) {
332
437
 
333
438
  export {
334
439
  saveArtifacts,
440
+ saveFlowArtifacts,
335
441
  saveLhr,
336
442
  loadArtifacts,
443
+ loadFlowArtifacts,
337
444
  saveAssets,
338
445
  prepareAssets,
339
446
  saveTrace,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lighthouse",
3
3
  "type": "module",
4
- "version": "9.5.0-dev.20221205",
4
+ "version": "9.5.0-dev.20221207",
5
5
  "description": "Automated auditing, performance metrics, and best practices for the web.",
6
6
  "main": "./core/index.js",
7
7
  "bin": {
package/vercel.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "github": {
3
+ "silent": true
4
+ },
5
+ "trailingSlash": true
6
+ }
package/now.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "version": 2,
3
- "builds": [
4
- {
5
- "src": "package.json",
6
- "use": "@now/static-build",
7
- "config": {"distDir": "dist"}
8
- }
9
- ],
10
- "github": {
11
- "silent": true
12
- },
13
- "trailingSlash": true
14
- }