This might be an issue with the XO CLI, not sure though.
Error: Failed to load config "xo-typescript" to extend from.
Referenced from: BaseConfig
at configMissingError (/home/runner/work/bot/bot/node_modules/eslint/lib/cli-engine/config-array-factory.js:265:9)
at ConfigArrayFactory._loadExtendedShareableConfig (/home/runner/work/bot/bot/node_modules/eslint/lib/cli-engine/config-array-factory.js:826:23)
at ConfigArrayFactory._loadExtends (/home/runner/work/bot/bot/node_modules/eslint/lib/cli-engine/config-array-factory.js:731:25)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/home/runner/work/bot/bot/node_modules/eslint/lib/cli-engine/config-array-factory.js:660:25)
at _normalizeObjectConfigDataBody.next (<anonymous>)
at ConfigArrayFactory._normalizeObjectConfigData (/home/runner/work/bot/bot/node_modules/eslint/lib/cli-engine/config-array-factory.js:596:20)
at _normalizeObjectConfigData.next (<anonymous>)
at createConfigArray (/home/runner/work/bot/bot/node_modules/eslint/lib/cli-engine/config-array-factory.js:340:25)
at ConfigArrayFactory.create (/home/runner/work/bot/bot/node_modules/eslint/lib/cli-engine/config-array-factory.js:395:16)
at createBaseConfigArray (/home/runner/work/bot/bot/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js:86:48)
Getting this error with XO v0.32.0 and TypeScript v3.8.3.
Upgrading to TypeScript v3.9.3 fixed the error.
I was having this issue with Typescriot v3.8.3, upgrading to v3.9.7 now gives the same error but with:
Error: Failed to load plugin 'react' declared in 'BaseConfig 禄 /home/rsa/go/src/brewery.doctype.se/skyfall/frontend/node_modules/eslint-config-xo-react/index.js': Cannot find module 'eslint-plugin-react'
Getting this same error with TypeScript v4.0.2
This is almost certainly the same root cause as why having a different Prettier version breaks. However XO is importing or using other modules isn't resilient to version changes and seems to force you to use whatever version is specified in the XO package.json.
I'm also having this issue with TypeScript v4.0.2
EDIT: resolved temporarily adding packages manually as suggested from this comment https://github.com/xojs/xo/issues/454#issuecomment-609485873
yarn add --dev eslint-config-xo-typescript fixes it for me.
Reason is this:
When ESLint loads an extended shareable config it does so relative to the file it is imported from:
new CLIEngine() sets up the baseConfigbaseConfig is forwarded to createBaseConfigArray()createBaseConfigArray() calls configArrayFactory.create()](https://github.com/eslint/eslintrc/blob/4440df8237a127e15cbde5c697353e1224f12ec1/lib/cascading-config-array-factory.js#L91-L101), but [forwards _only_ aname`create() a context (ctx), containing the name and filePath, is created is created and the config data gets normalized using [_normalizeConfigData()]Within _normalizeConfigData() the data eventually arrives at *_normalizeObjectConfigDataBody() where it loads the extends and as part of that tries to load eslint-config-xo-typescript (as the extended shareable config that it is).
And here's the core:
In _loadExtendedShareableConfig() the config is loaded relative to the provided filePath (the one that was missing in step 3. above), and if no filePath is set, then relative to a placeholder file within cwd.
It loads using resolver.resolve](moduleName, relativeToPath) which essentially is a wrapper around the Node.js core Module.createRequire(relativeToPath).resolve(moduleName).
So what happens is:
xo creates a virtual ESLint config, a baseConfig, and tells ESLint CLIEngine to run that from the cwd of the main project.xo has the extended shareable configs as dependencies to itself.node_modules and through that hoisting becomes require:able from the top project.npm or yarn makes any guaranties that any dependencies other than the ones defined in the top project will be possible to require from there.yarn 1.x wouldn't hoist eslint-config-xo-typescript while npm would. This only happens because of the incorrect reliance on hoisting.Solution?
Not really sure. Maybe one of:
cwd to the xo folder, as require() will find modules higher up in the folder hierarchy, so it will find the hoisted modules.resolvePluginsRelativeTo option for CLIEngine, maybe one could make xo provide the config through a plugin instead and point resolvePluginsRelativeTo to the folder of xo itself?resolveExtendedShareableConfigsRelativeTo that mimics resolvePluginsRelativeTo? (Which they may be reluctant as CLIEngine is deprecated, #474)
Most helpful comment
Reason is this:
When ESLint loads an extended shareable config it does so relative to the file it is imported from:
new CLIEngine()sets up thebaseConfigbaseConfigis forwarded tocreateBaseConfigArray()createBaseConfigArray()callsconfigArrayFactory.create()](https://github.com/eslint/eslintrc/blob/4440df8237a127e15cbde5c697353e1224f12ec1/lib/cascading-config-array-factory.js#L91-L101), but [forwards _only_ aname`create()a context (ctx), containing the name and filePath, is created is created and the config data gets normalized using [_normalizeConfigData()]Within
_normalizeConfigData()the data eventually arrives at*_normalizeObjectConfigDataBody()where it loads the extends and as part of that tries to loadeslint-config-xo-typescript(as the extended shareable config that it is).And here's the core:
In
_loadExtendedShareableConfig()the config is loaded relative to the providedfilePath(the one that was missing in step3.above), and if nofilePathis set, then relative to a placeholder file withincwd.It loads using
resolver.resolve](moduleName, relativeToPath)which essentially is a wrapper around the Node.js coreModule.createRequire(relativeToPath).resolve(moduleName).So what happens is:
xocreates a virtual ESLint config, abaseConfig, and tells ESLintCLIEngineto run that from thecwdof the main project.xohas the extended shareable configs as dependencies to itself.node_modulesand through that hoisting becomesrequire:able from the top project.npmoryarnmakes any guaranties that any dependencies other than the ones defined in the top project will be possible to require from there.yarn1.x wouldn't hoisteslint-config-xo-typescriptwhilenpmwould. This only happens because of the incorrect reliance on hoisting.Solution?
Not really sure. Maybe one of:
cwdto thexofolder, asrequire()will find modules higher up in the folder hierarchy, so it will find the hoisted modules.resolvePluginsRelativeTooption for CLIEngine, maybe one could makexoprovide the config through a plugin instead and pointresolvePluginsRelativeToto the folder ofxoitself?resolveExtendedShareableConfigsRelativeTothat mimicsresolvePluginsRelativeTo? (Which they may be reluctant asCLIEngineis deprecated, #474)