-
Notifications
You must be signed in to change notification settings - Fork 0
/
.eslintrc.js
125 lines (107 loc) · 3.31 KB
/
.eslintrc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* eslint-disable */
const { readFileSync } = require("fs");
const generalRules = {
"no-plusplus": "off",
// Allow leading underscores in identifiers (e.g. _id in MongoDB).
"no-underscore-dangle": "off",
// Some APIs use snake_case identifiers.
camelcase: "off",
// Depending on the context, using bracket notation might be clearer.
"dot-notation": "off",
/**
* Unused variables and arguments should be removed in most cases, but sometimes they are
* unavoidable. Prefix variable names with an underscore to suppress the error.
*/
"no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
},
],
// Not necessary for some APIs (consistency reasons)
"import/prefer-default-export": "off",
};
const reactRules = {
"react/jsx-filename-extension": "off",
"react/prop-types": "off",
"react/destructuring-assignment": "off",
"react/sort-comp": "warn",
// Use warnings instead of errors for issues that aren't deal-breakers.
"react/prefer-stateless-function": "warn",
"react/no-array-index-key": "warn",
};
/**
* Return a rules object which produces warnings instead of errors for accessibility problems.
*/
function getAccessibilityWarningRules() {
const oldRules = require("eslint-plugin-jsx-a11y").rules;
const newRules = {};
Object.entries(oldRules).forEach(([name, _rule]) => {
newRules[`jsx-a11y/${name}`] = "warn";
});
return newRules;
}
/**
* Return a rules object which allows for...of statements to be used, since this syntax produces
* errors with the default airbnb config.
*/
function getAllowForOfRules() {
const airbnbStyleRules = require("eslint-config-airbnb-base/rules/style.js").rules;
return {
"no-restricted-syntax": airbnbStyleRules["no-restricted-syntax"].filter(
(item) => item.selector !== "ForOfStatement"
),
};
}
/**
* Load the .eslintrc.json file, which contains frontend/backend-specific configuration.
*/
function loadConfig() {
const path = ".eslintrc.json";
try {
return JSON.parse(readFileSync(path, "utf8"));
} catch (e) {
throw new Error(
`File '${path}' does not exist. Generate it by running 'npx eslint --init'. When prompted to choose the file format, select JSON.`
);
}
}
const jsonConfig = loadConfig();
/**
* Return whether this part of the project is using React.
*/
function usingReact() {
return jsonConfig.plugins !== undefined && jsonConfig.plugins.includes("react");
}
/**
* Generate the complete rules object.
*/
function generateRules() {
const rules = { ...generalRules };
Object.assign(rules, getAllowForOfRules());
if (usingReact()) {
Object.assign(rules, reactRules);
Object.assign(rules, getAccessibilityWarningRules());
}
return rules;
}
if (process.env.NODE_ENV === "production") {
// In production (e.g. on Heroku), sometimes dev-dependencies are not installed
// This results in errors with the rule generation process
// Since linting isn't necessary in production, we can just ignore it
module.exports = {};
} else {
const rules = generateRules();
module.exports = {
settings: {
react: {
version: "detect",
},
},
...jsonConfig,
...(usingReact() ? { parser: "babel-eslint" } : {}),
extends: ["eslint:recommended", usingReact() ? "airbnb" : "airbnb-base", "prettier"],
rules,
};
}