Skip to content
This repository has been archived by the owner on Jan 25, 2024. It is now read-only.

Commit

Permalink
perf(projects): use interopDefault and use jiti to resolve .ts config
Browse files Browse the repository at this point in the history
  • Loading branch information
honghuangdc committed Dec 10, 2023
1 parent 2f25ab9 commit 0f90e23
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 65 deletions.
19 changes: 18 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
import { defineConfig } from '@soybeanjs/eslint-config';
import { fileURLToPath } from 'node:url';
import path from 'node:path';
import jiti from 'jiti';

/**
* TS runtime to resolve the eslint config file written in TypeScript.
*
* @param {string} filePath
*/
function createTsRuntime(filePath) {
const fileName = fileURLToPath(import.meta.url);
const runtime = jiti(fileName);

return runtime(path.resolve(path.dirname(fileName), filePath));
}

/** @type {{ defineConfig: typeof import('./src').defineConfig }} */
const { defineConfig } = createTsRuntime('./src/index.ts');

export default defineConfig(
{ vue: true, formatter: { markdown: true, yaml: true, toml: true } },
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@
"@eslint-types/typescript-eslint": "6.12.0",
"@eslint-types/unicorn": "49.0.0",
"@soybeanjs/cli": "1.0.0-beta.0",
"@soybeanjs/eslint-config": "link:",
"@toml-tools/parser": "1.0.0",
"@types/eslint": "8.44.8",
"@types/eslint-config-prettier": "6.11.3",
Expand Down
3 changes: 0 additions & 3 deletions pnpm-lock.yaml

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

10 changes: 6 additions & 4 deletions src/configs/formatter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import prettierPlugin from 'eslint-plugin-prettier';
import type { FlatESLintConfig } from 'eslint-define-config';
import {
GLOB_CSS,
Expand All @@ -22,7 +21,10 @@ export async function createFormatterConfig(
) {
const { html = true, css = true, json = true, markdown, yaml, toml } = options || {};

const plainParser = await interopDefault(import('eslint-parser-plain'));
const [pluginPrettier, parserPlain] = await Promise.all([
interopDefault(import('eslint-plugin-prettier')),
interopDefault(import('eslint-parser-plain'))
]);

function createPrettierFormatter(files: string[], parser: PrettierParser, plugins?: string[]) {
const rules: Partial<PrettierLanguageRules> = {
Expand All @@ -37,10 +39,10 @@ export async function createFormatterConfig(
const config: FlatESLintConfig = {
files,
languageOptions: {
parser: plainParser
parser: parserPlain
},
plugins: {
prettier: prettierPlugin
prettier: pluginPrettier
},
rules: {
'prettier/prettier': ['warn', rules]
Expand Down
1 change: 0 additions & 1 deletion src/configs/ignore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { FlatESLintConfig } from 'eslint-define-config';

import { GLOB_EXCLUDE } from '../constants/glob';

export function createIgnoreConfig(ignores: string[] = []) {
Expand Down
6 changes: 4 additions & 2 deletions src/configs/import.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import pluginImport from 'eslint-plugin-i';
import type { FlatESLintConfig } from 'eslint-define-config';
import { interopDefault } from '../shared';

export async function createImportConfig() {
const pluginImport = await interopDefault(import('eslint-plugin-i'));

export function createImportConfig() {
const configs: FlatESLintConfig[] = [
{
plugins: {
Expand Down
6 changes: 4 additions & 2 deletions src/configs/node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import pluginNode from 'eslint-plugin-n';
import type { FlatESLintConfig } from 'eslint-define-config';
import { interopDefault } from '../shared';

export async function createNodeConfig() {
const pluginNode = await interopDefault(import('eslint-plugin-n'));

export function createNodeConfig() {
const configs: FlatESLintConfig[] = [
{
plugins: {
Expand Down
8 changes: 5 additions & 3 deletions src/configs/prettier.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import prettierPlugin from 'eslint-plugin-prettier';
import prettierRules from 'eslint-config-prettier';
import type { FlatESLintConfig } from 'eslint-define-config';
import { GLOB_PRETTIER_LINT } from '../constants/glob';
import { interopDefault } from '../shared';
import type { PrettierLanguageRules } from '../types';

const { rules: eslintRules } = prettierRules;

export function createPrettierConfig(rules: Partial<PrettierLanguageRules>) {
export async function createPrettierConfig(rules: Partial<PrettierLanguageRules>) {
const pluginPrettier = await interopDefault(import('eslint-plugin-prettier'));

const { plugins = [] } = rules;

const pRules: Partial<PrettierLanguageRules> = {
Expand All @@ -18,7 +20,7 @@ export function createPrettierConfig(rules: Partial<PrettierLanguageRules>) {
{
files: GLOB_PRETTIER_LINT,
plugins: {
prettier: prettierPlugin
prettier: pluginPrettier
},
rules: {
...eslintRules,
Expand Down
93 changes: 53 additions & 40 deletions src/configs/typescript.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,69 @@
import tsPlugin from '@typescript-eslint/eslint-plugin';
import tsParser from '@typescript-eslint/parser';
import type { ESLint } from 'eslint';
import type { FlatESLintConfig, Rules } from 'eslint-define-config';
import { interopDefault } from '../shared';
import { GLOB_TS, GLOB_TSX } from '../constants/glob';

export const tsRules: Partial<Rules> = {
...tsPlugin.configs['eslint-recommended'].overrides![0].rules,
...tsPlugin.configs.strict.rules,
'@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports', disallowTypeAnnotations: false }],
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true
}
],
// Override JS
'no-redeclare': 'off',
'@typescript-eslint/no-redeclare': 'error',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
vars: 'all',
args: 'all',
ignoreRestSiblings: false,
varsIgnorePattern: '^_',
argsIgnorePattern: '^_'
}
],
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: false, variables: true }],
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error',
// off
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/unified-signatures': 'off'
};
export async function createTsRules() {
const pluginTs = await interopDefault(import('@typescript-eslint/eslint-plugin'));

const tsRules: Partial<Rules> = {
...pluginTs.configs['eslint-recommended'].overrides![0].rules,
...pluginTs.configs.strict.rules,
'@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports', disallowTypeAnnotations: false }],
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true
}
],
// Override JS
'no-redeclare': 'off',
'@typescript-eslint/no-redeclare': 'error',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
vars: 'all',
args: 'all',
ignoreRestSiblings: false,
varsIgnorePattern: '^_',
argsIgnorePattern: '^_'
}
],
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: false, variables: true }],
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error',
// off
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/unified-signatures': 'off'
};

return tsRules;
}

export async function createTsConfig() {
const [pluginTs, parserTs] = await Promise.all([
interopDefault(import('@typescript-eslint/eslint-plugin')),
interopDefault(import('@typescript-eslint/parser'))
]);

const tsRules = await createTsRules();

export function createTsConfig() {
const ts: FlatESLintConfig[] = [
{
files: [GLOB_TS, GLOB_TSX],
languageOptions: {
parser: tsParser,
parser: parserTs,
parserOptions: {
sourceType: 'module'
}
},
plugins: {
'@typescript-eslint': tsPlugin as any
'@typescript-eslint': pluginTs as unknown as ESLint.Plugin
},
rules: {
...tsRules
Expand Down
6 changes: 4 additions & 2 deletions src/configs/unicorn.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import pluginUnicorn from 'eslint-plugin-unicorn';
import type { FlatESLintConfig } from 'eslint-define-config';
import { interopDefault } from '../shared';

export async function createUnicornConfig() {
const pluginUnicorn = await interopDefault(import('eslint-plugin-unicorn'));

export function createUnicornConfig() {
const configs: FlatESLintConfig[] = [
{
plugins: {
Expand Down
4 changes: 3 additions & 1 deletion src/configs/vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { FlatESLintConfig } from 'eslint-define-config';
import { ensurePackages, interopDefault } from '../shared';
import { GLOB_VUE } from '../constants/glob';
import type { VueOption } from '../types';
import { tsRules } from './typescript';
import { createTsRules } from './typescript';

export async function createVueConfig(options: VueOption) {
await ensurePackages(['eslint-plugin-vue', 'vue-eslint-parser']);
Expand All @@ -15,6 +15,8 @@ export async function createVueConfig(options: VueOption) {
interopDefault(import('@typescript-eslint/eslint-plugin'))
]);

const tsRules = await createTsRules();

const configKeys: VueConfigKey[] =
options.version === 3
? ['vue3-essential', 'vue3-strongly-recommended', 'vue3-recommended']
Expand Down
10 changes: 5 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ export async function defineConfig(options: Partial<Option> = {}, ...userConfigs

const ignore = createIgnoreConfig(options.ignores);
const js = createJsConfig();
const node = createNodeConfig();
const imp = createImportConfig();
const unicorn = createUnicornConfig();
const ts = createTsConfig();
const node = await createNodeConfig();
const imp = await createImportConfig();
const unicorn = await createUnicornConfig();
const ts = await createTsConfig();
const vue = await getVueConfig(opts.vue);
const prettier = createPrettierConfig(opts.prettierRules);
const prettier = await createPrettierConfig(opts.prettierRules);
const formatter = await createFormatterConfig(opts.formatter, opts.prettierRules);
const userResolved = await Promise.all(userConfigs);

Expand Down

0 comments on commit 0f90e23

Please sign in to comment.