diff --git a/package.json b/package.json index 95c3b20..a57cd9a 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@types/adm-zip": "^0.5.5", "@types/figlet": "^1.5.8", "@types/inquirer": "^9.0.7", + "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.27", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", @@ -75,13 +76,17 @@ "@compass-aiden/helpers": "^0.2.0", "@compass-aiden/telegram": "^2.3.1", "@inquirer/prompts": "^4.3.0", + "acorn": "^8.11.3", + "acorn-walk": "^8.3.2", "adm-zip": "^0.5.12", + "astring": "^1.8.6", "axios": "^1.6.7", "chalk": "^5.3.0", "commander": "^12.0.0", "figlet": "^1.7.0", "handlebars": "^4.7.8", "inquirer": "^9.2.16", + "lodash-es": "^4.17.21", "ora": "^8.0.1", "yaml": "^2.4.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86ace31..fbfcb45 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,18 @@ dependencies: '@inquirer/prompts': specifier: ^4.3.0 version: 4.3.0 + acorn: + specifier: ^8.11.3 + version: 8.11.3 + acorn-walk: + specifier: ^8.3.2 + version: 8.3.2 adm-zip: specifier: ^0.5.12 version: 0.5.12 + astring: + specifier: ^1.8.6 + version: 1.8.6 axios: specifier: ^1.6.7 version: 1.6.7 @@ -35,6 +44,9 @@ dependencies: inquirer: specifier: ^9.2.16 version: 9.2.16 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 ora: specifier: ^8.0.1 version: 8.0.1 @@ -73,6 +85,9 @@ devDependencies: '@types/inquirer': specifier: ^9.0.7 version: 9.0.7 + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 '@types/node': specifier: ^20.11.27 version: 20.11.27 @@ -844,6 +859,16 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true + /@types/lodash-es@4.17.12: + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + dependencies: + '@types/lodash': 4.17.1 + dev: true + + /@types/lodash@4.17.1: + resolution: {integrity: sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==} + dev: true + /@types/mute-stream@0.0.4: resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} dependencies: @@ -1060,11 +1085,15 @@ packages: acorn: 8.11.3 dev: true + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + dev: false + /acorn@8.11.3: resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} hasBin: true - dev: true /adm-zip@0.5.12: resolution: {integrity: sha512-6TVU49mK6KZb4qG6xWaaM4C7sA/sgUMLy/JYMOzkcp3BvVLpW0fXDFQiIzAuxFCt/2+xD7fNIiPFAoLZPhVNLQ==} @@ -1215,6 +1244,11 @@ packages: is-shared-array-buffer: 1.0.3 dev: true + /astring@1.8.6: + resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} + hasBin: true + dev: false + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false diff --git a/src/main.ts b/src/main.ts index a2d2a50..27719d7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,7 +15,7 @@ export default () => { .usage(' [option]') .on('--help', () => { // eslint-disable-next-line no-console - console.log(`\r\n${figlet.textSync('Compass CLI')}`); + console.log(`\r\n${chalk.cyan(figlet.textSync('Compass CLI'))}`); // 新增说明信息 // eslint-disable-next-line no-console console.log(`\r\nRun ${chalk.cyan(`compass --help`)} show details\r\n`); diff --git a/src/utils/get-ast-tree-of-file.ts b/src/utils/get-ast-tree-of-file.ts new file mode 100644 index 0000000..78b612b --- /dev/null +++ b/src/utils/get-ast-tree-of-file.ts @@ -0,0 +1,38 @@ +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import * as acorn from 'acorn'; + +/** + * 获取文件的ast语法树 + * @param filePath 文件路径 + * @param options 配置项 + * @returns {acorn.Program} + */ +export default function getASTTreeOfFile( + filePath: string, + options?: { + cwd?: string; + } & Partial, +): acorn.Program { + const { cwd, encoding } = { + encoding: 'utf8' as const, + cwd: process.cwd(), + ...options, + }; + const target = typeof cwd !== 'undefined' ? resolve(cwd, filePath) : filePath; + const code = readFileSync(target, { encoding }); + const comments: acorn.Comment[] = []; + const tokens: acorn.Token[] = []; + const ast = acorn.parse(code, { + ecmaVersion: options?.ecmaVersion || 7, + onComment: comments, + onToken: tokens, + locations: true, + ...options, + }); + // @ts-expect-error -- expected + ast.comments = comments; + // @ts-expect-error -- expected + ast.tokens = tokens; + return ast; +} diff --git a/src/utils/index.ts b/src/utils/index.ts index 86de4a2..ba03d03 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -10,4 +10,5 @@ export { default as getLibraryVersionFromNpmRegisty } from './get-library-versio export { default as downloadRepoFromGithub } from './download-repo-from-github'; export { default as getFilePathsInFolder } from './get-file-paths-in-folder'; export { default as deleteFoldersSync } from './delete-folder-sync'; +export { default as getASTTreeOfFile } from './get-ast-tree-of-file'; export * from './delete-files-sync'; diff --git a/src/utils/plugins/eslint.plugin.ts b/src/utils/plugins/eslint.plugin.ts index 204ce2d..aef6c9c 100644 --- a/src/utils/plugins/eslint.plugin.ts +++ b/src/utils/plugins/eslint.plugin.ts @@ -56,6 +56,16 @@ export async function addEslintPlugin(options?: { pkgManager?: PkgManager; cwd?: eslintFileData.extends.push(answer); writeFileSync(eslintFilePath, JSON.stringify(eslintFileData, null, 2), 'utf-8'); } + + // Vite 相关配置 + let hasViteConfig = false; + if ( + isFileOrFolderExists(join(cwd || process.cwd(), 'vite.config.ts')) || + isFileOrFolderExists(join(cwd || process.cwd(), 'vite.config.js')) + ) { + hasViteConfig = true; + } + // 在package.json内写入lint命令 execSync(`npm pkg set scripts.lint="${pluginConfig.lint}"`, execOption); execSync( @@ -63,6 +73,23 @@ export async function addEslintPlugin(options?: { pkgManager?: PkgManager; cwd?: execOption, ); + if (hasViteConfig) { + Logger.info(`在Vite项目中推荐使用vite-plugin-checker插件,示例如下: + + import checker from 'vite-plugin-checker'; + + export default defineConfig({ + plugins: [ + // ......其他插件 + checker({ + eslint: { + lintCommand: 'eslint "./src/**/*.{ts,tsx,vue,js,jsx,cjs,mjs}" --fix', + }, + }), + ], + }); + `); + } Logger.success(`${isCreateFile ? 'Created' : 'Updated'} file at ${eslintFilePath}`); Logger.success( `Installed @compass-aiden/eslint-config eslint eslint-plugin-import ${pluginConfig.deps.join(' ')} at ${cwd || process.cwd()}`,