mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 06:06:37 +03:00
Simplify import graph scanning
Replace three duplicate matcher loops with one declarative pattern list while preserving import resolution behavior. Add Sass @use and @forward characterization coverage.\n\nAI-assisted change prepared under pbakaus's scheduled architecture-refactor authorization.
This commit is contained in:
@@ -31,6 +31,12 @@ const SCANNABLE_EXTENSIONS = new Set([
|
||||
|
||||
const HTML_EXTENSIONS = new Set(['.html', '.htm']);
|
||||
|
||||
const IMPORT_SPECIFIER_PATTERNS = [
|
||||
/import\s+(?:[\s\S]*?from\s+)?['"]([^'"]+)['"]/g,
|
||||
/@import\s+(?:url\(\s*)?['"]?([^'");\s]+)['"]?\s*\)?/g,
|
||||
/@(?:use|forward)\s+['"]([^'"]+)['"]/g,
|
||||
];
|
||||
|
||||
function walkDir(dir) {
|
||||
const files = [];
|
||||
let entries;
|
||||
@@ -75,26 +81,11 @@ function buildImportGraph(files) {
|
||||
const dir = path.dirname(file);
|
||||
const imports = new Set();
|
||||
|
||||
// ES imports: import ... from '...' and import '...'
|
||||
const esRe = /import\s+(?:[\s\S]*?from\s+)?['"]([^'"]+)['"]/g;
|
||||
let m;
|
||||
while ((m = esRe.exec(content)) !== null) {
|
||||
const resolved = resolveImport(m[1], dir, fileSet);
|
||||
if (resolved) imports.add(resolved);
|
||||
}
|
||||
|
||||
// CSS @import
|
||||
const cssRe = /@import\s+(?:url\(\s*)?['"]?([^'");\s]+)['"]?\s*\)?/g;
|
||||
while ((m = cssRe.exec(content)) !== null) {
|
||||
const resolved = resolveImport(m[1], dir, fileSet);
|
||||
if (resolved) imports.add(resolved);
|
||||
}
|
||||
|
||||
// SCSS @use / @forward
|
||||
const scssRe = /@(?:use|forward)\s+['"]([^'"]+)['"]/g;
|
||||
while ((m = scssRe.exec(content)) !== null) {
|
||||
const resolved = resolveImport(m[1], dir, fileSet);
|
||||
if (resolved) imports.add(resolved);
|
||||
for (const pattern of IMPORT_SPECIFIER_PATTERNS) {
|
||||
for (const match of content.matchAll(pattern)) {
|
||||
const resolved = resolveImport(match[1], dir, fileSet);
|
||||
if (resolved) imports.add(resolved);
|
||||
}
|
||||
}
|
||||
|
||||
graph.set(file, imports);
|
||||
|
||||
@@ -2797,6 +2797,20 @@ describe('buildImportGraph', () => {
|
||||
expect(themeImports.has(path.join(MF, 'variables.sass'))).toBe(true);
|
||||
});
|
||||
|
||||
test('resolves Sass @use and @forward', async () => {
|
||||
await withStaticFixture({
|
||||
'theme.scss': "@use './variables';\n@forward './tokens';\n",
|
||||
'variables.scss': '$primary: rebeccapurple;\n',
|
||||
'tokens.scss': '$spacing: 1rem;\n',
|
||||
}, ({ dir }) => {
|
||||
const theme = path.join(dir, 'theme.scss');
|
||||
const variables = path.join(dir, 'variables.scss');
|
||||
const tokens = path.join(dir, 'tokens.scss');
|
||||
const graph = buildImportGraph([theme, variables, tokens]);
|
||||
expect(graph.get(theme)).toEqual(new Set([variables, tokens]));
|
||||
});
|
||||
});
|
||||
|
||||
test('ignores bare/node_modules imports', () => {
|
||||
const graph = buildImportGraph([
|
||||
path.join(MF, 'App.tsx'),
|
||||
|
||||
Reference in New Issue
Block a user