Skip to content

Commit

Permalink
fix(eslint): Prepare eslint for rollup 3 and upgrade eslint to newest…
Browse files Browse the repository at this point in the history
… version (#1309)

Prior to these changes, the eslint plugin was using an older
version of eslint that relied on a class called CLIEngine.
In newer versions this has now been deprecated and so upgrading
versions required also updating to using ESLint internally
instead. Ultimately this doesn't change the usage of the plugin
but some of the option names have changed for ESLint (notably
configFile needs to change to overrideConfigFile).

The main driving factor for this change is to prevent conflicts
that happen when using @rollup/plugin-typescript and this plugin
together. Without this update, eslint would run on the transpiled
code and so the error messages weren't as helpful. This update
will allow the two plugins to work well together and provide
helpful information about errors and warnings.

This change also includes some necessary package updates to prepare
eslint for Rollup 3.

BREAKING CHANGES:
- options structure has changed due to moving from CLIEngine t
  ESlint. Review the new supported options below:
https://eslint.org/docs/latest/developer-guide/nodejs-api#-new-eslintoptions
- requires Node 14
  • Loading branch information
colingm authored and lukastaegert committed Oct 7, 2022
1 parent 69146cd commit daf3d4d
Show file tree
Hide file tree
Showing 10 changed files with 2,200 additions and 1,990 deletions.
54 changes: 29 additions & 25 deletions packages/eslint/README.md
@@ -1,7 +1,7 @@
[npm]: https://img.shields.io/npm/v/@rollup/plugin-alias
[npm-url]: https://www.npmjs.com/package/@rollup/plugin-alias
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-alias
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-alias
[npm]: https://img.shields.io/npm/v/@rollup/plugin-eslint
[npm-url]: https://www.npmjs.com/package/@rollup/plugin-eslint
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-eslint
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-eslint

[![npm][npm]][npm-url]
[![size][size]][size-url]
Expand All @@ -11,6 +11,10 @@

🍣 A Rollup plugin to lint entry points and all imported files with ESLint.

## Requirements

This plugin requires an [LTS](https://github.com/nodejs/Release) Node version (v14.0.0+) and Rollup v1.20.0+.

## Install

Using npm:
Expand Down Expand Up @@ -38,51 +42,51 @@ export default {

## Options

See more options here [eslint-config](http://eslint.org/docs/developer-guide/nodejs-api#cliengine).
This plugin takes a configuration object intended for the [ESLint constructor](https://eslint.org/docs/developer-guide/nodejs-api#-new-eslintoptions) with the addition of a `throwOnWarning`, `throwOnError`, `formatter`, `include` and `exclude` prop.

You can also use eslint configuration in the form of a `.eslintrc.*` file in your project's root. It will be loaded automatically.

### fix
### exclude

Type: `Boolean`<br>
Default: `false`
Type: `String | String[]`<br>
Default: `node_modules/**`

If true, will auto fix source code.
A single [`picomatch`](https://github.com/micromatch/picomatch) pattern or an array of patterns controlling which files this plugin should explicitly include. Gets forwarded to the [`createFilter`](https://github.com/rollup/plugins/tree/master/packages/pluginutils#createfilter) method of `@rollup/pluginutils`.

### throwOnError
### fix

Type: `Boolean`<br>
Default: `false`

If true, will throw an error if any errors were found.
If true, will auto fix source code.

### throwOnWarning
### formatter

Type: `Boolean`<br>
Default: `false`
Type: `Function | String`<br>
Default: `stylish`

If true, will throw an error if any warnings were found.
Custom error formatter, the name of a built-in formatter, or the path to a custom formatter.

### include

Type: `Array | String`<br>
Type: `String | String[]`<br>
Default: `[]`

A single file, or array of files, to include when linting.
A single [`picomatch`](https://github.com/micromatch/picomatch) pattern or an array of patterns controlling which files this plugin should explicitly include. Gets forwarded to the [`createFilter`](https://github.com/rollup/plugins/tree/master/packages/pluginutils#createfilter) method of `@rollup/pluginutils`.

### exclude
### throwOnError

Type: `Array | String`<br>
Default: `node_modules/**`
Type: `Boolean`<br>
Default: `false`

A single file, or array of files, to exclude when linting.
If true, will throw an error and exit the process when ESLint reports any errors.

### formatter
### throwOnWarning

Type: `Function | String`<br>
Default: `stylish`
Type: `Boolean`<br>
Default: `false`

Custom error formatter or the name of a built-in formatter.
If true, will throw an error and exit the process when ESLint reports any warnings.

## Meta

Expand Down
46 changes: 24 additions & 22 deletions packages/eslint/package.json
@@ -1,6 +1,6 @@
{
"name": "@rollup/plugin-eslint",
"version": "8.0.2",
"version": "8.0.4",
"publishConfig": {
"access": "public"
},
Expand All @@ -13,10 +13,15 @@
"author": "Bogdan Chadkin <trysound@yandex.ru>",
"homepage": "https://github.com/rollup/plugins/tree/master/packages/eslint#readme",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "dist/index.js",
"module": "dist/index.es.js",
"main": "./dist/cjs/index.js",
"module": "./dist/es/index.js",
"exports": {
"import": "./dist/es/index.js",
"types": "./types/index.d.ts",
"default": "./dist/cjs/index.js"
},
"engines": {
"node": ">= 10.0.0"
"node": ">=14.0.0"
},
"scripts": {
"build": "rollup -c",
Expand All @@ -34,6 +39,7 @@
},
"files": [
"dist",
"!dist/**/*.map",
"types",
"README.md",
"LICENSE"
Expand All @@ -48,30 +54,26 @@
"lint"
],
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0"
"rollup": "^1.20.0||^2.0.0||^3.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
},
"dependencies": {
"@rollup/pluginutils": "^4.0.0",
"eslint": "^7.12.0"
"@rollup/pluginutils": "^4.2.1",
"eslint": "^8.24.0"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-typescript": "^6.0.0",
"@types/eslint": "^7.2.2",
"rollup": "^2.67.3",
"typescript": "^4.1.2"
"@rollup/plugin-node-resolve": "^14.1.0",
"@rollup/plugin-typescript": "^8.5.0",
"@types/eslint": "^8.4.6",
"rollup": "^3.0.0-7",
"typescript": "^4.8.3"
},
"types": "types/index.d.ts",
"types": "./types/index.d.ts",
"ava": {
"babel": {
"compileEnhancements": false
},
"extensions": [
"ts"
],
"require": [
"ts-node/register"
],
"files": [
"!**/fixtures/**",
"!**/helpers/**",
Expand Down
13 changes: 0 additions & 13 deletions packages/eslint/rollup.config.js

This file was deleted.

7 changes: 7 additions & 0 deletions packages/eslint/rollup.config.mjs
@@ -0,0 +1,7 @@
import { readFileSync } from 'fs';

import { createConfig } from '../../shared/rollup.config.mjs';

export default createConfig({
pkg: JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8'))
});
78 changes: 40 additions & 38 deletions packages/eslint/src/index.ts
@@ -1,81 +1,83 @@
import * as path from 'path';
import { relative, resolve, sep } from 'path';

import { Plugin } from 'rollup';
import { createFilter } from '@rollup/pluginutils';
import { CLIEngine } from 'eslint';
import { ESLint } from 'eslint';

import { RollupEslintOptions } from '../types';
import type { RollupEslintOptions } from '../types';

function normalizePath(id: string) {
return path.relative(process.cwd(), id).split(path.sep).join('/');
return relative(process.cwd(), id).split(sep).join('/');
}

export default function eslint(options = {} as RollupEslintOptions): Plugin {
if (typeof options === 'string') {
const configFile = path.resolve(process.cwd(), options);
const configFile = resolve(process.cwd(), options);
// eslint-disable-next-line global-require, import/no-dynamic-require, no-param-reassign
options = require(configFile);
// Tell eslint not to look for configuration files.
// eslint-disable-next-line no-param-reassign
options.useEslintrc = false;
}

const cli = new CLIEngine(options);
let formatter: CLIEngine.Formatter;

switch (typeof options.formatter) {
case 'string':
formatter = cli.getFormatter(options.formatter);
break;
case 'function':
({ formatter } = options);
break;
default:
formatter = cli.getFormatter('stylish');
}
const {
include,
exclude = /node_modules/,
throwOnWarning = false,
throwOnError = false,
formatter = 'stylish',
...eslintOptions
} = options;

const filter = createFilter(options.include, options.exclude || /node_modules/);
const eslintInstance = new ESLint(eslintOptions);
const filter = createFilter(include, exclude);

return {
name: 'eslint',

// eslint-disable-next-line consistent-return
transform(code, id) {
async transform(_, id: string) {
const file = normalizePath(id);
if (!filter(id) || cli.isPathIgnored(file)) {
if (!filter(id) || (await eslintInstance.isPathIgnored(file))) {
return null;
}

const report = cli.executeOnText(code, file);
const hasWarnings = options.throwOnWarning && report.warningCount !== 0;
const hasErrors = options.throwOnError && report.errorCount !== 0;
const results = await eslintInstance.lintFiles(file);
const [result] = results;

if (options.fix && report) {
CLIEngine.outputFixes(report);
if (eslintOptions.fix) {
await ESLint.outputFixes(results);
}

if (report.warningCount === 0 && report.errorCount === 0) {
if (result.warningCount === 0 && result.errorCount === 0) {
return null;
}

const result = formatter(report.results);
const eslintFormatter: ESLint.Formatter =
typeof formatter === 'string'
? await eslintInstance.loadFormatter(formatter)
: { format: formatter };
const output = eslintFormatter.format(results);

if (result) {
if (output) {
// eslint-disable-next-line no-console
console.log(result);
console.log(output);
}

if (hasWarnings && hasErrors) {
throw Error('Warnings or errors were found');
const errorMessages = [];
if (result.warningCount > 0 && throwOnWarning) {
errorMessages.push(`${result.warningCount} warning${result.warningCount > 1 ? 's' : ''}`);
}

if (hasWarnings) {
throw Error('Warnings were found');
if (result.errorCount > 0 && throwOnError) {
errorMessages.push(`${result.errorCount} error${result.errorCount > 1 ? 's' : ''}`);
}

if (hasErrors) {
throw Error('Errors were found');
if (errorMessages.length > 0) {
throw new Error(
`Found ${errorMessages.join(' and ')} in ${relative('.', result.filePath)}`
);
}

return null;
}
};
}
1 change: 1 addition & 0 deletions packages/eslint/test/node_modules/current-package

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit daf3d4d

Please sign in to comment.