Upgrade to ESLint 9

This commit is contained in:
Alex
2024-10-16 00:29:26 -04:00
parent 0138cabb27
commit 00d0dfa107
53 changed files with 3813 additions and 2207 deletions

View File

@ -1,31 +0,0 @@
#!/usr/bin/env tsx
import { promises as fs } from 'node:fs';
import { camelCase } from 'lodash';
export async function buildLocalRules() {
const files = (await fs.readdir('./src/custom'))
.filter(file => file.endsWith('.ts'))
.filter(file => file !== 'index.ts')
.map(file => file.slice(0, -3));
const entryFile = /* js */ `
import type { ESLintUtils } from '@typescript-eslint/utils';
import type { Rule } from 'eslint';
${files.map(file => `import ${camelCase(file)} from './${file}';`).join('\n')}
export const rules: Record<
string,
Rule.RuleModule | ESLintUtils.RuleModule<string, unknown[]>
> = {
${files.map(file => `'${file}': ${camelCase(file)},`).join('\n ')}
};
`.trim();
await fs.writeFile('./src/custom/index.ts', entryFile + '\n');
}
if (require.main === module) {
void buildLocalRules();
}

View File

@ -5,19 +5,20 @@ import { relative, resolve } from 'node:path';
import esbuild from 'esbuild';
import type { Plugin } from 'esbuild';
import { memoize } from 'lodash';
import { gray, green } from 'picocolors';
import { memoize } from 'lodash-es';
import c from 'picocolors';
import { minify_sync } from 'terser';
import { dependencies } from '../dist/package.json';
import { buildLocalRules } from './build-local-rules';
import { dts } from './dts';
import { babelPlugin } from './modifier';
const ENV = (process.env.NODE_ENV ??= 'production');
const PROD = ENV === 'production';
const { gray, green } = c;
declare global {
interface Array<T> {
filter(
@ -71,10 +72,7 @@ if (process.env.DEBUG) {
async function bundle(
entry: string,
outfile = entry
.replace('./packages/', './dist/')
.replace('src/', '')
.replace('.ts', '.js'),
outfile: string,
options?: esbuild.BuildOptions & { treeShaking?: boolean },
) {
const output = await esbuild.build({
@ -140,25 +138,31 @@ async function editPackageJson() {
}
async function useText(path: string) {
const state = await fs.readFile(path, 'utf-8');
const state = await fs.readFile(path, 'utf8');
const setState = (text: string) => fs.writeFile(path, text);
return [state, setState] as const;
}
function bundleType(source: string, output: string) {
return dts({
source,
dist: output,
project: './tsconfig.build.json',
});
try {
return dts({
source,
dist: output,
project: './tsconfig.build.json',
});
} catch {
// noop
}
}
async function main() {
console.log('Building local rules…');
await buildLocalRules();
console.log('Building type definitions…');
bundleType('./src/index.ts', './dist/index.d.ts');
try {
await fs.rm('dist/config', { recursive: true });
} catch {
// noop
}
bundleType('./src/prettier.ts', './dist/prettier.d.ts');
bundleType('./src/types.ts', './dist/types.d.ts');
@ -166,13 +170,12 @@ async function main() {
console.log('Building packages…');
await Promise.all([
bundle('./packages/eslint-plugin-jsx-a11y/src/index.js'),
bundle('./packages/eslint-plugin-react-hooks/index.ts'),
bundle('./packages/eslint-plugin-n/lib/index.js', './dist/eslint-plugin-n/index.js'),
bundle('./packages/eslint-import-resolver-typescript/src/index.ts'),
bundle('./src/custom/index.ts', './dist/eslint-plugin-custom/index.js'),
bundle('./src/local/index.ts', './dist/eslint-plugin-local/index.js'),
bundle('./src/index.ts', './dist/index.js', unminify),
bundle('./src/index.ts', undefined!, {
format: 'esm',
splitting: true,
outdir: './dist/config',
...unminify,
}),
bundle('./src/types.ts', './dist/types.js', unminify),
bundle('./src/prettier.ts', './dist/prettier.js', unminify),
bundle('./src/install.ts', './dist/install.js', {
@ -185,9 +188,8 @@ async function main() {
editPackageJson(),
]);
console.log('Removing redirect…');
const [distIndex, setDistIndex] = await useText('./dist/index.js');
await setDistIndex(distIndex.replace(/import.*redirect.*;/g, ''));
// bundleType('./src/index.ts', './dist/config/index.d.ts');
await fs.copyFile('./src/config.d.ts', './dist/config/index.d.ts');
}
void main();

View File

@ -3,8 +3,7 @@ import fs from 'node:fs';
import { builtinModules } from 'node:module';
import glob from 'fast-glob';
import { uniq } from 'lodash';
import { uniq } from 'lodash-es';
import { dependencies, peerDependencies } from '../dist/package.json';

View File

@ -1,9 +1,9 @@
#!/usr/bin/env node
import * as ts from 'typescript';
import {
type EntryPointConfig,
generateDtsBundle,
} from 'dts-bundle-generator/dist/bundle-generator';
import * as ts from 'typescript';
export function dts({
source,

View File

@ -1,11 +1,14 @@
#!/usr/bin/env tsx
import assert from 'node:assert';
import { readFileSync } from 'node:fs';
import { resolve, extname } from 'node:path';
import type { Loader, Plugin } from 'esbuild';
import { extname, resolve } from 'node:path';
import * as babel from '@babel/core';
import type { types as t, types } from '@babel/core';
import { createMacro, type MacroHandler } from 'babel-plugin-macros';
import babelMacros, { type MacroHandler } from 'babel-plugin-macros';
import type { Loader, Plugin } from 'esbuild';
import PropTypes from 'prop-types';
import * as polyfill from '../src/polyfill';
const polyfills = Object.keys(polyfill);
@ -15,7 +18,7 @@ class HandlerMap {
set(names: string | string[], handler: MacroHandler) {
names = Array.isArray(names) ? names : [names];
const macro = createMacro(handler);
const macro = babelMacros.createMacro(handler);
for (const name of names) {
this.map.set(name, macro);
}
@ -23,7 +26,7 @@ class HandlerMap {
}
get keys() {
return Array.from(this.map.keys());
return [...this.map.keys()];
}
resolvePath = (module: string) => module;
@ -96,14 +99,14 @@ const map = new HandlerMap()
'object.groupby',
replace(t =>
t.memberExpression(
t.callExpression(t.identifier('require'), [t.stringLiteral('lodash')]),
t.callExpression(t.identifier('require'), [t.stringLiteral('lodash-es')]),
t.identifier('groupBy'),
),
),
);
// es-iterator-helpers/Iterator.prototype.*
const polyfillPath = resolve(__dirname, '../src/polyfill.ts');
const polyfillPath = resolve(import.meta.dirname, '../src/polyfill.ts');
const requirePolyfill = (t: typeof types, name: string) =>
t.memberExpression(
t.callExpression(t.identifier('require'), [t.stringLiteral(polyfillPath)]),
@ -127,15 +130,15 @@ map.set(
function replace(getReplacement: (types: typeof t) => t.Expression): MacroHandler {
return ({ references, babel: { types: t } }) => {
references.default.forEach(referencePath => {
for (const referencePath of references.default) {
referencePath.replaceWith(getReplacement(t));
});
}
};
}
function proto(getProperty: (types: typeof t) => t.Expression): MacroHandler {
return ({ references, babel: { types: t } }) => {
references.default.forEach(referencePath => {
for (const referencePath of references.default) {
const { parent, parentPath } = referencePath;
assert(t.isCallExpression(parent));
const [callee, ...rest] = parent.arguments;
@ -145,7 +148,7 @@ function proto(getProperty: (types: typeof t) => t.Expression): MacroHandler {
rest,
),
);
});
}
};
}
@ -160,21 +163,14 @@ export const babelPlugin: Plugin = {
return null;
}
let source = readFileSync(path, 'utf-8')
const source = readFileSync(path, 'utf8')
.replaceAll("require('object.hasown/polyfill')()", 'Object.hasOwn')
.replaceAll("require('object.fromentries/polyfill')()", 'Object.fromEntries')
.replaceAll(
"Object.keys(require('prop-types'))",
JSON.stringify(Object.keys(require('prop-types'))),
JSON.stringify(Object.keys(PropTypes)),
);
if (
path.includes('packages/eslint-plugin-import/src/rules/') ||
path.includes('packages/eslint-plugin-import/config/')
) {
source = source.replace('\nmodule.exports = {', '\nexport default {');
}
const isFlow = source.includes('@flow');
const loader = extname(path).slice(1) as Loader;

View File

@ -3,7 +3,6 @@ sync() (
cd "packages/$1" && git diff HEAD > "../../patch/$1.patch"
)
sync eslint-import-resolver-typescript
sync eslint-plugin-jsx-a11y
sync eslint-plugin-n
sync jsx-ast-utils