mm
This commit is contained in:
121
templates/vite-react-lib/scripts/gen-index-css.ts
Normal file
121
templates/vite-react-lib/scripts/gen-index-css.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { globSync } from "glob";
|
||||
|
||||
interface Config {
|
||||
targetDirs: string[];
|
||||
includeExtensions: string[];
|
||||
excludeKeywords: {
|
||||
dirs: string[];
|
||||
fileSuffixes: string[];
|
||||
filePatterns: RegExp[];
|
||||
};
|
||||
}
|
||||
|
||||
const CONFIG: Config = {
|
||||
targetDirs: ["src"],
|
||||
includeExtensions: [".ts", ".tsx", ".vue"],
|
||||
excludeKeywords: {
|
||||
dirs: ["__tests__", "tests", "story", "stories", "types"],
|
||||
fileSuffixes: [".d.ts"],
|
||||
filePatterns: [
|
||||
/^index\.(ts|tsx|js|jsx)$/,
|
||||
/\.(test|spec)\./,
|
||||
/\.(story|stories)\./,
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const normalizePath = (p: string) => p.replace(/\\/g, "/");
|
||||
|
||||
const isInExcludeDir = (filePath: string) => {
|
||||
const normalized = normalizePath(filePath);
|
||||
return CONFIG.excludeKeywords.dirs.some((dir) =>
|
||||
normalized.includes(`/${dir}/`),
|
||||
);
|
||||
};
|
||||
|
||||
const isExcludeSuffix = (filePath: string) =>
|
||||
CONFIG.excludeKeywords.fileSuffixes.some((suffix) =>
|
||||
filePath.endsWith(suffix),
|
||||
);
|
||||
|
||||
const isMatchExcludePattern = (fileName: string) =>
|
||||
CONFIG.excludeKeywords.filePatterns.some((pattern) => pattern.test(fileName));
|
||||
|
||||
function isValidFile(filePath: string): boolean {
|
||||
const fileName = filePath.split(/[\\/]/).pop()!;
|
||||
|
||||
if (isInExcludeDir(filePath)) return false;
|
||||
if (isExcludeSuffix(filePath)) return false;
|
||||
if (isMatchExcludePattern(fileName)) return false;
|
||||
|
||||
const ext = path.extname(filePath);
|
||||
return CONFIG.includeExtensions.includes(ext);
|
||||
}
|
||||
|
||||
function generateIndexFile(dirPath: string) {
|
||||
const searchPattern = path.resolve(dirPath, "**", "*.*");
|
||||
|
||||
const allFiles = globSync(searchPattern, {
|
||||
nodir: true,
|
||||
absolute: true,
|
||||
windowsPathsNoEscape: true,
|
||||
dot: false,
|
||||
follow: true,
|
||||
});
|
||||
|
||||
const validFiles = allFiles.filter(isValidFile);
|
||||
if (validFiles.length === 0) {
|
||||
console.log("⚠️ 未找到符合条件的文件,跳过生成 index.ts");
|
||||
return;
|
||||
}
|
||||
|
||||
validFiles.sort();
|
||||
|
||||
const exportStatements = validFiles.map((file) => {
|
||||
const relPath = path.relative(dirPath, file);
|
||||
const importPath = `./${relPath
|
||||
.replace(/\.[^.]+$/, "")
|
||||
.replace(/\\/g, "/")}`;
|
||||
return `export * from '${importPath}';`;
|
||||
});
|
||||
|
||||
const indexContent = `
|
||||
import './index.css';
|
||||
|
||||
${exportStatements.join("\n")}
|
||||
`.trim();
|
||||
|
||||
const indexFilePath = path.resolve(dirPath, "index.ts");
|
||||
|
||||
// ✅ 内容比对,避免重复写入
|
||||
if (fs.existsSync(indexFilePath)) {
|
||||
const old = fs.readFileSync(indexFilePath, "utf8");
|
||||
if (old === indexContent) {
|
||||
console.log("✅ index.ts 内容无变化,无需重新生成");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(indexFilePath, indexContent, "utf8");
|
||||
console.log(`✅ 成功生成 index.ts: ${indexFilePath}`);
|
||||
}
|
||||
|
||||
// 脚本入口
|
||||
const [targetDir] = CONFIG.targetDirs;
|
||||
if (!targetDir) {
|
||||
console.error("❌ CONFIG.targetDirs 不能为空");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const absTargetDir = path.resolve(process.cwd(), targetDir);
|
||||
|
||||
try {
|
||||
console.log(`🚀 开始扫描目录: ${absTargetDir}`);
|
||||
generateIndexFile(absTargetDir);
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
console.error(`❌ [gen-index-ts] 执行失败: ${msg}`);
|
||||
process.exit(1);
|
||||
}
|
||||
121
templates/vite-react-lib/scripts/gen-index-ts.ts
Normal file
121
templates/vite-react-lib/scripts/gen-index-ts.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { globSync } from "glob";
|
||||
|
||||
interface Config {
|
||||
targetDirs: string[];
|
||||
includeExtensions: string[];
|
||||
excludeKeywords: {
|
||||
dirs: string[];
|
||||
fileSuffixes: string[];
|
||||
filePatterns: RegExp[];
|
||||
};
|
||||
}
|
||||
|
||||
const CONFIG: Config = {
|
||||
targetDirs: ["src"],
|
||||
includeExtensions: [".ts", ".tsx", ".vue"],
|
||||
excludeKeywords: {
|
||||
dirs: ["__tests__", "tests", "story", "stories", "types"],
|
||||
fileSuffixes: [".d.ts"],
|
||||
filePatterns: [
|
||||
/^index\.(ts|tsx|js|jsx)$/,
|
||||
/\.(test|spec)\./,
|
||||
/\.(story|stories)\./,
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const normalizePath = (p: string) => p.replace(/\\/g, "/");
|
||||
|
||||
const isInExcludeDir = (filePath: string) => {
|
||||
const normalized = normalizePath(filePath);
|
||||
return CONFIG.excludeKeywords.dirs.some((dir) =>
|
||||
normalized.includes(`/${dir}/`),
|
||||
);
|
||||
};
|
||||
|
||||
const isExcludeSuffix = (filePath: string) =>
|
||||
CONFIG.excludeKeywords.fileSuffixes.some((suffix) =>
|
||||
filePath.endsWith(suffix),
|
||||
);
|
||||
|
||||
const isMatchExcludePattern = (fileName: string) =>
|
||||
CONFIG.excludeKeywords.filePatterns.some((pattern) => pattern.test(fileName));
|
||||
|
||||
function isValidFile(filePath: string): boolean {
|
||||
const fileName = filePath.split(/[\\/]/).pop()!;
|
||||
|
||||
if (isInExcludeDir(filePath)) return false;
|
||||
if (isExcludeSuffix(filePath)) return false;
|
||||
if (isMatchExcludePattern(fileName)) return false;
|
||||
|
||||
const ext = path.extname(filePath);
|
||||
return CONFIG.includeExtensions.includes(ext);
|
||||
}
|
||||
|
||||
function generateIndexFile(dirPath: string) {
|
||||
const searchPattern = path.resolve(dirPath, "**", "*.*");
|
||||
|
||||
const allFiles = globSync(searchPattern, {
|
||||
nodir: true,
|
||||
absolute: true,
|
||||
windowsPathsNoEscape: true,
|
||||
dot: false,
|
||||
follow: true,
|
||||
});
|
||||
|
||||
const validFiles = allFiles.filter(isValidFile);
|
||||
if (validFiles.length === 0) {
|
||||
console.log("⚠️ 未找到符合条件的文件,跳过生成 index.ts");
|
||||
return;
|
||||
}
|
||||
|
||||
validFiles.sort();
|
||||
|
||||
const exportStatements = validFiles.map((file) => {
|
||||
const relPath = path.relative(dirPath, file);
|
||||
const importPath = `./${relPath
|
||||
.replace(/\.[^.]+$/, "")
|
||||
.replace(/\\/g, "/")}`;
|
||||
return `export * from '${importPath}';`;
|
||||
});
|
||||
|
||||
const indexContent = `
|
||||
import './index.css';
|
||||
|
||||
${exportStatements.join("\n")}
|
||||
`.trim();
|
||||
|
||||
const indexFilePath = path.resolve(dirPath, "index.ts");
|
||||
|
||||
// ✅ 内容比对,避免重复写入
|
||||
if (fs.existsSync(indexFilePath)) {
|
||||
const old = fs.readFileSync(indexFilePath, "utf8");
|
||||
if (old === indexContent) {
|
||||
console.log("✅ index.ts 内容无变化,无需重新生成");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(indexFilePath, indexContent, "utf8");
|
||||
console.log(`✅ 成功生成 index.ts: ${indexFilePath}`);
|
||||
}
|
||||
|
||||
// 脚本入口
|
||||
const [targetDir] = CONFIG.targetDirs;
|
||||
if (!targetDir) {
|
||||
console.error("❌ CONFIG.targetDirs 不能为空");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const absTargetDir = path.resolve(process.cwd(), targetDir);
|
||||
|
||||
try {
|
||||
console.log(`🚀 开始扫描目录: ${absTargetDir}`);
|
||||
generateIndexFile(absTargetDir);
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
console.error(`❌ [gen-index-ts] 执行失败: ${msg}`);
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user