Change Request: Support ESM plugins
See original GitHub issueESLint version
v8.4.1
What problem do you want to solve?
I have implemented an eslint-plugin that relies on a 3rd-party npm package. Using a 3rd-party npm package allows me to reuse existing assets and develop an eslint-plugin quickly.
On the other hand, there is an increasing number of pure ESM npm packages on npmjs.com. Dynamic import is the only way to import pure ESM packages from CJS (ref). Currently, ESLint only supports eslint-plugin in CJS format and does not allow async plugins, making it virtually impossible to use Pure ESM packages with eslint-plugin (ref: #15394).
> yarn add -D git://github.com/mizdra/eslint-plugin-layout-shift.git#2a97ffba28749d0311f068f2eacd96180686bf40
> yarn run lint:eslint
yarn run v1.22.15
$ eslint .
Oops! Something went wrong! :(
ESLint: 8.4.1
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@mizdra/eslint-plugin-layout-shift/lib/index.js from /Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs not supported.
Instead change the require of index.js in /Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs to a dynamic import() which is available in all CommonJS modules.
at ConfigArrayFactory._loadPlugin (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3342:42)
at /Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3214:33
at Array.reduce (<anonymous>)
at ConfigArrayFactory._loadPlugins (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3210:22)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3031:44)
at _normalizeObjectConfigDataBody.next (<anonymous>)
at ConfigArrayFactory._normalizeObjectConfigData (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2971:20)
at _normalizeObjectConfigData.next (<anonymous>)
at ConfigArrayFactory.loadInDirectory (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2817:28)
at CascadingConfigArrayFactory._loadConfigInAncestors (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3772:46)
at CascadingConfigArrayFactory.getConfigArrayForFile (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3693:18)
at FileEnumerator._iterateFilesRecursive (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/eslint/lib/cli-engine/file-enumerator.js:482:49)
at _iterateFilesRecursive.next (<anonymous>)
at FileEnumerator.iterateFiles (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/eslint/lib/cli-engine/file-enumerator.js:297:49)
at iterateFiles.next (<anonymous>)
at CLIEngine.executeOnFiles (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/eslint/lib/cli-engine/cli-engine.js:778:48)
at ESLint.lintFiles (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/eslint/lib/eslint/eslint.js:559:23)
at Object.execute (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/eslint/lib/cli.js:301:36)
at main (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/eslint/bin/eslint.js:132:52)
at Object.<anonymous> (/Users/mizdra/src/github.com/mizdra/scrapbox-userscript-icon-suggestion/node_modules/eslint/bin/eslint.js:136:2)
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
What do you think is the correct solution?
I would like to see ESLint support the eslint-plugin for ESM. This will allow us to import Pure ESM packages from eslint-plugin with an import statement.
Internally, we need a mechanism to switch the import method depending on whether eslint-plugin is CJS or ESM. Jest’s implementation of switching the import method for jest.config.js
(in pkg.type == 'module'
) / jest.config.cjs
may be helpful (ref1, ref2).
Here are the lines that need to be changed:
Participation
- I am willing to submit a pull request for this change.
Additional comments
Issue Analytics
- State:
- Created 2 years ago
- Comments:16 (9 by maintainers)
Top GitHub Comments
The current eslintrc config system is frozen as we are working on the new flat config system (https://github.com/eslint/eslint/issues/13481).
The new config system will expect config files to load plugins instead of just specifying them by name, so I believe that ESM plugins can “just work”.
For example, if this is an ESM plugin:
then, it can be used in ESM config files like this:
and a bit more complicated in CJS config files, like this:
Yes, the current config system is frozen. It doesn’t make sense to open any further issues for config changes until the new config system is available for testing (you may be requesting something that already works).
As best I can tell from my prototype, ESM should “just work” as expected in the new config system. Hopefully we will have a developer preview available in the next couple of months.