134 lines
4.2 KiB
JavaScript
134 lines
4.2 KiB
JavaScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import { lookupFiles } from './utils.js';
|
|
|
|
/**
|
|
* 文件查找工具类 - 支持多种后缀名尝试机制
|
|
*/
|
|
export class FileFinder {
|
|
/**
|
|
* 查找具有多种后缀名的文件
|
|
* @param {string} basePath - 基础路径(不包含后缀)
|
|
* @param {string[]} extensions - 后缀名数组,按优先级排序
|
|
* @param {string} startDir - 起始目录
|
|
* @returns {string|null} 找到的文件路径或 null
|
|
*/
|
|
static findWithExtensions(basePath, extensions = ['.tsx', '.ts', '.jsx', '.js'], startDir = process.cwd()) {
|
|
for (const ext of extensions) {
|
|
const fullPath = path.join(startDir, basePath + ext);
|
|
if (fs.existsSync(fullPath)) {
|
|
return basePath + ext;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 查找多个候选文件
|
|
* @param {string[]} candidates - 候选文件路径数组
|
|
* @param {string} startDir - 起始目录
|
|
* @returns {string[]} 找到的文件路径数组
|
|
*/
|
|
static findMultiple(candidates, startDir = process.cwd()) {
|
|
const foundFiles = [];
|
|
for (const candidate of candidates) {
|
|
if (candidate === '*.html') {
|
|
// 特殊处理:查找所有 HTML 文件
|
|
const htmlFiles = lookupFiles(startDir);
|
|
foundFiles.push(...htmlFiles);
|
|
} else if (fs.existsSync(path.join(startDir, candidate))) {
|
|
foundFiles.push(candidate);
|
|
}
|
|
}
|
|
return foundFiles;
|
|
}
|
|
|
|
/**
|
|
* 查找框架特定的入口文件
|
|
* @param {string} projectType - 项目类型
|
|
* @param {string} startDir - 起始目录
|
|
* @returns {string[]} 找到的文件路径数组
|
|
*/
|
|
static findFrameworkEntry(projectType, startDir = process.cwd()) {
|
|
const foundFiles = [];
|
|
|
|
switch (projectType) {
|
|
case 'vite':
|
|
// 尝试查找 vite.config 文件
|
|
const viteConfig = this.findWithExtensions('vite.config', ['.js', '.ts', '.mjs'], startDir);
|
|
if (viteConfig) {
|
|
foundFiles.push(viteConfig);
|
|
}
|
|
break;
|
|
|
|
case 'next-pages':
|
|
// 尝试查找 _document 文件
|
|
const documentFile = this.findWithExtensions('pages/_document', ['.tsx', '.jsx', '.ts', '.js'], startDir);
|
|
if (documentFile) {
|
|
foundFiles.push(documentFile);
|
|
}
|
|
|
|
// 尝试查找 _app 文件
|
|
const appFile = this.findWithExtensions('pages/_app', ['.tsx', '.jsx', '.ts', '.js'], startDir);
|
|
if (appFile) {
|
|
foundFiles.push(appFile);
|
|
}
|
|
break;
|
|
|
|
case 'next-app':
|
|
// 尝试查找 layout 文件
|
|
const layoutFile = this.findWithExtensions('app/layout', ['.tsx', '.jsx', '.ts', '.js'], startDir);
|
|
if (layoutFile) {
|
|
foundFiles.push(layoutFile);
|
|
}
|
|
|
|
// 尝试查找 globals.css
|
|
const globalsCss = 'app/globals.css';
|
|
if (fs.existsSync(path.join(startDir, globalsCss))) {
|
|
foundFiles.push(globalsCss);
|
|
}
|
|
break;
|
|
|
|
case 'next-hybrid':
|
|
// 尝试查找 app/layout 文件
|
|
const appLayoutFile = this.findWithExtensions('app/layout', ['.tsx', '.jsx', '.ts', '.js'], startDir);
|
|
if (appLayoutFile) {
|
|
foundFiles.push(appLayoutFile);
|
|
}
|
|
|
|
// 尝试查找 pages/_document 文件
|
|
const pagesDocumentFile = this.findWithExtensions('pages/_document', ['.tsx', '.jsx', '.ts', '.js'], startDir);
|
|
if (pagesDocumentFile) {
|
|
foundFiles.push(pagesDocumentFile);
|
|
}
|
|
break;
|
|
|
|
case 'create-react-app':
|
|
// 尝试查找 HTML 文件
|
|
const htmlFiles = ['public/index.html', 'index.html'];
|
|
foundFiles.push(...this.findMultiple(htmlFiles, startDir));
|
|
break;
|
|
|
|
case 'html-static':
|
|
// 尝试查找 HTML 文件
|
|
const staticHtmlFiles = ['index.html', '*.html'];
|
|
foundFiles.push(...this.findMultiple(staticHtmlFiles, startDir));
|
|
break;
|
|
|
|
default:
|
|
// 默认查找 HTML 文件
|
|
const defaultHtmlFiles = ['index.html', '*.html'];
|
|
foundFiles.push(...this.findMultiple(defaultHtmlFiles, startDir));
|
|
break;
|
|
}
|
|
|
|
return foundFiles;
|
|
}
|
|
}
|
|
|
|
// 导出便捷方法
|
|
export function findFrameworkEntry(projectType, startDir = process.cwd()) {
|
|
return FileFinder.findFrameworkEntry(projectType, startDir);
|
|
}
|
|
|