GoogleChrome / lighthouse-ci

Automate running Lighthouse for every commit, viewing the changes, and preventing regressions
Apache License 2.0
6.33k stars 633 forks source link

ESM support (incl. lighthouserc.mjs + lighthouserc.cjs) #973

Open karlhorky opened 7 months ago

karlhorky commented 7 months ago

Is your feature request related to a problem? Please describe.

Currently, running lhci autorun in an ESM project causes ERR_REQUIRE_ESM failures, because the configuration file is being require()d:

$ lhci autorun
Error [ERR_REQUIRE_ESM]: require() of ES Module /home/runner/work/here-for-you-codealong/here-for-you-codealong/lighthouserc.js from /home/runner/.config/yarn/global/node_modules/@lhci/utils/src/lighthouserc.js not supported.
/home/runner/work/here-for-you-codealong/here-for-you-codealong/lighthouserc.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead either rename /home/runner/work/here-for-you-codealong/here-for-you-codealong/lighthouserc.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in /home/runner/work/here-for-you-codealong/here-for-you-codealong/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).

Describe the solution you'd like

It would be nice to be able to use Lighthouse CI in ESM projects (eg. projects specifying "type": "module" in package.json):

  1. ESM support in lighthouserc.js when "type": "module" specified in package.json
  2. lighthouserc.mjs for CommonJS projects who want to opt in to ESM in this one file
  3. ~lighthouserc.cjs for ESM projects who want to stay with the current CommonJS config~ done in https://github.com/GoogleChrome/lighthouse-ci/pull/650 and https://github.com/GoogleChrome/lighthouse-ci/pull/975

The currently supported configuration files:

Describe alternatives you've considered

Not having ESM support (having to use JSON config files in ESM projects)

Additional context

Lighthouse itself switched to ESM in this umbrella issue managed by @connorjclark

adamraine commented 7 months ago

lighthouserc.cjs is actually supported (https://github.com/GoogleChrome/lighthouse-ci/pull/650), but looks like the docs need to be updated :/. This at least covers case 3 so you don't need to use a JSON file, but the other cases would still be nice to have.

moos commented 5 months ago

+1 -- I have a custom Lighthouse config in my lighthouserc.js:

module.exports = {
  ci: {
     // [snip]
      settings: {
        configPath: './lighthouse-config.js',
      }
    },
};

Trying const constants = require('lighthouse/core/config/constants.js') in lighthouse-config.js doesn't work because those are ESM modules. import isn't supported (this issue), and haven't been able to get dynamic import() to work with CJS! 😖

Update: Renaming to lighthouse-config.mjs and using regular import/export does work!