Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
**/test/**/output
packages/commonjs/test/fixtures
packages/typescript/test/fixtures/syntax-error
packages/eslint/test/fixtures/flat-config

# temporary workaround for eslint bug where package.json is a directory
packages/node-resolve/test/fixtures/package-json-in-path
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint/.eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
test/fixtures/ignored.js
test/fixtures/legacy-config/ignored.js
4 changes: 2 additions & 2 deletions packages/eslint/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@
},
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"eslint": "^8.24.0"
"eslint": "^8.57.1"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.0.0",
"@rollup/plugin-typescript": "^9.0.1",
"@types/eslint": "^8.4.6",
"@types/eslint": "^8.56.12",
"rollup": "^4.0.0-24",
"typescript": "^4.8.3"
},
Expand Down
14 changes: 12 additions & 2 deletions packages/eslint/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ import { relative, resolve, sep } from 'path';

import type { Plugin } from 'rollup';
import { createFilter } from '@rollup/pluginutils';
import { ESLint } from 'eslint';
import { ESLint, loadESLint } from 'eslint';

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

// New API introduced in v8.57 missing from @types/eslint
declare module 'eslint' {
function loadESLint(): Promise<typeof ESLint>;
}

function normalizePath(id: string) {
return relative(process.cwd(), id).split(sep).join('/');
}
Expand All @@ -29,12 +34,17 @@ export default function eslint(options = {} as RollupEslintOptions): Plugin {
...eslintOptions
} = options;

const eslintInstance = new ESLint(eslintOptions);
let eslintInstance: ESLint | null = null;
const filter = createFilter(include, exclude);

return {
name: 'eslint',
async transform(_, id: string) {
if (!eslintInstance) {
const DefaultESLint = await loadESLint();
eslintInstance = new DefaultESLint(eslintOptions);
}

const file = normalizePath(id);
if (!filter(id) || (await eslintInstance.isPathIgnored(file))) {
return null;
Expand Down
34 changes: 34 additions & 0 deletions packages/eslint/test/fixtures/flat-config/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export default [
{
files: ["**/*.js"],
rules: {
"no-alert": 2,
"no-bitwise": 1,
"camelcase": 1,
"curly": 1,
"eqeqeq": 0,
"no-eq-null": 0,
"guard-for-in": 1,
"no-empty": 1,
"no-use-before-define": 0,
"object-curly-spacing": 0,
"no-obj-calls": 2,
"no-unused-vars": 0,
"new-cap": 1,
"no-shadow": 0,
"strict": 2,
"global-strict": 0,
"no-invalid-regexp": 2,
"comma-dangle": 2,
"no-undef": 1,
"no-new": 1,
"no-extra-semi": 1,
"no-debugger": 2,
"no-caller": 1,
"semi": 1,
"quotes": 0,
"no-unreachable": 2,
"eol-last": 0,
},
},
];
1 change: 1 addition & 0 deletions packages/eslint/test/fixtures/flat-config/undeclared.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = 0;
57 changes: 38 additions & 19 deletions packages/eslint/test/test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import eslint from 'current-package';
test('should lint files', async (t) => {
let count = 0;
await rollup({
input: './test/fixtures/undeclared.js',
input: './test/fixtures/legacy-config/undeclared.js',
plugins: [
eslint({
formatter: (results) => {
Expand All @@ -29,7 +29,7 @@ test('should lint files', async (t) => {

test('should not fail with default options', async (t) => {
await rollup({
input: './test/fixtures/undeclared.js',
input: './test/fixtures/legacy-config/undeclared.js',
plugins: [eslint()]
});

Expand All @@ -39,11 +39,11 @@ test('should not fail with default options', async (t) => {
test('should ignore node_modules with exclude option', async (t) => {
let count = 0;
await rollup({
input: './test/fixtures/modules.js',
input: './test/fixtures/legacy-config/modules.js',
plugins: [
nodeResolve({ jsnext: true }),
eslint({
overrideConfigFile: './test/fixtures/.eslintrc-babel',
overrideConfigFile: './test/fixtures/legacy-config/.eslintrc-babel',
formatter: () => {
count += 1;
}
Expand All @@ -57,7 +57,7 @@ test('should ignore node_modules with exclude option', async (t) => {
test('should ignore files according .eslintignore', async (t) => {
let count = 0;
await rollup({
input: './test/fixtures/ignored.js',
input: './test/fixtures/legacy-config/ignored.js',
plugins: [
eslint({
formatter: () => {
Expand All @@ -74,7 +74,7 @@ test('should fail with enabled throwOnWarning and throwOnError options', async (
await t.throwsAsync(
async () => {
await rollup({
input: './test/fixtures/use-strict.js',
input: './test/fixtures/legacy-config/use-strict.js',
plugins: [
eslint({
throwOnWarning: true,
Expand All @@ -92,7 +92,7 @@ test('should fail with enabled throwOnError option', async (t) => {
await t.throwsAsync(
async () => {
await rollup({
input: './test/fixtures/use-strict.js',
input: './test/fixtures/legacy-config/use-strict.js',
plugins: [
eslint({
throwOnError: true,
Expand All @@ -109,7 +109,7 @@ test('should fail with enabled throwOnWarning option', async (t) => {
await t.throwsAsync(
async () => {
await rollup({
input: './test/fixtures/use-strict.js',
input: './test/fixtures/legacy-config/use-strict.js',
plugins: [
eslint({
throwOnWarning: true,
Expand All @@ -124,7 +124,7 @@ test('should fail with enabled throwOnWarning option', async (t) => {

test('should not fail with throwOnError and throwOnWarning disabled', async (t) => {
await rollup({
input: './test/fixtures/use-strict.js',
input: './test/fixtures/legacy-config/use-strict.js',
plugins: [
eslint({
throwOnError: false,
Expand All @@ -141,7 +141,7 @@ test('should fail with not found formatter', async (t) => {
await t.throwsAsync(
async () => {
await rollup({
input: './test/fixtures/use-strict.js',
input: './test/fixtures/legacy-config/use-strict.js',
plugins: [
eslint({
formatter: 'not-found-formatter'
Expand All @@ -155,7 +155,7 @@ test('should fail with not found formatter', async (t) => {

test('should not fail with found formatter', async (t) => {
rollup({
input: './test/fixtures/use-strict.js',
input: './test/fixtures/legacy-config/use-strict.js',
plugins: [
eslint({
formatter: 'stylish'
Expand All @@ -168,7 +168,7 @@ test('should not fail with found formatter', async (t) => {

test('should not fail with asynchronous formatter function', async (t) => {
await rollup({
input: './test/fixtures/use-strict.js',
input: './test/fixtures/legacy-config/use-strict.js',
plugins: [
eslint({
formatter: async () => 'json'
Expand All @@ -181,12 +181,12 @@ test('should not fail with asynchronous formatter function', async (t) => {

test('should fix source code', async (t) => {
fs.writeFileSync(
'./test/fixtures/fixable-clone.js',
fs.readFileSync('./test/fixtures/fixable.js')
'./test/fixtures/legacy-config/fixable-clone.js',
fs.readFileSync('./test/fixtures/legacy-config/fixable.js')
);

await rollup({
input: './test/fixtures/fixable-clone.js',
input: './test/fixtures/legacy-config/fixable-clone.js',
plugins: [
eslint({
fix: true
Expand All @@ -195,19 +195,19 @@ test('should fix source code', async (t) => {
});

t.is(
fs.readFileSync('./test/fixtures/fixable-clone.js').toString(),
fs.readFileSync('./test/fixtures/fixed.js').toString()
fs.readFileSync('./test/fixtures/legacy-config/fixable-clone.js').toString(),
fs.readFileSync('./test/fixtures/legacy-config/fixed.js').toString()
);

fs.unlinkSync('./test/fixtures/fixable-clone.js');
fs.unlinkSync('./test/fixtures/legacy-config/fixable-clone.js');
});

test('works with cjs plugin', async (t) => {
const require = createRequire(import.meta.url);
const eslintPluginCjs = require('current-package');
let count = 0;
await rollup({
input: './test/fixtures/undeclared.js',
input: './test/fixtures/legacy-config/undeclared.js',
plugins: [
eslintPluginCjs({
formatter: (results) => {
Expand All @@ -222,3 +222,22 @@ test('works with cjs plugin', async (t) => {

t.is(count, 1);
});

test('works with flat config', async (t) => {
let count = 0;
await rollup({
input: './test/fixtures/flat-config/undeclared.js',
plugins: [
eslint({
formatter: (results) => {
count += results[0].messages.length;
// eslint-disable-next-line prefer-destructuring
const { message } = results[0].messages[0];
t.is(message, "'x' is not defined.");
}
})
]
});

t.is(count, 1);
});
Loading