vue-cssgen
Version:
Инструмент для автоматизации работы со стилями в Vue 3-проектах
175 lines (149 loc) • 6.5 kB
JavaScript
import fs from 'fs';
import path from 'path';
import animations from './animations.js';
import borderRadius from './borderRadius.js';
import borders from './borders.js';
import colors from './colors.js';
import container from './container.js';
import effects from './effects.js';
import flex from './flex.js';
import fontSizes from './fontSizes.js';
import fontWeights from './fontWeights.js';
import gradients from './gradients.js';
import grid from './grid.js';
import modifiers from './modifiers.js';
import opacity from './opacity.js';
import position from './position.js';
import sizes from './sizes.js';
import spacing from './spacing.js';
import textAlign from './textAlign.js';
// Сбор всех базовых правил
const baseRules = [
...animations,
...borderRadius,
...borders,
...colors,
...container,
...effects,
...flex,
...fontSizes,
...fontWeights,
...gradients,
...grid,
...modifiers,
...opacity,
...position,
...sizes,
...spacing,
...textAlign,
];
// Попытка загрузить кастомные правила из папки vue-cssgen-rules в корне проекта
async function loadProjectRules(projectRoot) {
// Используем projectRoot, если передан, иначе используем текущий каталог
const baseDir = projectRoot || process.cwd();
// Попробуем несколько возможных путей для поиска папки с правилами
const possiblePaths = [
path.resolve(baseDir, 'vue-cssgen-rules'),
path.resolve(process.cwd(), 'vue-cssgen-rules'),
path.resolve(baseDir, '..', 'vue-cssgen-rules'),
path.resolve(baseDir, '..', '..', 'vue-cssgen-rules'),
// Для случая, когда проект находится в подпапке client-vue
path.resolve(baseDir, 'client-vue', 'vue-cssgen-rules')
];
console.log('Поиск кастомных правил. Текущий каталог:', process.cwd());
console.log('projectRoot:', baseDir);
let rulesDir = null;
// Проверяем все возможные пути
for (const dir of possiblePaths) {
console.log('Проверяем путь:', dir);
if (fs.existsSync(dir)) {
rulesDir = dir;
console.log('Найден каталог с кастомными правилами:', rulesDir);
break;
}
}
if (!rulesDir) {
console.log('Каталог с кастомными правилами не найден в проверенных путях');
return [];
}
const customRules = [];
const files = fs.readdirSync(rulesDir).filter(f => f.endsWith('.js'));
console.log(`Найдено ${files.length} файлов с правилами:`, files);
for (const file of files) {
try {
const modulePath = path.join(rulesDir, file);
// Используем URL для правильного импорта в ESM
const fileUrl = `file://${modulePath.replace(/\\/g, '/')}`;
console.log('Загружаем файл:', fileUrl);
const imported = await import(fileUrl);
const rules = imported.default || [];
customRules.push(...rules);
console.log(`Загружено ${rules.length} правил из файла ${file}`);
} catch (error) {
console.error(`Ошибка загрузки правил из файла ${file}:`, error);
console.error(error.stack);
}
}
return customRules;
}
function isRegExpEqual( a, b ) {
return (
a instanceof RegExp &&
b instanceof RegExp &&
a.source === b.source &&
a.flags === b.flags
);
}
function mergeRules( base, custom ) {
const result = [...base];
custom.forEach(customRule => {
// Преобразуем регулярное выражение в строку для сравнения
const customRegexStr = customRule.match.toString();
// Ищем индекс правила с таким же регулярным выражением
const idx = result.findIndex(rule =>
rule.match.toString() === customRegexStr
);
if (idx !== -1) {
console.log(`Переопределяем правило: ${customRegexStr}`);
result[idx] = customRule;
} else {
result.push(customRule);
}
});
return result;
}
// Инициализируем правила базовыми
let rules = baseRules;
let rulesLoaded = false;
let rulesLoadPromise = null;
// Функция для загрузки правил, которая возвращает Promise
function loadRules(projectRoot) {
if (rulesLoaded) return Promise.resolve(rules);
if (rulesLoadPromise) return rulesLoadPromise;
rulesLoadPromise = (async () => {
try {
const customRules = await loadProjectRules(projectRoot);
if (customRules.length) {
rules = mergeRules(baseRules, customRules);
console.log(`Загружено ${customRules.length} кастомных правил`);
}
rulesLoaded = true;
return rules;
} catch (e) {
console.error('Ошибка при загрузке кастомных правил:', e);
rulesLoaded = true;
return rules;
}
})();
return rulesLoadPromise;
}
// Не запускаем загрузку правил сразу, ждем projectRoot
// Асинхронная функция для получения правил
export async function getRules(projectRoot) {
return await loadRules(projectRoot);
}
// Для обратной совместимости - возвращаем базовые правила сразу,
// но они будут заменены после загрузки кастомных
export default rules;
// Экспортируем функцию для ожидания загрузки правил
export { loadRules as waitForRules };