heroprotagonist / eslint-plugin-module-resolver Goto Github PK
View Code? Open in Web Editor NEWEslint plugin to be used with babel-plugin-module-resolver
License: MIT License
Eslint plugin to be used with babel-plugin-module-resolver
License: MIT License
Hello, I upgraded to v1.1.0 and I started getting the error in the title Cannot read property 'loc' of undefined
. I haven't touched anything in my config besides updating the package. Digging into it a little I isolated the issue to my rule set in 'module-resolver/use-alias': 2
which was working as expected in 1.0.0
.
Some of the api's have change from 5 => 6. This will be slightly harder than just running yarn add --dev eslint
{ components: './src/components' }
in either .babelrc
or .eslintrc
import blah from '../../components/blah'
There is a warning/error for imports from ../../components
, but not ../../components/blah
.
There should be a warning or error for imports from ../../components/blah
.
See the api here
TypeError: Error while loading rule 'module-resolver/use-alias': Cannot convert undefined or null to object
Occurred while linting /home/zeorin/code/sample-app/flow-typed/browser/hmr.js
at values (<anonymous>)
at Object.create (/home/zeorin/code/sample-app/node_modules/eslint-plugin-module-resolver/dist/rules/use-alias.js:57:32)
at createRuleListeners (/home/zeorin/code/sample-app/node_modules/eslint/lib/linter.js:578:21)
at Object.keys.forEach.ruleId (/home/zeorin/code/sample-app/node_modules/eslint/lib/linter.js:732:31)
at Array.forEach (<anonymous>)
at runRules (/home/zeorin/code/sample-app/node_modules/eslint/lib/linter.js:690:34)
at Linter._verifyWithoutProcessors (/home/zeorin/code/sample-app/node_modules/eslint/lib/linter.js:899:31)
at preprocess.map.textBlock (/home/zeorin/code/sample-app/node_modules/eslint/lib/linter.js:955:35)
at Array.map (<anonymous>)
at Linter.verify (/home/zeorin/code/sample-app/node_modules/eslint/lib/linter.js:954:42)
Use circle ci matrix jobs to accomplish this
Using:
"@babel/core": "7.4.3",
"babel-plugin-module-resolver": "3.2.0",
"eslint-plugin-module-resolver": "0.13.0",
When trying to add "module-resolver/use-alias": 2
to .eslintrc
I get the following output from ESLint:
TypeError: Error while loading rule 'module-resolver/use-alias': Cannot read property 'plugins' of null
at Object.create (/path/to/project/packages/web/node_modules/eslint-plugin-module-resolver/dist/rules/use-alias.js:56:40)
at createRuleListeners (/path/to/project/packages/web/node_modules/eslint/lib/linter.js:577:21)
at Object.keys.forEach.ruleId (/path/to/project/packages/web/node_modules/eslint/lib/linter.js:731:31)
at Array.forEach (<anonymous>)
at runRules (/path/to/project/packages/web/node_modules/eslint/lib/linter.js:689:34)
at Linter._verifyWithoutProcessors (/path/to/project/packages/web/node_modules/eslint/lib/linter.js:891:31)
at preprocess.map.textBlock (/path/to/project/packages/web/node_modules/eslint/lib/linter.js:940:35)
at Array.map (<anonymous>)
at Linter.verify (/path/to/project/packages/web/node_modules/eslint/lib/linter.js:939:42)
at Linter.verifyAndFix (/path/to/project/packages/web/node_modules/eslint/lib/linter.js:1032:29)
It's worth noting that when running ESLint the rule is actually working.
Hi, thanks for your plugin !
This module is not compatible with babel.config.js file because find-babel-config
does not.
See tleunen/find-babel-config#31
Thanks !
Does this have to actually run on Node v10+?
Hey,
Thank you for the plugin. The idea is nice, however I can't make it work even for basic things. For example:
alias is: ClientMain: './src/client/main'
import is: import App from '../../../client/main/components/App'
I checked examples (which have only easiest name resolutions) and code, seems like in the example above, the alias Set will be { 'src/client/main' }
and here it will check first import part (client
) in this Set, so 'src/client/main' !== 'client'
.
However, this code is working fine with import App from 'ClientMain/components/App'
.
It would be great to have a better file path resolution because now it's hard to make it work.
In projects where I'm using module-resolver
I often skip alias definition. Module resolver by default treats each root's subdirectory as an alias which is very convenient. I can just have absolute paths to all my modules. This is my default config
module.exports = {
plugins: [
[
'module-resolver',
{
root: ['./src'],
alias: {}, // plugin crashes without this prop
extensions: ['.js', '.ts', '.tsx', '.json'],
},
],
],
};
However, this plugin only supports only user-defined aliases. In addition, if alias
prop is skipped in the config, plugin crashes.
I would like to address that, but I'm not sure If I should extend existing rule use-alias
or define a new rule like use-default-alias
. After shallow code analysis, I think the first option would be easier to implement since I will just extend aliases paths. In the second option, I will probably have to exclude default aliases from the use-alias
rule since it may try to fix the same error in different ways. BTW after that, I will work on making rules fixable, this is what I need in the project.
Let me know @HeroProtagonist and I will tackle that.
It would be nice to have an option for an error not to be thrown for some level of depth import. I need 1, maybe more is needed for someone else.
For example:
// Component is Forms/Input/Input.js
// I would like to import FieldError which is 1 level high
import FieldError from '../FieldError'
In this example I don't want to import it like this: Client/components/Forms/FieldError
.
What do you think?
node_modules/eslint-plugin-module-resolver/dist/rules/use-alias.js
TypeError: Cannot read property 'loc' of undefined
at CallExpression (./node_modules/eslint-plugin-module-resolver/dist/rules/use-alias.js:112: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:147:30)
at Traverser._traverse (./node_modules/eslint/lib/util/traverser.js:144:34)
at Traverser._traverse (./node_modules/eslint/lib/util/traverser.js:147:30)
Hacking in some debug logging just before it dies:
CallExpression: function CallExpression(node) {
console.warn('CallExpression2:', { node })
context.report({
node: node,
message: message,
loc: node.arguments[0].loc
});
}
It's trying to access node.arguments[0].loc
, but there are no arguments, which is why it crashes:
{ node:
Node {
type: 'CallExpression',
start: 598,
end: 621,
loc: SourceLocation { start: [Object], end: [Object] },
callee:
Node {
type: 'Identifier',
start: 598,
end: 619,
loc: [Object],
name: '_makeShallowComponent',
range: [Array],
_babelType: 'Identifier' },
arguments: [],
range: [ 598, 621 ],
_babelType: 'CallExpression',
parent:
Node {
type: 'VariableDeclarator',
start: 575,
end: 621,
loc: [Object],
id: [Object],
init: [Circular],
range: [Array],
_babelType: 'VariableDeclarator',
parent: [Object] } } }
The snippet of code it appears to be failing on for me is this, nested relatively deep in my jest test:
const { wrappedComponent } = _makeShallowComponent()
It doesn't seem to matter what it is/where it's placed though, as the following as the only thing in the file also causes a failure:
const { foo } = bar()
Hacking that line of code to use a proper check lets the error complete, and shows it as:
So I'm thinking maybe this has gotten itself into a weird/undesirable edgecase due to the config being unable to be found, and then it's dying based on an unexpected case there.
Getting super hacky with things, I put the following code in place as per the babel docs:
// var _findBabelConfig$sync = findBabelConfig.sync(babelDir),
// config = _findBabelConfig$sync.config;
var ___babel = require("@babel/core");
var config = ___babel.loadPartialConfig()
console.warn('babelconfig', config)
And it seemed to find my config file (though obviously it's not correctly wired into this rule/plugin properly, just enough to proof of concept):
babelconfig PartialConfig {
// ..snip ..
config: 'my-project-dir/babel.config.js'
}
TypeError: Error while loading rule 'module-resolver/use-alias': Cannot convert undefined or null to object
Occurred while linting /home/zeorin/code/eldo-app/packages/api/src/app.hooks.js
at values (<anonymous>)
at Object.create (/home/zeorin/code/eldo-app/node_modules/eslint-plugin-module-resolver/dist/rules/use-alias.js:114:22)
at createRuleListeners (/home/zeorin/code/eldo-app/node_modules/eslint/lib/linter/linter.js:758:21)
at /home/zeorin/code/eldo-app/node_modules/eslint/lib/linter/linter.js:928:31
at Array.forEach (<anonymous>)
at runRules (/home/zeorin/code/eldo-app/node_modules/eslint/lib/linter/linter.js:873:34)
at Linter._verifyWithoutProcessors (/home/zeorin/code/eldo-app/node_modules/eslint/lib/linter/linter.js:1170:31)
at Linter._verifyWithoutProcessors (/home/zeorin/code/eldo-app/node_modules/eslint-plugin-eslint-comments/lib/utils/patch.js:181:42)
at Linter._verifyWithConfigArray (/home/zeorin/code/eldo-app/node_modules/eslint/lib/linter/linter.js:1268:21)
at Linter.verify (/home/zeorin/code/eldo-app/node_modules/eslint/lib/linter/linter.js:1223:25)
In my opinion option extensions
is redundant and it will be more convenient for users and more compatible with babel-plugin-module-resolver
if we would take list of extensions from babel plugin config.
The default list of extensions is defined here
const defaultExtensions = ['.js', '.jsx', '.es', '.es6', '.mjs'];
Extensions are used to determine whether aliased file exists or not.
So TypeScript users and also React Native users (platform-specific extensions like file.android.js
, file.ios.js
) have to define extensions array twice.
It would be good to remove that option and get extensions from babel config, however, this would introduce breaking change and we should bump major version of the plugin. I assume it follows semantic versioning.
Edit: supporting array from babel config as a default value for that option seems not to be breaking.
What do you think @HeroProtagonist ?
Seems it doesn't work with Typescript files that have extension .ts and .tsx.
Make an example folder with a simple project to aid with development
From this issue travis-ci/travis-ci#5035. Seems that status checks of each stage cannot be seem as easily as with circle ci. Time to migrate
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.