-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check module import validity with eslint-plugin-import #12303
Conversation
de34610
to
90f6502
Compare
90f6502
to
e85d027
Compare
Howdy Jason, regarding the changes in |
Hey Andrés, thanks for the heads up! That's good to know :) |
7c88a27
to
df4944e
Compare
c8bc0f0
to
cb47d9f
Compare
@@ -64,15 +65,7 @@ const webpackConfig = { | |||
} | |||
] | |||
}, | |||
resolve: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be moved to a separate config? Wouldn't it be enough to resolve using the webpack.config.js
file from .eslint-resolver.js
as-is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @aduth, the main reason I had separated the resolve
into its own separate file was due to the fact that the dependencies for webpack.config.js
assumes a different root than the node paths ESLint is instantiated with. For example, webpack.config.js
has lib/create-config
, which is a dependency in the client
folder; ESLint can't easily resolve this. (An easy way to repro this: node -e "var config = require('./webpack.config');"
)
I don't know of an easy way to modify the node paths for ESLint, which is why I decided to separate the resolve configs to a new file.
.eslint-resolver.js
Outdated
|
||
exports.interfaceVersion = 2 | ||
|
||
exports.resolve = function (source, file, config) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ironically your ESLint resolver script has many lint errors 😄 (spacing after function, between parens).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
D'oh! 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized that ESLint was ignoring the file due to the .eslint
prefix. I went ahead and changed .eslintignore
to force parsing .eslint-resolver.js
so this shouldn't happen again.
.eslint-resolver.js
Outdated
*/ | ||
const log = debugFactory('eslint-plugin-import:resolver:wp-calypso-resolver'); | ||
|
||
const nodeResolverConfig = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain the need for separate resolving configs? Should this be pulled from webpack.config.node.js
for server-side module importing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure - the reason why we need separate resolving configs is due to how files across our project assume a different root directory. For client files, this includes /client/
and /client/extensions/
; for server files, this includes /
, /client/
, and /server/
. Test files tend to add /test/
as a root directory as well.
I do think it should be pulling from webpack.config.node.js
for server-side module importing. I'll push out a revision to address this shortly.
/* eslint-disable import/no-commonjs */ | ||
|
||
const path = require( 'path' ); | ||
const customResolverPath = path.join( __dirname, './.eslint-resolver.js' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't the result of this join be simply "./.eslint-resolver.js" which we could instead define as a string key of the settings
, not a computed property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're absolutely correct. I'll fix this.
EDIT: I initially thought this was the case, but I overlooked the fact that the result of path.join
is the absolute path of the resolver file (e.g. /Users/myUsername/wp-calypso/.eslint-resolver.js
). Unless an absolute path is specified as the Object key, CircleCI fails to run run-lint
properly.
.eslintrc.js
Outdated
rules: { | ||
camelcase: 0, // REST API objects include underscores | ||
// NOTE: Some import rules are errors in client (Webpack's resolution) and | ||
// warnings in server (Node's module resolution). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we still define these all as errors and expect the server-specific configuration to override them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can define all of these rules as errors and override them inside server/.eslintrc.json
. The following rules are already overridden for the server:
- Set to warn:
import/default
import/export
import/named
import/namespace
- Set to ignore:
-import/no-commonjs
Which rules would you recommend upgrading to error in .eslintrc.js
? The following rules are currently set as warnings for the client:
import/no-commonjs
import/no-named-as-default-member
import/no-named-as-default
import/no-webpack-loader-syntax
index.js
Outdated
@@ -1,4 +1,5 @@ | |||
/* eslint-disable no-console */ | |||
/* eslint-disable import/no-commonjs */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI you can comma-separate disabled rules in a single eslint-disable
comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it 👍
This custom resolver inspects the file's path to decide which off-the-shelf resolver would be appropriate. For files from the client folder, this resolver uses Webpack's resolver. For other files, this resolver uses Node's resolver.
Peak irony has been reached.
a236882
to
5fa8734
Compare
This reverts commit 127a900.
@jsnmoon This PR needs a rebase |
Given that we're beginning to rely more in Prettier, I think we can put this PR on hold indefinitely for now. I'll leave the branch alive for anyone who'd like to use this as a reference to integrate import path resolution with ESLint. |
(Assists #11688.)
This change adds eslint-plugin-import to our ESLint configuration. It uses either a Webpack resolver or a Node resolver depending on the path of the linted file.
This change helps us verify the validity of existing imports as well as ensuring correctness for any new imports we introduce into the project. This will be especially important as we begin migrating the client module notation from CommonJS to ES.
Todo List:
/client/
directory/server/
directory/test/
directoryCC @ockham @aduth @ehg: Your input would be greatly appreciated!