Skip to content

Commit

Permalink
Add node/no-unsupported-features rules and fix unit tests (#341)
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdlg authored Feb 18, 2020
1 parent e0f81a7 commit 2297c07
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 29 deletions.
3 changes: 0 additions & 3 deletions config/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,6 @@ module.exports = {
// }
// ],

// Disabled as the rule doesn't allow to exclude compiled sources
// 'node/no-unsupported-features': 'error',

'node/process-exit-as-throw': 'error',

// Disabled as the rule doesn't exclude scripts executed with `node` but not referenced in 'bin'. See https://github.com/mysticatea/eslint-plugin-node/issues/96
Expand Down
6 changes: 6 additions & 0 deletions lib/options-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ const buildXOConfig = options => config => {
}
}

if (options.nodeVersion) {
config.rules['node/no-unsupported-features/es-builtins'] = ['error', {version: options.nodeVersion}];
config.rules['node/no-unsupported-features/es-syntax'] = ['error', {version: options.nodeVersion, ignores: ['modules']}];
config.rules['node/no-unsupported-features/node-builtins'] = ['error', {version: options.nodeVersion}];
}

if (options.space && !options.prettier) {
config.rules.indent = ['error', spaces, {SwitchCase: 1}];

Expand Down
23 changes: 18 additions & 5 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,23 +336,37 @@ Put a `package.json` with your config at the root and omit the `xo` property in

### Transpilation

If some files in your project are transpiled in order to support an older Node.js version, you can use the [config overrides](#config-overrides) option to set a specific [`nodeVersion`](#nodeversion) target for these files.
If some files in your project are transpiled in order to support an older Node.js version, you can use the [config overrides](#config-overrides) option to set a specific [`nodeVersion`](#nodeversion) to target your sources files.

For example, if your project targets Node.js 4 (your `package.json` is configured with `engines.node` set to `>=4`) and you are using [AVA](https://github.com/avajs/ava), then your test files are automatically transpiled. You can override `nodeVersion` for the tests files:
For example, if your project targets Node.js 8 but you want to use the latest JavaScript syntax as supported in Node.js 12:
1. Set the `engines.node` property of your `package.json` to `>=8`
2. Configure [Babel](https://babeljs.io) to transpile your source files (in `src` directory in this example)
3. Make sure to include the transpiled files in your published package with the [`files`](https://docs.npmjs.com/files/package.json#files) and [`main`](https://docs.npmjs.com/files/package.json#main) properties of your `package.json`
4. Configure the XO `overrides` option to set `nodeVersion` to `>=12` for your source files directory

```json
{
"engines": {
"node": ">=8"
},
"scripts": {
"build": "babel src --out-dir dist"
},
"main": "dist/index.js",
"files": ["dist/**/*.js"],
"xo": {
"overrides": [
{
"files": "{test,tests,spec,__tests__}/**/*.js",
"nodeVersion": ">=9"
"files": "{src}/**/*.js",
"nodeVersion": ">=12"
}
]
}
}
```

This way your `package.json` will contain the actual minimum Node.js version supported by your published code, but XO will lint your source code as if it targets Node.js 12.

### Including files ignored by default

To include files that XO [ignores by default](https://github.com/xojs/xo/blob/master/lib/constants.js#L1), add them as negative globs in the `ignores` option:
Expand All @@ -367,7 +381,6 @@ To include files that XO [ignores by default](https://github.com/xojs/xo/blob/ma
}
```


## FAQ

#### What does XO mean?
Expand Down
41 changes: 20 additions & 21 deletions test/options-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,8 @@ test('buildConfig: space: 4', t => {

test('buildConfig: semicolon', t => {
const config = manager.buildConfig({semicolon: false, nodeVersion: '12'});
t.deepEqual(config.rules, {
semi: ['error', 'never'],
'semi-spacing': ['error', {
before: false,
after: true
}]
});
t.deepEqual(config.rules.semi, ['error', 'never']);
t.deepEqual(config.rules['semi-spacing'], ['error', {before: false, after: true}]);
});

test('buildConfig: prettier: true', t => {
Expand Down Expand Up @@ -211,6 +206,9 @@ test('buildConfig: engines: undefined', t => {
t.is(config.rules['unicorn/prefer-flat-map'], 'off');
t.is(config.rules['node/prefer-promises/dns'], 'off');
t.is(config.rules['node/prefer-promises/fs'], 'off');
t.is(config.rules['node/no-unsupported-features/es-builtins'], undefined);
t.is(config.rules['node/no-unsupported-features/es-syntax'], undefined);
t.is(config.rules['node/no-unsupported-features/node-builtins'], undefined);
});

test('buildConfig: nodeVersion: false', t => {
Expand All @@ -226,31 +224,32 @@ test('buildConfig: nodeVersion: false', t => {
t.is(config.rules['node/prefer-promises/fs'], 'off');
});

test('buildConfig: nodeVersion: invalid range', t => {
const config = manager.buildConfig({nodeVersion: '4'});

// Override all the rules specific to Node.js version
t.is(config.rules['prefer-object-spread'], 'off');
t.is(config.rules['prefer-rest-params'], 'off');
t.is(config.rules['prefer-destructuring'], 'off');
t.is(config.rules['promise/prefer-await-to-then'], 'off');
t.is(config.rules['unicorn/prefer-flat-map'], 'off');
t.is(config.rules['node/prefer-promises/dns'], 'off');
t.is(config.rules['node/prefer-promises/fs'], 'off');
});

test('buildConfig: nodeVersion: >=6', t => {
const config = manager.buildConfig({nodeVersion: '>=6'});

// Turn off rule if we support Node.js below 7.6.0
t.is(config.rules['promise/prefer-await-to-then'], 'off');
// Set node/no-unsupported-features rules with the nodeVersion
t.deepEqual(config.rules['node/no-unsupported-features/es-builtins'], ['error', {version: '>=6'}]);
t.deepEqual(
config.rules['node/no-unsupported-features/es-syntax'],
['error', {version: '>=6', ignores: ['modules']}]
);
t.deepEqual(config.rules['node/no-unsupported-features/node-builtins'], ['error', {version: '>=6'}]);
});

test('buildConfig: nodeVersion: >=8', t => {
const config = manager.buildConfig({nodeVersion: '>=8'});

// Do not turn off rule if we support only Node.js above 7.6.0
t.is(config.rules['promise/prefer-await-to-then'], undefined);
// Set node/no-unsupported-features rules with the nodeVersion
t.deepEqual(config.rules['node/no-unsupported-features/es-builtins'], ['error', {version: '>=8'}]);
t.deepEqual(
config.rules['node/no-unsupported-features/es-syntax'],
['error', {version: '>=8', ignores: ['modules']}]
);
t.deepEqual(config.rules['node/no-unsupported-features/node-builtins'], ['error', {version: '>=8'}]);
});

test('mergeWithPrettierConfig: use `singleQuote`, `trailingComma`, `bracketSpacing` and `jsxBracketSameLine` from `prettier` config if defined', t => {
Expand Down Expand Up @@ -344,7 +343,7 @@ test('mergeWithPrettierConfig: throw error is `space`/`tabWidth` conflicts', t =
test('buildConfig: rules', t => {
const rules = {'object-curly-spacing': ['error', 'always']};
const config = manager.buildConfig({rules, nodeVersion: '12'});
t.deepEqual(config.rules, rules);
t.deepEqual(config.rules['object-curly-spacing'], rules['object-curly-spacing']);
});

test('buildConfig: parser', t => {
Expand Down

0 comments on commit 2297c07

Please sign in to comment.