Open tilgovi opened 5 years ago
Since this module also does not resolve plugins and presets, a lot of the work can probably be replaced with loadPartialConfig({ configFile })
from @babel/core
. It returns an object with options
.
I've also just hit this issue while trying to use https://github.com/tleunen/babel-plugin-module-resolver:
Error while loading rule 'module-resolver/use-alias': Cannot read property 'env' of undefined
TypeError: Error while loading rule 'module-resolver/use-alias': Cannot read property 'env' of undefined
at module.exports.api (./babel.config.js:5:24)
at getBabelJsConfig (./node_modules/find-babel-config/lib/index.js:21:16)
at Function.findBabelConfigSync [as sync] (./node_modules/find-babel-config/lib/index.js:152:27)
at Object.create (./node_modules/eslint-plugin-module-resolver/dist/rules/use-alias.js:79:49)
at createRuleListeners (./node_modules/eslint/lib/linter.js:682:21)
at Object.keys.forEach.ruleId (./node_modules/eslint/lib/linter.js:841:31)
at Array.forEach (<anonymous>)
at runRules (./node_modules/eslint/lib/linter.js:781:34)
at Linter._verifyWithoutProcessors (./node_modules/eslint/lib/linter.js:1003:33)
at preprocess.map.textBlock (./node_modules/eslint/lib/linter.js:1046:35)
My workaround was to mock out the aspects of api
that we require (namely env
), based on the docs:
// If we aren't passed an api, mock one out here..
// Ref: https://babeljs.io/docs/en/config-files#apienv
const fakedApiObject = {
env: checkEnv => {
const envName = process.env.NODE_ENV || 'development'
if (typeof checkEnv === 'string') {
return checkEnv === envName
} else if (Array.isArray(checkEnv)) {
return checkEnv.includes(envName)
} else if (typeof checkEnv === 'function') {
return checkEnv(envName)
} else {
return envName
}
}
}
module.exports = (api = fakedApiObject) => {
// ..snip..
That ends up getting further, but then is dying on this (but that is likely more related to eslint-plugin-module-resolver
than this package):
TypeError: Cannot read property 'loc' of undefined
at CallExpression (./node_modules/eslint-plugin-module-resolver/dist/rules/use-alias.js:108:36)
at listeners.(anonymous function).forEach.listener (./node_modules/eslint/lib/util/safe-emitter.js:47:58)
at Array.forEach (<anonymous>)
at Object.emit (./node_modules/eslint/lib/util/safe-emitter.js:47:38)
at NodeEventGenerator.applySelector (./node_modules/eslint/lib/util/node-event-generator.js:251:26)
at NodeEventGenerator.applySelectors (./node_modules/eslint/lib/util/node-event-generator.js:280:22)
at NodeEventGenerator.enterNode (./node_modules/eslint/lib/util/node-event-generator.js:294:14)
at CodePathAnalyzer.enterNode (./node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:608:23)
at Traverser.enter [as _enter] (./node_modules/eslint/lib/linter.js:865:28)
at Traverser._traverse (./node_modules/eslint/lib/util/traverser.js:132:14)
at Traverser._traverse (./node_modules/eslint/lib/util/traverser.js:147:30)
at Traverser._traverse (./node_modules/eslint/lib/util/traverser.js:144:34)
at Traverser._traverse (./node_modules/eslint/lib/util/traverser.js:144:34)
at Traverser.traverse (./node_modules/eslint/lib/util/traverser.js:115:14)
at runRules (./node_modules/eslint/lib/linter.js:862:15)
at Linter._verifyWithoutProcessors (./node_modules/eslint/lib/linter.js:1003:33)
Super cutting down the file it's failing on, it basically looks like this:
import { makeFile } from '../../../helpers/file-helpers'
const file = makeFile()
The file-helpers
exists correctly at that path, the error seems to occur regardless of whether it contains any content/exports though.
It seems it may be related to it not being able to find my module-transform
config in my babel config, as I was doing it through jest's babel config override section. If I comment everything aside from the relative path import i get the following eslint error:
warning Unable to find config for babel-plugin-module-resolver module-resolver/use-alias
Which goes away once i add the config back in :
[
'module-resolver',
{
root: ['./spec/javascripts'],
alias: {
'test-helpers': './helpeaaarstestfoo',
},
},
],
I'm not 100%.. but I think this could possibly also be solved by using loadPartialConfig
from @babel/core
, as I know jest makes use of similar to add it's own config changes. I expect what this rule is seeing isn't representative of the final babel config as jest/etc would see it.
Edit: Opened https://github.com/HeroProtagonist/eslint-plugin-module-resolver/issues/44 RE: the 2nd part of my issue here with further details.
@0xdevalias @tilgovi
I added support for config files with these lines. No value is passed into the config when it is called, so it makes sense that this happens.
Do you guys know if babel exports this api
object so we could pass it in? Or is there a better way to handle the config when it is a function?
Do you guys know if babel exports this api object so we could pass it in? Or is there a better way to handle the config when it is a function?
@babel/core
may do everything you need:
> require('@babel/core').loadPartialConfig({ rootMode: 'upward-optional' })
PartialConfig {
options: {
rootMode: 'upward-optional',
babelrc: false,
configFile: false,
passPerPreset: false,
envName: 'development',
cwd: '...',
root: '...',
filename: undefined,
plugins: [ [ConfigItem], [ConfigItem], [ConfigItem] ],
presets: [ [ConfigItem] ]
},
babelignore: undefined,
babelrc: undefined,
config: '.../babel.config.js'
}
Unfortunately, I suspect there are probably exotic uses of find-babel-config
and babel-plugin-module-resolver
and eslint-import-resolver-babel-module
and places where options that may be important to pass might conflict with their meaning for this function.
I made an effort to catalogue some of the issues here: https://github.com/tleunen/eslint-import-resolver-babel-module/issues/89#issuecomment-541482240
My recommendation, at this point, would be to try out a branch of eslint-resolver-babel-module
and babel-plugin-module-resolver
that just use the core loadPartialConfig
function and nothing else. Possibly a near total rewrite. If it works, it would greatly simplify the whole situation and you could bump a major version number.
My recommendation, at this point, would be to try out a branch of eslint-resolver-babel-module and babel-plugin-module-resolver that just use the core loadPartialConfig function and nothing else. Possibly a near total rewrite. If it works, it would greatly simplify the whole situation and you could bump a major version number.
I think that would look like option 4 in my comment. The babel-plugin-module-resolver
would not use this package (find-babel-config
) at all. It should either use the current working directory, or an explicit root, or get it from the babel configuration somehow. I don't know if Babel passes the root directory through to plugins or not, but Babel definitely knows it. If it doesn't pass it, use loadPartialConfig
to find it. Then eslint-import-resolver-babel-module
should not take any configuration that isn't a Babel configuration option used for finding the config, and all other options should be taken from the configuration for babel-plugin-module-resolver
.
Just in case it doesn't go without saying: none of this is meant as an attack. Thank you for your work on these projects. They've been immensely helpful to me. If I can help by prototyping any of the above, please let me know what makes sense to you.
@tilgovi - No worries, I don't take it personally. I've been away from these projects for a long time because I'm not an active user/consumer of these anymore. So it's hard for me to find the time and the motivation to keep improving them.
I'd like to update this library to use loadPartialConfig
since Babel provides this function now.
In term of babel-plugin-module-resolver
using this package or not, we can debate this in its own repo as well. If loadPartialConfig
makes it super easy, I don't see a real valid use case of keeping find-babel-config
honestly.
Cool. I'll let you know what I find.
If a configuration file exports a function, it is not called with any arguments.
It should be called with an API object: https://babeljs.io/docs/en/config-files#config-function-api