xo 0.24.0 → 0.25.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli-main.js CHANGED
@@ -154,12 +154,16 @@ if (options.nodeVersion) {
154
154
  }
155
155
  }
156
156
 
157
- if (options.init) {
158
- require('xo-init')();
159
- } else if (options.stdin) {
160
- getStdin().then(stdin => {
157
+ (async () => {
158
+ if (options.init) {
159
+ require('xo-init')();
160
+ } else if (options.stdin) {
161
+ const stdin = await getStdin();
162
+
161
163
  if (options.fix) {
162
- console.log(xo.lintText(stdin, options).results[0].output);
164
+ const result = xo.lintText(stdin, options).results[0];
165
+ // If there is no output, pass the stdin back out
166
+ console.log(result.output || stdin);
163
167
  return;
164
168
  }
165
169
 
@@ -169,9 +173,9 @@ if (options.init) {
169
173
  }
170
174
 
171
175
  log(xo.lintText(stdin, options));
172
- });
173
- } else {
174
- xo.lintFiles(input, options).then(report => {
176
+ } else {
177
+ const report = await xo.lintFiles(input, options);
178
+
175
179
  if (options.fix) {
176
180
  xo.outputFixes(report);
177
181
  }
@@ -181,5 +185,5 @@ if (options.init) {
181
185
  }
182
186
 
183
187
  log(report);
184
- });
185
- }
188
+ }
189
+ })();
package/cli.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- /* eslint-disable import/no-unassigned-import */
3
2
  'use strict';
4
3
  const resolveCwd = require('resolve-cwd');
5
4
  const hasFlag = require('has-flag');
package/config/plugins.js CHANGED
@@ -3,7 +3,7 @@
3
3
  module.exports = {
4
4
  // Repeated here from eslint-config-xo in case some plugins set something different
5
5
  parserOptions: {
6
- ecmaVersion: 2019,
6
+ ecmaVersion: 2020,
7
7
  sourceType: 'module',
8
8
  ecmaFeatures: {
9
9
  jsx: true
@@ -31,6 +31,36 @@ module.exports = {
31
31
  },
32
32
  rules: {
33
33
  'no-use-extend-native/no-use-extend-native': 'error',
34
+
35
+ // TODO: Enable this again in the minor XO release.
36
+ // TODO: Remove this override at some point.
37
+ // It's just here to ease users into readable variable names.
38
+ // 'unicorn/prevent-abbreviations': [
39
+ // 'error',
40
+ // {
41
+ // checkProperties: false,
42
+ // checkFilenames: false,
43
+ // replacements: {
44
+ // args: false
45
+ // }
46
+ // }
47
+ // ],
48
+ 'unicorn/prevent-abbreviations': 'off',
49
+
50
+ // TODO: Remove this override when the rule is more stable.
51
+ 'unicorn/consistent-function-scoping': 'off',
52
+
53
+ // TODO: Change the rule default for this.
54
+ 'unicorn/expiring-todo-comments': [
55
+ 'error',
56
+ {
57
+ allowWarningComments: true
58
+ }
59
+ ],
60
+
61
+ // TODO: Temporarily disabled as the rule is buggy.
62
+ 'function-call-argument-newline': 'off',
63
+
34
64
  'promise/param-names': 'error',
35
65
  'promise/no-return-wrap': [
36
66
  'error',
@@ -51,12 +81,19 @@ module.exports = {
51
81
  'error',
52
82
  {
53
83
  js: 'never',
54
- json: 'never',
55
- jsx: 'never'
84
+ jsx: 'never',
85
+ json: 'always'
56
86
  }
57
87
  ],
58
- 'import/first': 'error',
59
- 'import/named': 'error',
88
+
89
+ // Disabled as it causes problems with TypeScript when you use mixed ESM and CommonJS
90
+ // TODO: Enable again when I target only ESM
91
+ // 'import/first': 'error',
92
+
93
+ // Disabled as it doesn't work with TypeScript
94
+ // This issue and some others: https://github.com/benmosher/eslint-plugin-import/issues/1341
95
+ // 'import/named': 'error',
96
+
60
97
  'import/namespace': [
61
98
  'error',
62
99
  {
@@ -70,8 +107,16 @@ module.exports = {
70
107
  // Enable this sometime in the future when Node.js has ES2015 module support
71
108
  // 'import/no-cycle': 'error'
72
109
 
73
- 'import/no-useless-path-segments': 'error',
74
- 'import/newline-after-import': 'error',
110
+ 'import/no-useless-path-segments': [
111
+ 'error',
112
+ {
113
+ noUselessIndex: true
114
+ }
115
+ ],
116
+
117
+ // Disabled as it doesn't work with TypeScript
118
+ // 'import/newline-after-import': 'error',
119
+
75
120
  'import/no-amd': 'error',
76
121
  'import/no-duplicates': 'error',
77
122
 
@@ -88,12 +133,15 @@ module.exports = {
88
133
  'import/no-mutable-exports': 'error',
89
134
  'import/no-named-as-default-member': 'error',
90
135
  'import/no-named-as-default': 'error',
91
- 'import/no-unresolved': [
92
- 'error',
93
- {
94
- commonjs: true
95
- }
96
- ],
136
+
137
+ // Disabled because it's buggy and it also doesn't work with TypeScript
138
+ // 'import/no-unresolved': [
139
+ // 'error',
140
+ // {
141
+ // commonjs: true
142
+ // }
143
+ // ],
144
+
97
145
  'import/order': 'error',
98
146
  'import/no-unassigned-import': [
99
147
  'error',
@@ -164,7 +212,7 @@ module.exports = {
164
212
  'error',
165
213
  'always'
166
214
  ],
167
- // TODO: Enable these when XO targets Node.js 8
215
+ // TODO: Enable these when XO targets Node.js 10
168
216
  // 'node/prefer-global/text-decoder': [
169
217
  // 'error',
170
218
  // 'always'
@@ -181,6 +229,8 @@ module.exports = {
181
229
  // 'error',
182
230
  // 'always'
183
231
  // ]
232
+ // 'node/prefer-promises/dns': 'error',
233
+ // 'node/prefer-promises/fs': 'error',
184
234
 
185
235
  'eslint-comments/disable-enable-pair': [
186
236
  'error',
@@ -195,6 +245,9 @@ module.exports = {
195
245
  // 'eslint-comments/no-unlimited-disable': 'error',
196
246
 
197
247
  'eslint-comments/no-unused-disable': 'error',
198
- 'eslint-comments/no-unused-enable': 'error'
248
+ 'eslint-comments/no-unused-enable': 'error',
249
+
250
+ // Disabled by default, enabled only in Node.js >= 11 in option-manager.js
251
+ 'unicorn/prefer-flat-map': 'off'
199
252
  }
200
253
  };
package/index.js CHANGED
@@ -34,11 +34,14 @@ const processReport = (report, options) => {
34
34
  const runEslint = (paths, options) => {
35
35
  const config = optionsManager.buildConfig(options);
36
36
  const engine = new eslint.CLIEngine(config);
37
- const report = engine.executeOnFiles(paths, config);
37
+ const report = engine.executeOnFiles(
38
+ paths.filter(path => !engine.isPathIgnored(path)),
39
+ config,
40
+ );
38
41
  return processReport(report, options);
39
42
  };
40
43
 
41
- module.exports.lintText = (str, options) => {
44
+ module.exports.lintText = (string, options) => {
42
45
  options = optionsManager.preprocess(options);
43
46
 
44
47
  if (options.overrides && options.overrides.length > 0) {
@@ -58,12 +61,15 @@ module.exports.lintText = (str, options) => {
58
61
  throw new Error('The `ignores` option requires the `filename` option to be defined.');
59
62
  }
60
63
 
64
+ const engine = new eslint.CLIEngine(options);
65
+
61
66
  if (options.filename) {
62
67
  const filename = path.relative(options.cwd, options.filename);
63
68
 
64
69
  if (
65
70
  multimatch(filename, options.ignores).length > 0 ||
66
- globby.gitignore.sync({cwd: options.cwd, ignore: options.ignores})(options.filename)
71
+ globby.gitignore.sync({cwd: options.cwd, ignore: options.ignores})(options.filename) ||
72
+ engine.isPathIgnored(options.filename)
67
73
  ) {
68
74
  return {
69
75
  errorCount: 0,
@@ -78,46 +84,46 @@ module.exports.lintText = (str, options) => {
78
84
  }
79
85
  }
80
86
 
81
- const engine = new eslint.CLIEngine(options);
82
- const report = engine.executeOnText(str, options.filename);
87
+ const report = engine.executeOnText(string, options.filename);
83
88
 
84
89
  return processReport(report, options);
85
90
  };
86
91
 
87
- module.exports.lintFiles = (patterns, options) => {
92
+ module.exports.lintFiles = async (patterns, options) => {
88
93
  options = optionsManager.preprocess(options);
89
94
 
90
95
  const isEmptyPatterns = patterns.length === 0;
91
96
  const defaultPattern = `**/*.{${options.extensions.join(',')}}`;
92
97
 
93
- return globby(
98
+ let paths = await globby(
94
99
  isEmptyPatterns ? [defaultPattern] : arrify(patterns),
95
100
  {
96
101
  ignore: options.ignores,
97
102
  gitignore: true,
98
103
  cwd: options.cwd
99
104
  }
100
- ).then(paths => {
101
- // Filter out unwanted file extensions
102
- // For silly users that don't specify an extension in the glob pattern
103
- if (!isEmptyPatterns) {
104
- paths = paths.filter(filePath => {
105
- const ext = path.extname(filePath).replace('.', '');
106
- return options.extensions.includes(ext);
107
- });
108
- }
105
+ );
106
+ paths = paths.map(x => path.relative(options.cwd, path.resolve(options.cwd, x)));
107
+
108
+ // Filter out unwanted file extensions
109
+ // For silly users that don't specify an extension in the glob pattern
110
+ if (!isEmptyPatterns) {
111
+ paths = paths.filter(filePath => {
112
+ const extension = path.extname(filePath).replace('.', '');
113
+ return options.extensions.includes(extension);
114
+ });
115
+ }
109
116
 
110
- if (!(options.overrides && options.overrides.length > 0)) {
111
- return runEslint(paths, options);
112
- }
117
+ if (!(options.overrides && options.overrides.length > 0)) {
118
+ return runEslint(paths, options);
119
+ }
113
120
 
114
- const {overrides} = options;
115
- delete options.overrides;
121
+ const {overrides} = options;
122
+ delete options.overrides;
116
123
 
117
- const grouped = optionsManager.groupConfigs(paths, options, overrides);
124
+ const grouped = optionsManager.groupConfigs(paths, options, overrides);
118
125
 
119
- return mergeReports(grouped.map(data => runEslint(data.paths, data.options)));
120
- });
126
+ return mergeReports(grouped.map(data => runEslint(data.paths, data.options)));
121
127
  };
122
128
 
123
129
  module.exports.getFormatter = eslint.CLIEngine.getFormatter;
@@ -32,15 +32,13 @@ const resultToFile = result => {
32
32
  };
33
33
  };
34
34
 
35
- const files = (report, predicate) => report.results
35
+ const getFiles = (report, predicate) => report.results
36
36
  .filter(result => predicate(result))
37
37
  .sort(sortResults)
38
38
  .map(result => resultToFile(result));
39
39
 
40
40
  module.exports = report => {
41
- if (report.errorCount > 0) {
42
- openEditor(files(report, result => result.errorCount > 0));
43
- } else if (report.warningCount > 0) {
44
- openEditor(files(report, result => result.warningCount > 0));
45
- }
41
+ const count = report.errorCount > 0 ? 'errorCount' : 'warningCount';
42
+ const files = getFiles(report, result => result[count] > 0);
43
+ openEditor(files);
46
44
  };
@@ -19,7 +19,8 @@ const DEFAULT_IGNORE = [
19
19
  '{tmp,temp}/**',
20
20
  '**/*.min.js',
21
21
  'vendor/**',
22
- 'dist/**'
22
+ 'dist/**',
23
+ 'tap-snapshots/*.js'
23
24
  ];
24
25
 
25
26
  const DEFAULT_EXTENSION = [
@@ -95,8 +96,20 @@ const ENGINE_RULES = {
95
96
  'always'
96
97
  ]
97
98
  },
99
+ 'node/prefer-promises/dns': {
100
+ '12.0.0': 'error'
101
+ },
102
+ 'node/prefer-promises/fs': {
103
+ '12.0.0': 'error'
104
+ },
98
105
  'no-useless-catch': {
99
106
  '10.0.0': 'error'
107
+ },
108
+ 'prefer-named-capture-group': {
109
+ '10.0.0': 'error'
110
+ },
111
+ 'unicorn/prefer-flat-map': {
112
+ '11.0.0': 'error'
100
113
  }
101
114
  };
102
115
 
@@ -108,7 +121,7 @@ const mergeFn = (previousValue, value) => {
108
121
  };
109
122
 
110
123
  const normalizeOptions = options => {
111
- options = Object.assign({}, options);
124
+ options = {...options};
112
125
 
113
126
  // Aliases for humans
114
127
  const aliases = [
@@ -142,17 +155,26 @@ const normalizeOptions = options => {
142
155
  return options;
143
156
  };
144
157
 
145
- const mergeWithPkgConf = options => {
146
- options = Object.assign({cwd: process.cwd()}, options);
158
+ const mergeWithPackageConfig = options => {
159
+ options = {
160
+ cwd: process.cwd(),
161
+ ...options
162
+ };
163
+
147
164
  options.cwd = path.resolve(options.cwd);
148
- const conf = pkgConf.sync('xo', {cwd: options.cwd, skipOnFalse: true});
165
+ const config = pkgConf.sync('xo', {cwd: options.cwd, skipOnFalse: true});
149
166
  const engines = pkgConf.sync('engines', {cwd: options.cwd});
150
- return Object.assign({}, conf, {nodeVersion: engines && engines.node && semver.validRange(engines.node)}, options);
167
+
168
+ return {
169
+ ...config,
170
+ nodeVersion: engines && engines.node && semver.validRange(engines.node),
171
+ ...options
172
+ };
151
173
  };
152
174
 
153
175
  const normalizeSpaces = options => typeof options.space === 'number' ? options.space : 2;
154
176
 
155
- const mergeWithPrettierConf = (options, prettierOptions) => {
177
+ const mergeWithPrettierConfig = (options, prettierOptions) => {
156
178
  if ((options.semicolon === true && prettierOptions.semi === false) ||
157
179
  (options.semicolon === false && prettierOptions.semi === true)) {
158
180
  throw new Error(`The Prettier config \`semi\` is ${prettierOptions.semi} while XO \`semicolon\` is ${options.semicolon}`);
@@ -269,13 +291,13 @@ const buildConfig = options => {
269
291
  name = `eslint-config-${name}`;
270
292
  }
271
293
 
272
- const ret = resolveFrom(options.cwd, name);
294
+ const returnValue = resolveFrom(options.cwd, name);
273
295
 
274
- if (!ret) {
296
+ if (!returnValue) {
275
297
  throw new Error(`Couldn't find ESLint config: ${name}`);
276
298
  }
277
299
 
278
- return ret;
300
+ return returnValue;
279
301
  });
280
302
 
281
303
  config.baseConfig.extends = config.baseConfig.extends.concat(configs);
@@ -285,13 +307,15 @@ const buildConfig = options => {
285
307
  if (options.prettier) {
286
308
  // Disable formatting rules conflicting with Prettier
287
309
  config.rules['unicorn/number-literal-case'] = 'off';
310
+ // Can be re-enabled when https://github.com/prettier/prettier/issues/4157 is fixed
311
+ config.rules['unicorn/no-nested-ternary'] = 'off';
288
312
  // The prettier plugin uses Prettier to format the code with `--fix`
289
313
  config.plugins = config.plugins.concat('prettier');
290
314
  // The prettier config overrides ESLint stylistic rules that are handled by Prettier
291
315
  config.baseConfig.extends = config.baseConfig.extends.concat('prettier');
292
316
  // The `prettier/prettier` rule reports errors if the code is not formatted in accordance to Prettier
293
317
  config.rules['prettier/prettier'] = [
294
- 'error', mergeWithPrettierConf(options, prettier.resolveConfig.sync(options.cwd || process.cwd()) || {})
318
+ 'error', mergeWithPrettierConfig(options, prettier.resolveConfig.sync(options.cwd || process.cwd()) || {})
295
319
  ];
296
320
  // If the user has the React, Flowtype, or Standard plugin, add the corresponding Prettier rule overrides
297
321
  // See https://github.com/prettier/eslint-config-prettier for the list of plugins overrrides
@@ -364,7 +388,7 @@ const getIgnores = options => {
364
388
  };
365
389
 
366
390
  const preprocess = options => {
367
- options = mergeWithPkgConf(options);
391
+ options = mergeWithPackageConfig(options);
368
392
  options = normalizeOptions(options);
369
393
  options = getIgnores(options);
370
394
  options.extensions = DEFAULT_EXTENSION.concat(options.extensions || []);
@@ -373,8 +397,8 @@ const preprocess = options => {
373
397
 
374
398
  module.exports.DEFAULT_IGNORE = DEFAULT_IGNORE;
375
399
  module.exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
376
- module.exports.mergeWithPkgConf = mergeWithPkgConf;
377
- module.exports.mergeWithPrettierConf = mergeWithPrettierConf;
400
+ module.exports.mergeWithPackageConfig = mergeWithPackageConfig;
401
+ module.exports.mergeWithPrettierConfig = mergeWithPrettierConfig;
378
402
  module.exports.normalizeOptions = normalizeOptions;
379
403
  module.exports.buildConfig = buildConfig;
380
404
  module.exports.findApplicableOverrides = findApplicableOverrides;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "xo",
3
- "version": "0.24.0",
4
- "description": "JavaScript happiness style linter ❤️",
3
+ "version": "0.25.3",
4
+ "description": "JavaScript linter with great defaults",
5
5
  "license": "MIT",
6
6
  "repository": "xojs/xo",
7
7
  "author": {
@@ -11,10 +11,10 @@
11
11
  },
12
12
  "bin": "cli.js",
13
13
  "engines": {
14
- "node": ">=6"
14
+ "node": ">=8"
15
15
  },
16
16
  "scripts": {
17
- "test": "node cli-main.js && eslint . && nyc ava"
17
+ "test": "eslint --quiet . && nyc ava"
18
18
  },
19
19
  "files": [
20
20
  "config",
@@ -33,7 +33,6 @@
33
33
  "style",
34
34
  "lint",
35
35
  "linter",
36
- "jscs",
37
36
  "jshint",
38
37
  "jslint",
39
38
  "eslint",
@@ -49,49 +48,50 @@
49
48
  "simple"
50
49
  ],
51
50
  "dependencies": {
52
- "arrify": "^1.0.1",
51
+ "arrify": "^2.0.1",
53
52
  "debug": "^4.1.0",
54
- "eslint": "^5.12.0",
55
- "eslint-config-prettier": "^3.3.0",
56
- "eslint-config-xo": "^0.26.0",
53
+ "eslint": "^6.4.0",
54
+ "eslint-config-prettier": "^6.3.0",
55
+ "eslint-config-xo": "^0.27.1",
57
56
  "eslint-formatter-pretty": "^2.0.0",
58
- "eslint-plugin-ava": "^5.1.0",
57
+ "eslint-plugin-ava": "^9.0.0",
59
58
  "eslint-plugin-eslint-comments": "^3.0.1",
60
- "eslint-plugin-import": "^2.14.0",
59
+ "eslint-plugin-import": "^2.18.2",
61
60
  "eslint-plugin-no-use-extend-native": "^0.4.0",
62
- "eslint-plugin-node": "^8.0.0",
63
- "eslint-plugin-prettier": "^3.0.0",
61
+ "eslint-plugin-node": "^10.0.0",
62
+ "eslint-plugin-prettier": "^3.1.1",
64
63
  "eslint-plugin-promise": "^4.0.0",
65
- "eslint-plugin-unicorn": "^7.0.0",
66
- "find-cache-dir": "^2.0.0",
67
- "get-stdin": "^6.0.0",
64
+ "eslint-plugin-unicorn": "^12.0.0",
65
+ "find-cache-dir": "^3.0.0",
66
+ "get-stdin": "^7.0.0",
68
67
  "globby": "^9.0.0",
69
- "has-flag": "^3.0.0",
68
+ "has-flag": "^4.0.0",
70
69
  "lodash.isequal": "^4.5.0",
71
- "lodash.mergewith": "^4.6.1",
70
+ "lodash.mergewith": "^4.6.2",
72
71
  "meow": "^5.0.0",
73
- "multimatch": "^3.0.0",
74
- "open-editor": "^1.2.0",
75
- "path-exists": "^3.0.0",
76
- "pkg-conf": "^2.1.0",
72
+ "multimatch": "^4.0.0",
73
+ "open-editor": "^2.0.1",
74
+ "path-exists": "^4.0.0",
75
+ "pkg-conf": "^3.1.0",
77
76
  "prettier": "^1.15.2",
78
- "resolve-cwd": "^2.0.0",
79
- "resolve-from": "^4.0.0",
80
- "semver": "^5.5.0",
81
- "slash": "^2.0.0",
82
- "update-notifier": "^2.3.0",
77
+ "resolve-cwd": "^3.0.0",
78
+ "resolve-from": "^5.0.0",
79
+ "semver": "^6.3.0",
80
+ "slash": "^3.0.0",
81
+ "update-notifier": "^3.0.1",
83
82
  "xo-init": "^0.7.0"
84
83
  },
85
84
  "devDependencies": {
86
85
  "ava": "^1.1.0",
87
- "coveralls": "^3.0.0",
88
- "eslint-config-xo-react": "^0.17.0",
89
- "eslint-plugin-react": "^7.6.1",
86
+ "coveralls": "^3.0.6",
87
+ "eslint-config-xo-react": "^0.20.0",
88
+ "eslint-plugin-react": "^7.14.3",
89
+ "eslint-plugin-react-hooks": "^2.0.1",
90
90
  "execa": "^1.0.0",
91
- "nyc": "^13.0.1",
91
+ "nyc": "^14.1.1",
92
92
  "pify": "^4.0.0",
93
- "proxyquire": "^2.0.1",
94
- "temp-write": "^3.4.0"
93
+ "proxyquire": "^2.1.3",
94
+ "temp-write": "^4.0.0"
95
95
  },
96
96
  "eslintConfig": {
97
97
  "extends": "eslint-config-xo"
package/readme.md CHANGED
@@ -6,7 +6,7 @@
6
6
  <br>
7
7
  </h1>
8
8
 
9
- > JavaScript happiness style linter
9
+ > JavaScript linter with great defaults
10
10
 
11
11
  [![Build Status](https://travis-ci.org/xojs/xo.svg?branch=master)](https://travis-ci.org/xojs/xo) [![Coverage Status](https://coveralls.io/repos/github/xojs/xo/badge.svg?branch=master)](https://coveralls.io/github/xojs/xo?branch=master) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) [![Gitter](https://badges.gitter.im/join_chat.svg)](https://gitter.im/xojs/Lobby)
12
12
 
@@ -16,6 +16,8 @@ Uses [ESLint](https://eslint.org) underneath, so issues regarding rules should b
16
16
 
17
17
  *JSX is supported by default, but you'll need [eslint-config-xo-react](https://github.com/xojs/eslint-config-xo-react#use-with-xo) for React specific linting.*
18
18
 
19
+ *Vue components are not supported by default. You'll need [eslint-config-xo-vue](https://github.com/ChocPanda/eslint-config-xo-vue#use-with-xo) for specific linting in a Vue app.*
20
+
19
21
  ![](https://raw.githubusercontent.com/sindresorhus/eslint-formatter-pretty/master/screenshot.png)
20
22
 
21
23
 
@@ -160,26 +162,26 @@ You can configure some options in XO by putting it in package.json:
160
162
 
161
163
  ### envs
162
164
 
163
- Type: `Array`<br>
165
+ Type: `string[]`<br>
164
166
  Default: `['node']`
165
167
 
166
168
  Which [environments](https://eslint.org/docs/user-guide/configuring#specifying-environments) your code is designed to run in. Each environment brings with it a certain set of predefined global variables.
167
169
 
168
170
  ### globals
169
171
 
170
- Type: `Array`
172
+ Type: `string[]`
171
173
 
172
174
  Additional global variables your code accesses during execution.
173
175
 
174
176
  ### ignores
175
177
 
176
- Type: `Array`
178
+ Type: `string[]`
177
179
 
178
- Some [paths](lib/options-manager.js) are ignored by default, including paths in `.gitignore`. Additional ignores can be added here.
180
+ Some [paths](lib/options-manager.js) are ignored by default, including paths in `.gitignore` and [.eslintignore](https://eslint.org/docs/user-guide/configuring#eslintignore). Additional ignores can be added here.
179
181
 
180
182
  ### space
181
183
 
182
- Type: `boolean`, `number`<br>
184
+ Type: `boolean | number`<br>
183
185
  Default: `false` *(tab indentation)*
184
186
 
185
187
  Set it to `true` to get 2-space indentation or specify the number of spaces.
@@ -188,7 +190,7 @@ This option exists for pragmatic reasons, but I would strongly recommend you rea
188
190
 
189
191
  ### rules
190
192
 
191
- Type: `Object`
193
+ Type: `object`
192
194
 
193
195
  Override any of the [default rules](https://github.com/xojs/eslint-config-xo/blob/master/index.js). See the [ESLint docs](https://eslint.org/docs/rules/) for more info on each rule.
194
196
 
@@ -197,7 +199,7 @@ Please take a moment to consider if you really need to use this option.
197
199
  ### semicolon
198
200
 
199
201
  Type: `boolean`<br>
200
- Default: `true` *(semicolons required)*
202
+ Default: `true` *(Semicolons required)*
201
203
 
202
204
  Set it to `false` to enforce no-semicolon style.
203
205
 
@@ -221,33 +223,34 @@ If contradicting options are set for both Prettier and XO an error will be throw
221
223
 
222
224
  ### nodeVersion
223
225
 
224
- Type: `string`, `boolean`<br>
226
+ Type: `string | boolean`<br>
225
227
  Default: Value of the `engines.node` key in the project `package.json`
226
228
 
227
229
  Enable rules specific to the Node.js versions within the configured range.
230
+
228
231
  If set to `false`, no rules specific to a Node.js version will be enabled.
229
232
 
230
233
  ### plugins
231
234
 
232
- Type: `Array`
235
+ Type: `string[]`
233
236
 
234
237
  Include third-party [plugins](https://eslint.org/docs/user-guide/configuring.html#configuring-plugins).
235
238
 
236
239
  ### extends
237
240
 
238
- Type: `Array`, `string`
241
+ Type: `string | string[]`
239
242
 
240
243
  Use one or more [shareable configs](https://eslint.org/docs/developer-guide/shareable-configs.html) or [plugin configs](https://eslint.org/docs/user-guide/configuring#using-the-configuration-from-a-plugin) to override any of the default rules (like `rules` above).
241
244
 
242
245
  ### extensions
243
246
 
244
- Type: `Array`
247
+ Type: `string[]`
245
248
 
246
249
  Allow more extensions to be linted besides `.js` and `.jsx`. Make sure they're supported by ESLint or an ESLint plugin.
247
250
 
248
251
  ### settings
249
252
 
250
- Type: `Object`
253
+ Type: `object`
251
254
 
252
255
  [Shared ESLint settings](https://eslint.org/docs/user-guide/configuring#adding-shared-settings) exposed to rules. For example, to configure the [`import`](https://github.com/benmosher/eslint-plugin-import#settings) plugin to use your webpack configuration for determining search paths, you can put `{"import/resolver": "webpack"}` here.
253
256
 
@@ -385,7 +388,8 @@ XO is based on ESLint. This project started out as just a shareable ESLint confi
385
388
 
386
389
  - [Gulp](https://github.com/xojs/gulp-xo)
387
390
  - [Grunt](https://github.com/xojs/grunt-xo)
388
- - [webpack](https://github.com/Semigradsky/xo-loader)
391
+ - [webpack loader](https://github.com/Semigradsky/xo-loader)
392
+ - [webpack plugin](https://github.com/nstanard/xo-webpack-plugin)
389
393
  - [Metalsmith](https://github.com/blainsmith/metalsmith-xo)
390
394
  - [Fly](https://github.com/lukeed/fly-xo)
391
395
 
@@ -395,6 +399,7 @@ XO is based on ESLint. This project started out as just a shareable ESLint confi
395
399
  - [eslint-config-xo](https://github.com/xojs/eslint-config-xo) - ESLint shareable config for XO with tab indent
396
400
  - [eslint-config-xo-space](https://github.com/xojs/eslint-config-xo-space) - ESLint shareable config for XO with 2-space indent
397
401
  - [eslint-config-xo-react](https://github.com/xojs/eslint-config-xo-react) - ESLint shareable config for React to be used with the above
402
+ - [eslint-config-xo-vue](https://github.com/ChocPanda/eslint-config-xo-vue) - ESLint shareable config for Vue to be used with the above
398
403
  - [stylelint-config-xo](https://github.com/xojs/stylelint-config-xo) - Stylelint shareable config for XO with tab indent
399
404
  - [stylelint-config-xo-space](https://github.com/xojs/stylelint-config-xo-space) - Stylelint shareable config for XO with 2-space indent
400
405
  - [tslint-xo](https://github.com/xojs/tslint-xo) - TSLint shareable config for XO
@@ -404,7 +409,6 @@ XO is based on ESLint. This project started out as just a shareable ESLint confi
404
409
 
405
410
  ## Support
406
411
 
407
- - [Gitter chat](https://gitter.im/xojs/Lobby)
408
412
  - [Twitter](https://twitter.com/sindresorhus)
409
413
 
410
414
 
@@ -435,8 +439,3 @@ You can also find some nice dynamic XO badges on [badgen.net](https://badgen.net
435
439
 
436
440
  - [James Talmage](https://github.com/jamestalmage)
437
441
  - [Michael Mayer](https://github.com/schnittstabil)
438
-
439
-
440
- ## License
441
-
442
- MIT