New rule proposal: Flag duplicate literals
See original GitHub issuePlease describe what the rule should do:
This rule should flag uses of duplicate literals in the same file. The goal of this rule is to recommend that those duplicate literals be combined into one variable, which increases maintainability (by solving the problem of a user changing only a subset of the literals in the file, resulting in inconsistent behavior).
It is assumed that this will only work on literals in the same file. No attempt will be made to cross-reference other JS files to look for duplicates across files.
What category of rule is this? (place an “X” next to just one item)
[ ] Enforces code style [ ] Warns about a potential error [x] Suggests an alternate way of doing something [ ] Other (please specify:)
Provide 2-3 code examples that this rule will warn about:
/**** 1. If conditions written as quick one-liners ****/
if (/myPattern/.test(str)) {
}
// Later...
if (/myPattern/.test(str) && somethingElse()) {
}
/**** 2. Validation configuration in popular libraries ****/
const MyModel = Backbone.Model.extend({
validation: {
WorkEmail: {
pattern: /^[^<>:"^/|%?*\\]*$/,
message: "Email cannot contain special characters"
},
PersonalEmail: {
pattern: /^[^<>:"^/|%?*\\]*$/, // <-- Duplicated RegExp literal
message: "Email cannot contain special characters" // <-- Duplicated string literal
}
}
});
/**** 3. Reusing a literal already in a variable (see Bikeshedding Question 1 below) ****/
const myRegEx = /^somePattern$/;
// Later...
if (/^somePattern$/.test(str)) {
// ...
}
Why should this rule be included in ESLint (instead of a plugin)?
This is a common maintainability refactor, library-independent, and can seriously save time when those duplicated literals need to be changed later.
Some bikeshedding questions:
- Should this rule also flag a literal that is already in a variable (and simply reused), or should that fall under another rule? (See example 3 above)
- What literals should and shouldn’t be flagged, and what sort of options should we supply?
- My proposal is we should flag string, RegExp, and numeric literals by default, and allow users to opt out of any of those types using basic rule options. It would also be great to allow specific exceptions.
- I don’t think we should flag boolean literals because they are ubiquitous and obvious and creating a variable just for a boolean is pretty silly most of the time. I wouldn’t be opposed to adding an option to flag booleans (as an opt-in stricter check), but I don’t think it’s needed.
- It might make sense to check only strings and RegExp literals at first, since there could be conflicts with no-magic-numbers for numeric literals. I’d be okay with that too.
I’ll champion this.
Issue Analytics
- State:
- Created 7 years ago
- Reactions:2
- Comments:27 (27 by maintainers)
Could you explain the value of doing that? I don’t understand why we would want to add options to make this similar to
no-magic-numbers
. In my mind, the rules are enforcing different things –no-magic-numbers
requires “magic” values to be given a semantic meaning, whereasno-duplicate-literals
prevents code duplication. I agree that there’s some overlap there, but the rules have significantly different goals, so I’m not convinced it’s worth trying to combine them. I think having ano-magic-numbers
and ano-duplicate-literals
rule would be fine.Strongly agree with @not-an-aardvark that this proposal is completely different from no-magic-numbers.