I was trying to use lighthouse for some integration tests and running the module like:
lighthouse('http://localhost:5123/')
Throws:
Uncaught Error: connect ECONNREFUSED 127.0.0.1:9222
I imagine this is due to no Chrome instance with debug protocol open on 9222.
Would be good if the above use of lighthouse did the same as the cli (i.e. use the lighthouse environment variable and open the browser).
I think Lighthouse can run against any endpoint that implements the chrome devtools protocol. But you can reuse the launcher code to start Chrome:
const lighthouse = require('lighthouse');
const { ChromeLauncher } = require('lighthouse/lighthouse-cli/chrome-launcher');
const launcher = new ChromeLauncher({ port: 9222});
launcher.run()
.then(() => lighthouse('http://localhost:5123/', { port: 9222 }))
.then(result => {
console.log(result);
launcher.kill();
});
@samccone do you have a preference on how this API manifests?
+1 to exposing chrome launcher via a fn call
@Janpot is correct, so long as something exposes the protocol things will just work, the launcher is currently only for chrome, which I think is fine.
Would you guys consider separating chrome-launcher into its own module?
Yup. I think we'd prefer to maintain the monorepo, so we'll keep it in here, but I'm into publishing chrome-launcher to NPM as its own thing.
@Janpot can you help get the refactors stated to make this happen?
is separating launcher on its own into another module a win?
const launcher = new ChromeLauncher();
launcher.run()
.then(() => doWork())
.then(() => launcher.kill());
can't be abstracted much more.
It may make more sense to just expose a lighthouse module that's really launchChromeAndRunLighthouse(url, flags, config). I started this in #1141, but abandoned it as it was too much of a change.
tl;dr was have bin.ts basically function as a yargs processor, then call (yet another) runner that would do the rest of what bin.ts currently does starting in runLighthouse(), launch Chrome and run Lighthouse. This new runner could then be exposed as an alternative launchChromeAndRunLighthouse (or whatever) interface. Reshuffling file locations and names up for bike shedding :)
Biggest task I didn't want to take on at the time was re-centrailizing where flag default values were set so that there was a single source of truth for those (and yargs defaults could easily read from constants in whatever that file ended up being).
really runLighthouse in bin.ts could absorb and take over for the current module.
Current behavior (don't launch Chrome) would be maintained, though it would move from the default to requiring you to pass in askipAutolaunch = true flag
@paulirish at first sight the refactor doesn't look too extensive to me. Two things would need to be abstracted:
./ask.ts: I would refactor this by removing this.autoSelectChrome. Then add a this.selectChrome option, which is a function that gets a list of installations and returns a promise to one of them. Default would be installations => Promise.resolve(installations[0]) which is the same behaviour as this.autoSelectChrome. Consumers of the API could provide a custom function like a little wrapper around the current ./ask.ts.Anyway. Within the scope of lighthouse alone, separating this into its own module may not immediately result in large benefits. But within the scope of the node ecosystem it makes a lot more sense. It's a nice self contained piece of functionality where there's demand for. Demand that will only rise when headless chrome gets more stable. It probably will be easier to test and to contribute to.
And then for my personal benefit it would allow me to only import just the ChromeLauncher instead of having the complete lighthouse package in my node_modules.
In any case, it's just a suggestion
Closing in favor of https://github.com/GoogleChrome/lighthouse/issues/2092
Most helpful comment
Would you guys consider separating
chrome-launcherinto its own module?