Skip to content

Commit ee09aa3

Browse files
committed
Resolve _partial.scss in compiler (close #1439)
1 parent 88c488a commit ee09aa3

File tree

2 files changed

+19
-19
lines changed

2 files changed

+19
-19
lines changed
Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
1-
import type { HasDependency } from './types.js';
1+
import { existsSync } from 'node:fs';
2+
import { basename, dirname, join } from '../util/path.js';
3+
import type { HasDependency, SyncCompilerFn } from './types.js';
24

35
const condition = (hasDependency: HasDependency) =>
46
hasDependency('sass') || hasDependency('sass-embedded') || hasDependency('node-sass');
57

68
const importMatcher = /@(?:use|import|forward)\s+['"](pkg:)?([^'"]+)['"]/g;
79

8-
const toRelative = (specifier: string) => (specifier.startsWith('.') ? specifier : `./${specifier}`);
9-
10-
const compiler = (text: string) => {
11-
const imports = [];
12-
let match: RegExpExecArray | null;
13-
let index = 0;
14-
15-
// biome-ignore lint/suspicious/noAssignInExpressions: standard regex loop pattern
16-
while ((match = importMatcher.exec(text))) {
17-
if (match[2] && !match[2].startsWith('sass:'))
18-
imports.push(`import _$${index++} from '${match[1] ? match[2] : toRelative(match[2])}';`);
19-
}
20-
21-
return imports.join('\n');
10+
// Resolve _partials here to not soil the main resolver
11+
const resolvePartial = (specifier: string, containingFile: string) => {
12+
const rel = specifier.startsWith('.') ? specifier : `./${specifier}`;
13+
const name = basename(rel);
14+
if (name.startsWith('_')) return rel;
15+
const dir = dirname(rel);
16+
const partial = name.endsWith('.scss') ? `_${name}` : `_${name}.scss`;
17+
if (existsSync(join(dirname(containingFile), dir, partial))) return `${dir}/_${name}`;
18+
return rel;
2219
};
2320

21+
const compiler: SyncCompilerFn = (text, filePath) =>
22+
[...text.matchAll(importMatcher)]
23+
.filter(match => match[2] && !match[2].startsWith('sass:'))
24+
.map((match, i) => `import _$${i} from '${match[1] ? match[2] : resolvePartial(match[2], filePath)}';`)
25+
.join('\n');
26+
2427
export default { condition, compiler };

packages/knip/test/compilers.scss.test.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,11 @@ test('Built-in compiler for SCSS', async () => {
1313
const { issues, counters } = await main(options);
1414

1515
assert(issues.files.has(join(cwd, 'unused.scss')));
16-
assert(issues.files.has(join(cwd, '_partial.scss')));
17-
assert(issues.unresolved['styles.scss']['./partial']);
1816

1917
assert.deepEqual(counters, {
2018
...baseCounters,
2119
devDependencies: 1,
22-
files: 2,
23-
unresolved: 1,
20+
files: 1,
2421
processed: 14,
2522
total: 14,
2623
});

0 commit comments

Comments
 (0)