]> git.proxmox.com Git - pve-eslint.git/blame - eslint/docs/user-guide/migrating-to-2.0.0.md
import 8.4.0 source
[pve-eslint.git] / eslint / docs / user-guide / migrating-to-2.0.0.md
CommitLineData
eb39fafa
DC
1# Migrating to v2.0.0
2
3ESLint v2.0.0 is the second major version release. As a result, there are some significant changes between how ESLint worked during its life in 0.x and 1.x and how it will work going forward. These changes are the direct result of feedback from the ESLint community of users and were not made without due consideration for the upgrade path. We believe that these changes make ESLint even better, and while some work is necessary to upgrade, we hope the pain of this upgrade is small enough that you will see the benefit of upgrading.
4
5**Important:** If you are upgrading from 0.x, please refer to [Migrating to 1.0.0](./migrating-to-1.0.0) as your starting point.
6
7## Rule Schema Changes
8
9Due to a quirk in the way rule schemas worked, it was possible that you'd need to account for the rule severity (0, 1, or 2) in a rule schema if the options were sufficiently complex. That would result in a schema such as:
10
11```js
12module.exports = {
13 "type": "array",
14 "items": [
15 {
16 "enum": [0, 1, 2]
17 },
18 {
19 "enum": ["always", "never"]
20 }
21 ],
22 "minItems": 1,
23 "maxItems": 2
24};
25```
26
27This was confusing to rule developers as it seemed that rules shouldn't be in charge of validating their own severity. In 2.0.0, rules no longer need to check their own severity.
28
29**To address:** If you are exporting a rule schema that checks severity, you need to make several changes:
30
311. Remove the severity from the schema
321. Adjust `minItems` from 1 to 0
331. Adjust `maxItems` by subtracting 1
34
35Here's what the schema from above looks like when properly converted:
36
37```js
38module.exports = {
39 "type": "array",
40 "items": [
41 {
42 "enum": ["always", "never"]
43 }
44 ],
45 "minItems": 0,
46 "maxItems": 1
47};
48```
49
50## Removed Rules
51
52The following rules have been deprecated with new rules created to take their place. The following is a list of the removed rules and their replacements:
53
54* [no-arrow-condition](https://eslint.org/docs/rules/no-arrow-condition) is replaced by a combination of [no-confusing-arrow](https://eslint.org/docs/rules/no-confusing-arrow) and [no-constant-condition](https://eslint.org/docs/rules/no-constant-condition). Turn on both of these rules to get the same functionality as `no-arrow-condition`.
55* [no-empty-label](https://eslint.org/docs/rules/no-empty-label) is replaced by [no-labels](https://eslint.org/docs/rules/no-labels) with `{"allowLoop": true, "allowSwitch": true}` option.
56* [space-after-keywords](https://eslint.org/docs/rules/space-after-keywords) is replaced by [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing).
57* [space-before-keywords](https://eslint.org/docs/rules/space-before-keywords) is replaced by [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing).
58* [space-return-throw-case](https://eslint.org/docs/rules/space-return-throw-case) is replaced by [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing).
59
60**To address:** You'll need to update your rule configurations to use the new rules. ESLint v2.0.0 will also warn you when you're using a rule that has been removed and will suggest the replacement rules. Hopefully, this will result in few surprises during the upgrade process.
61
62## Configuration Cascading Changes
63
64Prior to 2.0.0, if a directory contained both an `.eslintrc` file and a `package.json` file with ESLint configuration information, the settings from the two files would be merged together. In 2.0.0, only the settings from the `.eslintrc.*` file are used and the ones in `package.json` are ignored when both are present. Otherwise, `package.json` can still be used with ESLint configuration, but only if no other `.eslintrc.*` files are present.
65
66**To address:** If you have both an `.eslintrc.*` and `package.json` with ESLint configuration information in the same directory, combine your configurations into just one of those files.
67
68## Built-In Global Variables
69
70Prior to 2.0.0, new global variables that were standardized as part of ES6 such as `Promise`, `Map`, `Set`, and `Symbol` were included in the built-in global environment. This could lead to potential issues when, for example, `no-undef` permitted use of the `Promise` constructor even in ES5 code where promises are unavailable. In 2.0.0, the built-in environment only includes the standard ES5 global variables, and the new ES6 global variables have been moved to the `es6` environment.
71
72**To address:** If you are writing ES6 code, enable the `es6` environment if you have not already done so:
73
74```js
75// In your .eslintrc
76{
77 env: {
78 es6: true
79 }
80}
81
82// Or in a configuration comment
83/*eslint-env es6*/
84```
85
86## Language Options
87
88Prior to 2.0.0, the way to enable language options was by using `ecmaFeatures` in your configuration. In 2.0.0:
89
90* The `ecmaFeatures` property is now under a top-level `parserOptions` property.
91* All ECMAScript 6 `ecmaFeatures` flags have been removed in favor of a `ecmaVersion` property under `parserOptions` that can be set to 3, 5 (default), or 6.
92* The `ecmaFeatures.modules` flag has been replaced by a `sourceType` property under `parserOptions` which can be set to `"script"` (default) or `"module"` for ES6 modules.
93
94**To address:** If you are using any ECMAScript 6 feature flags in `ecmaFeatures`, you'll need to use `ecmaVersion: 6` instead. The ECMAScript 6 feature flags are:
95
96* `arrowFunctions` - enable [arrow functions](https://leanpub.com/understandinges6/read#leanpub-auto-arrow-functions)
97* `binaryLiterals` - enable [binary literals](https://leanpub.com/understandinges6/read#leanpub-auto-octal-and-binary-literals)
98* `blockBindings` - enable `let` and `const` (aka [block bindings](https://leanpub.com/understandinges6/read#leanpub-auto-block-bindings))
99* `classes` - enable classes
100* `defaultParams` - enable [default function parameters](https://leanpub.com/understandinges6/read/#leanpub-auto-default-parameters)
101* `destructuring` - enable [destructuring](https://leanpub.com/understandinges6/read#leanpub-auto-destructuring-assignment)
102* `forOf` - enable [`for-of` loops](https://leanpub.com/understandinges6/read#leanpub-auto-iterables-and-for-of)
103* `generators` - enable [generators](https://leanpub.com/understandinges6/read#leanpub-auto-generators)
104* `modules` - enable modules and global strict mode
105* `objectLiteralComputedProperties` - enable [computed object literal property names](https://leanpub.com/understandinges6/read#leanpub-auto-computed-property-names)
106* `objectLiteralDuplicateProperties` - enable [duplicate object literal properties](https://leanpub.com/understandinges6/read#leanpub-auto-duplicate-object-literal-properties) in strict mode
107* `objectLiteralShorthandMethods` - enable [object literal shorthand methods](https://leanpub.com/understandinges6/read#leanpub-auto-method-initializer-shorthand)
108* `objectLiteralShorthandProperties` - enable [object literal shorthand properties](https://leanpub.com/understandinges6/read#leanpub-auto-property-initializer-shorthand)
109* `octalLiterals` - enable [octal literals](https://leanpub.com/understandinges6/read#leanpub-auto-octal-and-binary-literals)
110* `regexUFlag` - enable the [regular expression `u` flag](https://leanpub.com/understandinges6/read#leanpub-auto-the-regular-expression-u-flag)
111* `regexYFlag` - enable the [regular expression `y` flag](https://leanpub.com/understandinges6/read#leanpub-auto-the-regular-expression-y-flag)
112* `restParams` - enable the [rest parameters](https://leanpub.com/understandinges6/read#leanpub-auto-rest-parameters)
113* `spread` - enable the [spread operator](https://leanpub.com/understandinges6/read#leanpub-auto-the-spread-operator) for arrays
114* `superInFunctions` - enable `super` references inside of functions
115* `templateStrings` - enable [template strings](https://leanpub.com/understandinges6/read/#leanpub-auto-template-strings)
116* `unicodeCodePointEscapes` - enable [code point escapes](https://leanpub.com/understandinges6/read/#leanpub-auto-escaping-non-bmp-characters)
117
118If you're using any of these flags, such as:
119
120```js
121{
122 ecmaFeatures: {
123 arrowFunctions: true
124 }
125}
126```
127
128Then you should enable ES6 using `ecmaVersion`:
129
130```js
131{
132 parserOptions: {
133 ecmaVersion: 6
134 }
135}
136```
137
138If you're using any non-ES6 flags in `ecmaFeatures`, you need to move those inside of `parserOptions`. For instance:
139
140```js
141{
142 ecmaFeatures: {
143 jsx: true
144 }
145}
146```
147
148Then you should move `ecmaFeatures` under `parserOptions`:
149
150```js
151{
152 parserOptions: {
153 ecmaFeatures: {
154 jsx: true
155 }
156 }
157}
158```
159
160If you were using `ecmaFeatures.modules` to enable ES6 module support like this:
161
162```js
163{
164 ecmaFeatures: {
165 modules: true
166 }
167}
168```
169
170```js
171{
172 parserOptions: {
173 sourceType: "module"
174 }
175}
176```
177
178Additionally, if you are using `context.ecmaFeatures` inside of your rules, then you'll need to update your code in the following ways:
179
1801. If you're using an ES6 feature flag such as `context.ecmaFeatures.blockBindings`, rewrite to check for `context.parserOptions.ecmaVersion > 5`.
1811. If you're using `context.ecmaFeatures.modules`, rewrite to check that the `sourceType` property of the Program node is `"module"`.
1821. If you're using a non-ES6 feature flag such as `context.ecmaFeatures.jsx`, rewrite to check for `context.parserOptions.ecmaFeatures.jsx`.
183
184If you have a plugin with rules and you are using RuleTester, then you also need to update the options you pass for rules that use `ecmaFeatures`. For example:
185
186```js
187var ruleTester = new RuleTester();
188ruleTester.run("no-var", rule, {
189 valid: [
190 {
191 code: "let x;",
192 parserOptions: { ecmaVersion: 6 }
193 }
194 ]
195});
196```
197
198If you're not using `ecmaFeatures` in your configuration or your custom/plugin rules and tests, then no change is needed.
199
200## New Rules in `"eslint:recommended"`
201
202```json
203{
204 "extends": "eslint:recommended"
205}
206```
207
208In 2.0.0, the following 11 rules were added to `"eslint:recommended"`.
209
210* [constructor-super](https://eslint.org/docs/rules/constructor-super)
211* [no-case-declarations](https://eslint.org/docs/rules/no-case-declarations)
212* [no-class-assign](https://eslint.org/docs/rules/no-class-assign)
213* [no-const-assign](https://eslint.org/docs/rules/no-const-assign)
214* [no-dupe-class-members](https://eslint.org/docs/rules/no-dupe-class-members)
215* [no-empty-pattern](https://eslint.org/docs/rules/no-empty-pattern)
216* [no-new-symbol](https://eslint.org/docs/rules/no-new-symbol)
217* [no-self-assign](https://eslint.org/docs/rules/no-self-assign)
218* [no-this-before-super](https://eslint.org/docs/rules/no-this-before-super)
219* [no-unexpected-multiline](https://eslint.org/docs/rules/no-unexpected-multiline)
220* [no-unused-labels](https://eslint.org/docs/rules/no-unused-labels)
221
222**To address:** If you don't want to be notified by those rules, you can simply disable those rules.
223
224```json
225{
226 "extends": "eslint:recommended",
227 "rules": {
228 "no-case-declarations": 0,
229 "no-class-assign": 0,
230 "no-const-assign": 0,
231 "no-dupe-class-members": 0,
232 "no-empty-pattern": 0,
233 "no-new-symbol": 0,
234 "no-self-assign": 0,
235 "no-this-before-super": 0,
236 "no-unexpected-multiline": 0,
237 "no-unused-labels": 0,
238 "constructor-super": 0
239 }
240}
241```
242
243## Scope Analysis Changes
244
245We found some bugs in our scope analysis that needed to be addressed. Specifically, we were not properly accounting for global variables in all the ways they are defined.
246
247Originally, `Variable` objects and `Reference` objects refer each other:
248
249* `Variable#references` property is an array of `Reference` objects which are referencing the variable.
250* `Reference#resolved` property is a `Variable` object which are referenced.
251
252But until 1.x, the following variables and references had the wrong value (empty) in those properties:
253
254* `var` declarations in the global.
255* `function` declarations in the global.
256* Variables defined in config files.
257* Variables defined in `/* global */` comments.
258
259Now, those variables and references have correct values in these properties.
260
261`Scope#through` property has references where `Reference#resolved` is `null`. So as a result of this change, the value of `Scope#through` property was changed also.
262
263**To address:** If you are using `Scope#through` to find references of a built-in global variable, you need to make several changes.
264
265For example, this is how you might locate the `window` global variable in 1.x:
266
267```js
268var globalScope = context.getScope();
269globalScope.through.forEach(function(reference) {
270 if (reference.identifier.name === "window") {
271 checkForWindow(reference);
272 }
273});
274```
275
276This was a roundabout way to find the variable because it was added after the fact by ESLint. The `window` variable was in `Scope#through` because the definition couldn't be found.
277
278In 2.0.0, `window` is no longer located in `Scope#through` because we have added back the correct declaration. That means you can reference the `window` object (or any other global object) directly. So the previous example would change to this:
279
280```js
281var globalScope = context.getScope();
282var variable = globalScope.set.get("window");
283if (variable) {
284 variable.references.forEach(checkForWindow);
285}
286```
287
34eeec05 288Further Reading: <https://estools.github.io/escope/>
eb39fafa
DC
289
290## Default Changes When Using `eslint:recommended`
291
292This will affect you if you are extending from `eslint:recommended`, and are enabling [`no-multiple-empty-lines`] or [`func-style`] with only a severity, such as:
293
294```json
295{
296 "extends": "eslint:recommended",
297 "rules": {
298 "no-multiple-empty-lines": 2,
299 "func-style": 2
300 }
301}
302```
303
304The rule `no-multiple-empty-lines` has no default exceptions, but in ESLint `1.x`, a default from `eslint:recommended` was applied such that a maximum of two empty lines would be permitted.
305
306The rule `func-style` has a default configuration of `"expression"`, but in ESLint `1.x`, `eslint:recommended` defaulted it to `"declaration"`.
307
308ESLint 2.0.0 removes these conflicting defaults, and so you may begin seeing linting errors related to these rules.
309
310**To address:** If you would like to maintain the previous behavior, update your configuration for `no-multiple-empty-lines` by adding `{"max": 2}`, and change `func-style` to `"declaration"`. For example:
311
312```json
313{
314 "extends": "eslint:recommended",
315 "rules": {
316 "no-multiple-empty-lines": [2, {"max": 2}],
317 "func-style": [2, "declaration"]
318 }
319}
320```
321
322[`no-multiple-empty-lines`]: ../rules/no-multiple-empty-lines
323[`func-style`]: ../rules/func-style
324
325## SourceCode constructor (Node API) changes
326
327`SourceCode` constructor got to handle Unicode BOM.
328If the first argument `text` has BOM, `SourceCode` constructor sets `true` to `this.hasBOM` and strips BOM from the text.
329
330```js
331var SourceCode = require("eslint").SourceCode;
332
333var code = new SourceCode("\uFEFFvar foo = bar;", ast);
334
335assert(code.hasBOM === true);
336assert(code.text === "var foo = bar;");
337```
338
339So the second argument `ast` also should be parsed from stripped text.
340
341**To address:** If you are using `SourceCode` constructor in your code, please parse the source code after it stripped BOM:
342
343```js
344var ast = yourParser.parse(text.replace(/^\uFEFF/, ""), options);
345var sourceCode = new SourceCode(text, ast);
346```
347
348## Rule Changes
349
350* [`strict`](../rules/strict.md) - defaults to `"safe"` (previous default was `"function"`)
351
352## Plugins No Longer Have Default Configurations
353
354Prior to v2.0.0, plugins could specify a `rulesConfig` for the plugin. The `rulesConfig` would automatically be applied whenever someone uses the plugin, which is the opposite of what ESLint does in every other situation (where nothing is on by default). To bring plugins behavior in line, we have removed support for `rulesConfig` in plugins.
355
356**To address:** If you are using a plugin in your configuration file, you will need to manually enable the plugin rules in the configuration file.