diff --git a/.fatherrc.ts b/.fatherrc.ts index f0c53dc..eb6439b 100644 --- a/.fatherrc.ts +++ b/.fatherrc.ts @@ -1,8 +1,7 @@ import { defineConfig } from 'father'; +import path from 'path'; export default defineConfig({ cjs: { output: 'dist' }, - targets: { - chrome: 85, - }, + plugins: [path.resolve(__dirname, 'src')], }); diff --git a/package.json b/package.json index 6805962..a40dafb 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "dist" ], "scripts": { - "build": "father build", + "build": "cross-env CHECK_TS_ONLY=1 father build", "dev": "father dev", "lint:es": "eslint \"{src,test}/**/*.{js,jsx,ts,tsx}\"", "prepare": "husky install", @@ -35,13 +35,19 @@ ] }, "dependencies": { + "@typescript-eslint/eslint-plugin": "^8.28.0", + "@typescript-eslint/parser": "^8.28.0", + "chalk": "^4.1.2", + "eslint": "^8.23.0", "fs-extra": "^11.3.0" }, "devDependencies": { "@commitlint/cli": "^17.1.2", "@commitlint/config-conventional": "^17.1.0", + "@types/eslint": "^8.56.12", + "@types/fs-extra": "^11.0.4", "@umijs/lint": "^4", - "eslint": "^8.23.0", + "cross-env": "^7.0.3", "father": "^4.1.0", "husky": "^8.0.1", "lint-staged": "^13.0.3", diff --git a/src/index.ts b/src/index.ts index cf79c02..1f0efc5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ -import { execSync } from 'child_process'; +import chalk from 'chalk'; +import { ESLint } from 'eslint'; import type { IApi } from 'father'; import fs from 'fs-extra'; import path from 'path'; @@ -20,6 +21,8 @@ export default (api: IApi) => { return; } + console.log('Check Typescript exports...'); + // Break if current project not install `@rc-component/np` const packageJson = await fs.readJson(path.join(cwd, 'package.json')); @@ -34,41 +37,95 @@ export default (api: IApi) => { const inputFolder = api?.config?.esm?.input || api?.config?.esm?.input || 'src/'; - const isEslintInstalled = checkNpmPackageDependency(packageJson, 'eslint'); - if (isEslintInstalled) { - execSync( - // Requires compatibility with Windows environment - `npx eslint ${inputFolder} --ext .tsx,.ts --rule "@typescript-eslint/consistent-type-exports: error"`, - { - cwd, - env: process.env, - stdio: [process.stdin, process.stdout, process.stderr], - encoding: 'utf-8', + const eslint = new ESLint({ + useEslintrc: false, + overrideConfig: { + rules: { + '@typescript-eslint/consistent-type-exports': ['error'], + }, + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 2021, + sourceType: 'module', + project: './tsconfig.json', }, - ); - } else { - console.log('ESLint is not installed, skip.'); + plugins: ['@typescript-eslint'], + }, + extensions: ['tsx', 'ts'], + }); + + const results = await eslint.lintFiles([inputFolder]); + + // Collect eslint errors + interface ErrorInfo { + line: number; + text: string; + error: string; + } + const errorMessages: { + filePath: string; + errors: ErrorInfo[]; + }[] = []; + + results.forEach((result) => { + const fullText = result.source || ''; + const textLines = fullText.split('\n'); + + const errorInfos: ErrorInfo[] = []; + + result.messages.forEach((message) => { + errorInfos.push({ + line: message.line, + text: textLines[message.line - 1], + error: message.message, + }); + }); + + if (errorInfos.length) { + errorMessages.push({ + filePath: result.filePath, + errors: errorInfos, + }); + } + }); + + if (errorMessages.length) { + console.log(''); + console.log(chalk.red('Eslint errors:')); + + errorMessages.forEach((error) => { + console.log(chalk.yellow(`${error.filePath}`)); + error.errors.forEach((item) => { + console.log(`${item.line}: ${item.text.trim()}`); + console.log(chalk.gray(`${item.error}`)); + }); + console.log(''); + }); + + process.exit(1); } }); // modify default build config for all rc projects - api.modifyDefaultConfig((memo) => { - Object.assign(memo, { - esm: { - output: 'es', - // transform all rc-xx/lib to rc-xx/es for esm build - extraBabelPlugins: [require.resolve('./babelPluginImportLib2Es')], - }, - cjs: { - // specific platform to browser, father 4 build cjs for node by default - platform: 'browser', - output: 'lib', - }, - targets: { - chrome: 85, - }, - } as typeof memo); + if (!process.env.CHECK_TS_ONLY) { + api.modifyDefaultConfig((memo) => { + Object.assign(memo, { + esm: { + output: 'es', + // transform all rc-xx/lib to rc-xx/es for esm build + extraBabelPlugins: [require.resolve('./babelPluginImportLib2Es')], + }, + cjs: { + // specific platform to browser, father 4 build cjs for node by default + platform: 'browser', + output: 'lib', + }, + targets: { + chrome: 85, + }, + } as typeof memo); - return memo; - }); + return memo; + }); + } };