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
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ Install the meta package for all configs:
bun add -D @lobehub/lint
```

`@lobehub/lint`, `@lobehub/eslint-config`, and `create-lobe-lint` now require Node.js `>=22`. The other standalone config packages still support Node.js `>=18`.

Or install individual packages as needed:

```bash
Expand All @@ -113,6 +115,8 @@ The fastest way to set up LobeHub lint configs in your project is using the CLI
npx create-lobe-lint
```

If you generate ESLint-related configs, use Node.js `>=22`.

This will start an interactive setup that auto-detects your project configuration (package manager, TypeScript, React framework) and generates the appropriate config files.

```bash
Expand Down Expand Up @@ -223,7 +227,7 @@ export default semanticRelease;

- **ESM only** - CommonJS is no longer supported
- **ESLint 9** - Requires ESLint 9+ with Flat Config
- **Node.js 18** - Requires Node.js 18+
- **Node.js 22 for ESLint** - `@lobehub/eslint-config`, `@lobehub/lint`, and `create-lobe-lint` now require Node.js 22+

### Migration Steps

Expand Down
30 changes: 15 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,28 +45,28 @@
"*.{ts,tsx}": [
"prettier --parser=typescript --write",
"stylelint --fix",
"eslint --fix"
"eslint --fix --no-warn-ignored"
]
},
"devDependencies": {
"@commitlint/cli": "^19.6.1",
"@types/node": "^22.10.5",
"bumpp": "^10.4.1",
"commitlint": "^19.6.1",
"eslint": "^9.18.0",
"eslint-typegen": "^2.3.0",
"@commitlint/cli": "^20.5.0",
"@types/node": "^25.6.0",
"bumpp": "^11.0.1",
"commitlint": "^20.5.0",
"eslint": "^10.2.0",
"eslint-typegen": "^2.3.1",
"husky": "^9.1.7",
"lint-staged": "^15.3.0",
"prettier": "^3.4.2",
"lint-staged": "^16.4.0",
"prettier": "^3.8.3",
"remark-cli": "^12.0.1",
"stylelint": "^16.12.0",
"tsdown": "^0.9.2",
"typescript": "^5.7.3",
"vitest": "^3.0.4"
"stylelint": "^17.7.0",
"tsdown": "^0.21.8",
"typescript": "^6.0.2",
"vitest": "^4.1.4"
},
"packageManager": "pnpm@9.15.4",
"packageManager": "pnpm@10.33.0",
"engines": {
"node": ">=18"
"node": ">=22"
},
"pnpm": {
"patchedDependencies": {
Expand Down
8 changes: 4 additions & 4 deletions packages/commitlint-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"types": "./dist/index.d.mts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"module": "./dist/index.mjs",
"types": "./dist/index.d.mts",
"files": [
"dist"
],
Expand Down
4 changes: 3 additions & 1 deletion packages/create-lint/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

CLI tool to setup LobeHub lint configurations

[Changelog](./CHANGELOG.md) · [Report Bug][issues-link] · [Request Feature][issues-link]
[Changelog](./CHANGELOG.md) · \[Report Bug]\[issues-link] · \[Request Feature]\[issues-link]

</div>

Expand Down Expand Up @@ -46,6 +46,8 @@ Run the CLI with npx:
npx create-lobe-lint
```

If you generate ESLint-related configs, use Node.js `>=22`. The generated setup depends on `@lobehub/eslint-config`, which now requires Node.js `>=22`.

This will start an interactive setup process that:

1. Detects your project configuration
Expand Down
19 changes: 11 additions & 8 deletions packages/create-lint/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
"types": "./dist/index.d.mts",
"import": "./dist/index.mjs"
}
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"main": "./dist/index.mjs",
"types": "./dist/index.d.mts",
"bin": {
"create-lobe-lint": "./dist/index.js"
"create-lobe-lint": "./dist/index.mjs"
},
"files": [
"dist"
Expand All @@ -35,13 +35,16 @@
"type-check": "tsc --noEmit"
},
"dependencies": {
"@clack/prompts": "^0.8.0",
"@clack/prompts": "^1.2.0",
"mri": "^1.2.0",
"package-manager-detector": "^1.6.0",
"picocolors": "^1.1.0"
"picocolors": "^1.1.1"
},
"devDependencies": {
"@types/node": "^25.6.0"
},
"engines": {
"node": ">=18"
"node": ">=22"
},
"publishConfig": {
"access": "public",
Expand Down
18 changes: 15 additions & 3 deletions packages/create-lint/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ export async function run(options: CliOptions): Promise<void> {
process.exit(0);
}

if (selections.tools.includes('eslint')) {
p.note(
'Generated ESLint configs depend on @lobehub/eslint-config, which now requires Node.js >=22.',
'Node Requirement',
);
}

// Ask about ignore files generation
selections.configureIgnoreFiles = await askIgnoreFilesConfiguration(options, selections);

Expand Down Expand Up @@ -313,9 +320,11 @@ async function getManualSelections(
process.exit(0);
}

const tools = selectedTools as ConfigTool[];

let reactFramework = detectedFramework;

if (selectedTools.includes('eslint')) {
if (tools.includes('eslint')) {
if (options.react !== undefined) {
reactFramework = parseReactFramework(options.react);
} else if (!options.yes) {
Expand All @@ -333,7 +342,7 @@ async function getManualSelections(
excludeUnusedImportsAutofix: false,
installDeps: options.install ?? true,
reactFramework,
tools: selectedTools as ConfigTool[],
tools,
};
}

Expand Down Expand Up @@ -551,12 +560,15 @@ function getInstallCommandHint(pm: string, deps: string[]): string {
}

function printHelp(): void {
console.log(`
console.info(`
${pc.bold('create-lobe-lint')} - Setup LobeHub lint configurations

${pc.bold('Usage:')}
npx create-lobe-lint [options]

${pc.bold('Note:')}
ESLint and @lobehub/lint configs require Node.js >=22

${pc.bold('Options:')}
-p, --preset Quick setup with preset tools (ESLint, Prettier, Stylelint, Commitlint)
-m, --manual Manually select tools to configure
Expand Down
2 changes: 1 addition & 1 deletion packages/create-lint/tests/e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const packageRoot = path.resolve(__dirname, '..');
const distEntry = path.join(packageRoot, 'dist', 'index.js');
const distEntry = path.join(packageRoot, 'dist', 'index.mjs');

describe('create-lobe-lint E2E', () => {
let tmpDir: string;
Expand Down
3 changes: 2 additions & 1 deletion packages/create-lint/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"lib": ["ES2023"]
"lib": ["ES2023"],
"types": ["node"]
},
"extends": "../../tsconfig.base.json",
"include": ["src"]
Expand Down
2 changes: 1 addition & 1 deletion packages/create-lint/tsdown.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default defineConfig({
format: ['esm'],
dts: true,
clean: true,
target: 'node18',
target: 'node22',
sourcemap: false,
outputOptions: {
banner: '#!/usr/bin/env node',
Expand Down
4 changes: 3 additions & 1 deletion packages/eslint-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ ESLint Flat Config configuration for LobeHub projects
pnpm add -D @lobehub/eslint-config eslint typescript
```

Node.js `>=22` is required.

## Usage

Create `eslint.config.js` (or `eslint.config.mjs`) in your project root:
Expand Down Expand Up @@ -261,7 +263,7 @@ function defineConfig(options?: Options, ...configs: FlatConfig[]): FlatConfigAr

## Requirements

- Node.js >= 18
- Node.js >= 22
- ESLint >= 9.0.0
- TypeScript >= 5.0.0 (optional)

Expand Down
40 changes: 20 additions & 20 deletions packages/eslint-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"types": "./dist/index.d.mts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"module": "./dist/index.mjs",
"types": "./dist/index.d.mts",
"files": [
"dist"
],
Expand All @@ -36,33 +36,33 @@
"type-check": "tsc --noEmit"
},
"dependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "^4.6.0",
"@eslint-react/eslint-plugin": "^2.12.4",
"@eslint-community/eslint-plugin-eslint-comments": "^4.7.1",
"@eslint-react/eslint-plugin": "^4.2.3",
"@eslint/js": "^10.0.1",
"@next/eslint-plugin-next": "^16.1.6",
"@next/eslint-plugin-next": "^16.2.3",
"eslint-config-prettier": "^9.1.2",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-mdx": "^3.6.2",
"eslint-plugin-import-x": "^4.16.1",
"eslint-mdx": "^3.7.0",
"eslint-plugin-import-x": "^4.16.2",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-mdx": "^3.6.2",
"eslint-plugin-perfectionist": "^5.5.0",
"eslint-plugin-perfectionist": "^5.8.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-compiler": "^19.1.0-rc.2",
"eslint-plugin-react-hooks": "5.2.0",
"eslint-plugin-react-native": "^5.0.0",
"eslint-plugin-react-refresh": "^0.5.0",
"eslint-plugin-regexp": "^3.0.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-unicorn": "^63.0.0",
"eslint-plugin-react-refresh": "^0.5.2",
"eslint-plugin-regexp": "^3.1.0",
"eslint-plugin-simple-import-sort": "^13.0.0",
"eslint-plugin-unicorn": "^64.0.0",
"eslint-plugin-unused-imports": "^4.4.1",
"eslint-plugin-yml": "^3.1.2",
"globals": "^17.3.0",
"typescript-eslint": "^8.55.0"
"eslint-plugin-yml": "^3.3.1",
"globals": "^17.5.0",
"typescript-eslint": "^8.58.2"
},
"devDependencies": {
"eslint-typegen": "^2.3.0",
"glob": "^13.0.2"
"eslint-typegen": "^2.3.1",
"glob": "^13.0.6"
},
"peerDependencies": {
"eslint": "^10.0.0",
Expand All @@ -74,7 +74,7 @@
}
},
"engines": {
"node": ">=18"
"node": ">=22"
},
"publishConfig": {
"access": "public",
Expand Down
10 changes: 1 addition & 9 deletions packages/eslint-config/scripts/generate-eslint-typegen.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import tseslint from 'typescript-eslint';

const outFile = path.resolve('src/eslint-typegen.d.ts');

const eslintReactPlugins = eslintReact.configs['recommended-typescript']?.plugins ?? {};

const dts = await pluginsToRulesDTS({
// ESLint plugins used by this package
'@typescript-eslint': tseslint.plugin,
Expand All @@ -39,13 +37,7 @@ const dts = await pluginsToRulesDTS({
'jsx-a11y': jsxA11y,
'@next/next': nextPlugin,
'@eslint-community/eslint-comments': eslintComments,

// @eslint-react registers multiple plugin namespaces
'@eslint-react': eslintReactPlugins['@eslint-react'],
'@eslint-react/dom': eslintReactPlugins['@eslint-react/dom'],
'@eslint-react/web-api': eslintReactPlugins['@eslint-react/web-api'],
'@eslint-react/hooks-extra': eslintReactPlugins['@eslint-react/hooks-extra'],
'@eslint-react/naming-convention': eslintReactPlugins['@eslint-react/naming-convention'],
'@eslint-react': eslintReact,
});

const banner = `// This file is generated by scripts/generate-eslint-typegen.mjs\n// Do not edit manually.\n\n`;
Expand Down
6 changes: 1 addition & 5 deletions packages/eslint-config/src/configs/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import eslintReact from '@eslint-react/eslint-plugin';
import { defineConfig } from 'eslint/config';
import reactPlugin from 'eslint-plugin-react';
import reactCompiler from 'eslint-plugin-react-compiler';
import reactHooksPlugin from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';

import { GLOB_JSX, GLOB_TSX } from '../globs';
Expand All @@ -24,13 +23,10 @@ export function react(options: Options) {
files,
plugins: {
'react': reactPlugin,
'react-hooks': reactHooksPlugin,
'react-refresh': reactRefresh,
},
rules: {
...reactHooksPlugin.configs.recommended.rules,

'@eslint-react/dom/no-dangerously-set-innerhtml': 'off',
'@eslint-react/dom-no-dangerously-set-innerhtml': 'off',
'@eslint-react/no-array-index-key': 'warn',
'@eslint-react/no-leaked-conditional-rendering': 'off',

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @ts-nocheck

interface HtmlBlockProps {
html: string;
}

export function HtmlBlock({ html }: HtmlBlockProps) {
return <div dangerouslySetInnerHTML={{ __html: html }} />;
}
Loading
Loading