-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
feat(gatsby): add required eslint rules even if user has custom eslint config #28911
Changes from 1 commit
479af2c
f5ad45a
cd016ff
f477549
67d085b
8fd1faf
5c6bedc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module.exports = { | ||
rules: { | ||
// Custom ESLint rules from Gatsby | ||
"no-anonymous-exports-page-templates": `warn`, | ||
"limited-exports-page-templates": `warn`, | ||
}, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import * as path from "path" | ||
import { Loader, RuleSetRule, Plugin } from "webpack" | ||
import { Loader, RuleSetRule, Plugin, Configuration } from "webpack" | ||
import { GraphQLSchema } from "graphql" | ||
import postcss from "postcss" | ||
import autoprefixer from "autoprefixer" | ||
|
@@ -20,7 +20,11 @@ import { | |
|
||
import { builtinPlugins } from "./webpack-plugins" | ||
import { IProgram, Stage } from "../commands/types" | ||
import { eslintConfig } from "./eslint-config" | ||
import { | ||
eslintConfig, | ||
mergeRequiredConfigIn, | ||
eslintRequiredConfig, | ||
} from "./eslint-config" | ||
|
||
type LoaderResolver<T = {}> = (options?: T) => Loader | ||
|
||
|
@@ -124,6 +128,8 @@ interface IWebpackUtils { | |
plugins: PluginUtils | ||
} | ||
|
||
const vendorRegex = /(node_modules|bower_components)/ | ||
|
||
/** | ||
* A factory method that produces an atoms namespace | ||
*/ | ||
|
@@ -132,7 +138,6 @@ export const createWebpackUtils = ( | |
program: IProgram | ||
): IWebpackUtils => { | ||
const assetRelativeRoot = `static/` | ||
const vendorRegex = /(node_modules|bower_components)/ | ||
const supportedBrowsers = getBrowsersList(program.directory) | ||
|
||
const PRODUCTION = !stage.includes(`develop`) | ||
|
@@ -749,3 +754,38 @@ export function reactHasJsxRuntime(): boolean { | |
|
||
return false | ||
} | ||
|
||
export function ensureRequireEslintRules(config: Configuration): Configuration { | ||
// for fast refresh we want to ensure that that there is eslint rule running | ||
// because user might have added their own `eslint-loader` let's check if there is one | ||
// and adjust it to add the rule or append new loader with required rule | ||
const rule = config.module.rules.find(rule => { | ||
if (typeof rule.loader === `string`) { | ||
return rule.loader.includes(`eslint-loader`) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Includes? No risk of false positives here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe I can keep There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think filename based validation is fine here. But a substr check seems a little too much of a shortcut, that's all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm, so do you have any advice on what would good to do here? I can cover maybe few specific scenario:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added hopefully more strict checks in f477549 which I don't particularly like (but neither I did |
||
} | ||
|
||
return false | ||
}) | ||
|
||
if (rule) { | ||
if (typeof rule.options !== `string`) { | ||
mergeRequiredConfigIn(rule.options) | ||
} | ||
} else { | ||
config.module.rules.push({ | ||
enforce: `pre`, | ||
test: /\.jsx?$/, | ||
exclude: (modulePath: string): boolean => | ||
modulePath.includes(VIRTUAL_MODULES_BASE_PATH) || | ||
vendorRegex.test(modulePath), | ||
use: [ | ||
{ | ||
loader: require.resolve(`eslint-loader`), | ||
options: eslintRequiredConfig, | ||
}, | ||
], | ||
}) | ||
} | ||
|
||
return 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.
So if
.extends
exists but is not an array then theeslintRequirePreset
part is silently dropped? Smells like a bit like a footgun.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.
You are right, I thought
extends
only accept arrays but it also accept just strings, so I will add handling for itThere 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.
Added handling for single string case in f5ad45a + some tests for it