@@ -5,7 +5,15 @@ const MARKDOWN_EXT = "md,mdx"
55
66module . exports = {
77 root : true ,
8- plugins : [ "@graphql-eslint" , "mdx" , "@typescript-eslint" , "tailwindcss" ] ,
8+ plugins : [
9+ "@graphql-eslint" ,
10+ "mdx" ,
11+ "@typescript-eslint" ,
12+ "tailwindcss" ,
13+ "react" ,
14+ "@next/next" ,
15+ "react-hooks" ,
16+ ] ,
917 overrides : [
1018 {
1119 files : [ `**/*.{${ CODE_EXT } }` ] ,
@@ -14,33 +22,67 @@ module.exports = {
1422 "plugin:@typescript-eslint/recommended" ,
1523 "plugin:tailwindcss/recommended" ,
1624 "prettier" ,
25+ "plugin:@next/next/recommended" ,
26+ "plugin:react-hooks/recommended-legacy" ,
27+ "plugin:react/recommended" ,
1728 ] ,
1829 rules : {
19- "tailwindcss/classnames-order" : "off" ,
20- "@typescript-eslint/no-restricted-imports" : [
21- "error" ,
30+ "react/react-in-jsx-scope" : "off" , // TS checks this
31+ "react/prop-types" : "off" , // and this
32+ "no-undef" : "off" , // and this too
33+ // This is type checking for projects without `@types/react`. Disabled due to false positives.
34+ "react/no-unknown-property" : "off" ,
35+
36+ "react/no-unescaped-entities" : [
37+ "warn" , // quotes and apostrophes are okay
2238 {
23- paths : [
39+ forbid : [
2440 {
25- name : "next/image" ,
26- message : "Please use `next-image-export-optimizer` instead" ,
27- allowTypeImports : true ,
41+ char : "<" ,
42+ alternatives : [ "<" ] ,
43+ } ,
44+ {
45+ char : ">" ,
46+ alternatives : [ ">" ] ,
47+ } ,
48+ {
49+ char : "{" ,
50+ alternatives : [ "{" ] ,
51+ } ,
52+ {
53+ char : "}" ,
54+ alternatives : [ "}" ] ,
2855 } ,
2956 ] ,
3057 } ,
3158 ] ,
59+ "@next/next/no-img-element" : "off" , // straight up upsell, small `img`s actually don't need optimization
60+
61+ "tailwindcss/classnames-order" : "off" ,
3262 "prefer-const" : [ "error" , { destructuring : "all" } ] ,
3363 "prefer-rest-params" : "off" ,
3464 "@typescript-eslint/no-explicit-any" : "off" ,
3565 "@typescript-eslint/no-unused-vars" : "off" ,
3666 "@typescript-eslint/ban-ts-comment" : "off" ,
3767 "@typescript-eslint/no-var-requires" : "off" ,
3868 "@typescript-eslint/ban-types" : "off" ,
69+ "no-restricted-syntax" : [
70+ "error" ,
71+ {
72+ selector :
73+ "JSXElement[openingElement.name.name=/^(Image|NextImage)$/]:not(:has(JSXAttribute[name.name='placeholder']))" ,
74+ message :
75+ "Pass `placeholder: 'empty' | 'blur'` when calling <Image> or <NextImage>." ,
76+ } ,
77+ ] ,
3978 } ,
4079 settings : {
4180 tailwindcss : {
4281 whitelist : [ "roboto-mono" ] ,
4382 } ,
83+ react : {
84+ version : "detect" ,
85+ } ,
4486 } ,
4587 } ,
4688 {
@@ -63,6 +105,8 @@ module.exports = {
63105 } ,
64106 rules : {
65107 "mdx/remark" : "error" ,
108+ "no-unused-expressions" : "off" ,
109+ "react/jsx-no-undef" : "off" ,
66110 } ,
67111 } ,
68112 {
@@ -90,7 +134,9 @@ module.exports = {
90134 {
91135 files : [
92136 `src/pages/blog/**/*.{${ MARKDOWN_EXT } }` ,
137+ `src/pages/graphql-js/running-an-express-graphql-server.mdx` ,
93138 `src/code/**/*.{${ MARKDOWN_EXT } }` ,
139+ `src/app/conf/**/*.{${ MARKDOWN_EXT } }` ,
94140 ] ,
95141 rules : {
96142 // Disable `remark-lint-first-heading-level` since in blogs we don't want to enforce the first heading to be an `h1`
0 commit comments