Skip to content

Commit 0e94940

Browse files
fix: resolution algorithm (#720)
1 parent 96f436f commit 0e94940

File tree

103 files changed

+1424
-37
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+1424
-37
lines changed

src/importsToResolve.js

+37-14
Original file line numberDiff line numberDiff line change
@@ -19,41 +19,64 @@ function importsToResolve(url) {
1919
// @see https://github.com./webpack-contrib/sass-loader/issues/167
2020
const ext = path.extname(request);
2121

22+
// In case there is module request, send this to webpack resolver
2223
if (matchModuleImport.test(url)) {
2324
return [request, url];
2425
}
2526

26-
// libsass' import algorithm works like this:
27-
28-
// In case there is a file extension...
29-
// - If the file is a CSS-file, do not include it all, but just link it via @import url().
30-
// - The exact file name must match (no auto-resolving of '_'-modules).
27+
// Because @import is also defined in CSS, Sass needs a way of compiling plain CSS @imports without trying to import the files at compile time.
28+
// To accomplish this, and to ensure SCSS is as much of a superset of CSS as possible, Sass will compile any @imports with the following characteristics to plain CSS imports:
29+
// - imports where the URL ends with .css.
30+
// - imports where the URL begins http:// or https://.
31+
// - imports where the URL is written as a url().
32+
// - imports that have media queries.
33+
//
34+
// The `node-sass` package sends `@import` ending on `.css` to importer, it is bug, so we skip resolve
3135
if (ext === '.css') {
3236
return [];
3337
}
3438

39+
const dirname = path.dirname(request);
40+
const basename = path.basename(request);
41+
42+
// In case there is file extension:
43+
//
44+
// 1. Try to resolve `_` file.
45+
// 2. Try to resolve file without `_`.
46+
// 3. Send a original url to webpack resolver, maybe it is alias.
3547
if (['.scss', '.sass'].includes(ext)) {
36-
return [request, url];
48+
return [`${dirname}/_${basename}`, `${dirname}/${basename}`, url];
3749
}
3850

39-
// In case there is no file extension...
40-
// - Prefer modules starting with '_'.
41-
// - File extension precedence: .scss, .sass, .css.
42-
const basename = path.basename(request);
43-
51+
// In case there is no file extension and filename starts with `_`:
52+
//
53+
// 1. Try to resolve files with `scss`, `sass` and `css` extensions.
54+
// 2. Try to resolve directory with `_index` or `index` filename.
55+
// 3. Send a original url to webpack resolver, maybe it is alias.
4456
if (basename.charAt(0) === '_') {
45-
return [`${request}.scss`, `${request}.sass`, `${request}.css`, url];
57+
return [
58+
`${request}.scss`,
59+
`${request}.sass`,
60+
`${request}.css`,
61+
request,
62+
url,
63+
];
4664
}
4765

48-
const dirname = path.dirname(request);
49-
66+
// In case there is no file extension and filename doesn't start with `_`:
67+
//
68+
// 1. Try to resolve file starts with `_` and with extensions
69+
// 2. Try to resolve file with extensions
70+
// 3. Try to resolve directory with `_index` or `index` filename.
71+
// 4. Send a original url to webpack resolver, maybe it is alias.
5072
return [
5173
`${dirname}/_${basename}.scss`,
5274
`${dirname}/_${basename}.sass`,
5375
`${dirname}/_${basename}.css`,
5476
`${request}.scss`,
5577
`${request}.sass`,
5678
`${request}.css`,
79+
request,
5780
url,
5881
];
5982
}

src/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ function loader(content) {
5555
// Supported since v4.36.0
5656
if (hasGetResolve(self)) {
5757
resolve = this.getResolve({
58-
mainFields: ['sass', 'style', '...'],
58+
mainFields: ['sass', 'style', 'main', '...'],
59+
mainFiles: ['_index', 'index', '...'],
5960
extensions: ['.scss', '.sass', '.css', '...'],
6061
});
6162
}

test/__snapshots__/loader.test.js.snap

+136-8
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,22 @@ exports[`loader should work and ignore all css "@import" at-rules (node-sass) (s
282282
283283
exports[`loader should work and ignore all css "@import" at-rules (node-sass) (scss): warnings 1`] = `Array []`;
284284
285+
exports[`loader should work and use the "_index" file in package (dart-sass) (sass): errors 1`] = `Array []`;
286+
287+
exports[`loader should work and use the "_index" file in package (dart-sass) (sass): warnings 1`] = `Array []`;
288+
289+
exports[`loader should work and use the "_index" file in package (dart-sass) (scss): errors 1`] = `Array []`;
290+
291+
exports[`loader should work and use the "_index" file in package (dart-sass) (scss): warnings 1`] = `Array []`;
292+
293+
exports[`loader should work and use the "_index" file in package (node-sass) (sass): errors 1`] = `Array []`;
294+
295+
exports[`loader should work and use the "_index" file in package (node-sass) (sass): warnings 1`] = `Array []`;
296+
297+
exports[`loader should work and use the "_index" file in package (node-sass) (scss): errors 1`] = `Array []`;
298+
299+
exports[`loader should work and use the "_index" file in package (node-sass) (scss): warnings 1`] = `Array []`;
300+
285301
exports[`loader should work and use the "custom-sass" field (dart-sass) (sass): errors 1`] = `Array []`;
286302
287303
exports[`loader should work and use the "custom-sass" field (dart-sass) (sass): warnings 1`] = `Array []`;
@@ -298,21 +314,53 @@ exports[`loader should work and use the "custom-sass" field (node-sass) (scss):
298314
299315
exports[`loader should work and use the "custom-sass" field (node-sass) (scss): warnings 1`] = `Array []`;
300316
301-
exports[`loader should work and use the "index" property in package (dart-sass) (sass): errors 1`] = `Array []`;
317+
exports[`loader should work and use the "index" file in package (dart-sass) (sass): errors 1`] = `Array []`;
318+
319+
exports[`loader should work and use the "index" file in package (dart-sass) (sass): warnings 1`] = `Array []`;
320+
321+
exports[`loader should work and use the "index" file in package (dart-sass) (scss): errors 1`] = `Array []`;
322+
323+
exports[`loader should work and use the "index" file in package (dart-sass) (scss): warnings 1`] = `Array []`;
324+
325+
exports[`loader should work and use the "index" file in package (node-sass) (sass): errors 1`] = `Array []`;
326+
327+
exports[`loader should work and use the "index" file in package (node-sass) (sass): warnings 1`] = `Array []`;
328+
329+
exports[`loader should work and use the "index" file in package (node-sass) (scss): errors 1`] = `Array []`;
330+
331+
exports[`loader should work and use the "index" file in package (node-sass) (scss): warnings 1`] = `Array []`;
332+
333+
exports[`loader should work and use the "index" file in package when the "index" value already in the "mainFiles" resolve option (dart-sass) (sass): errors 1`] = `Array []`;
302334
303-
exports[`loader should work and use the "index" property in package (dart-sass) (sass): warnings 1`] = `Array []`;
335+
exports[`loader should work and use the "index" file in package when the "index" value already in the "mainFiles" resolve option (dart-sass) (sass): warnings 1`] = `Array []`;
304336
305-
exports[`loader should work and use the "index" property in package (dart-sass) (scss): errors 1`] = `Array []`;
337+
exports[`loader should work and use the "index" file in package when the "index" value already in the "mainFiles" resolve option (dart-sass) (scss): errors 1`] = `Array []`;
306338
307-
exports[`loader should work and use the "index" property in package (dart-sass) (scss): warnings 1`] = `Array []`;
339+
exports[`loader should work and use the "index" file in package when the "index" value already in the "mainFiles" resolve option (dart-sass) (scss): warnings 1`] = `Array []`;
308340
309-
exports[`loader should work and use the "index" property in package (node-sass) (sass): errors 1`] = `Array []`;
341+
exports[`loader should work and use the "index" file in package when the "index" value already in the "mainFiles" resolve option (node-sass) (sass): errors 1`] = `Array []`;
310342
311-
exports[`loader should work and use the "index" property in package (node-sass) (sass): warnings 1`] = `Array []`;
343+
exports[`loader should work and use the "index" file in package when the "index" value already in the "mainFiles" resolve option (node-sass) (sass): warnings 1`] = `Array []`;
312344
313-
exports[`loader should work and use the "index" property in package (node-sass) (scss): errors 1`] = `Array []`;
345+
exports[`loader should work and use the "index" file in package when the "index" value already in the "mainFiles" resolve option (node-sass) (scss): errors 1`] = `Array []`;
314346
315-
exports[`loader should work and use the "index" property in package (node-sass) (scss): warnings 1`] = `Array []`;
347+
exports[`loader should work and use the "index" file in package when the "index" value already in the "mainFiles" resolve option (node-sass) (scss): warnings 1`] = `Array []`;
348+
349+
exports[`loader should work and use the "index" file in package when the "index" value is not in the "mainFiles" resolve option (dart-sass) (sass): errors 1`] = `Array []`;
350+
351+
exports[`loader should work and use the "index" file in package when the "index" value is not in the "mainFiles" resolve option (dart-sass) (sass): warnings 1`] = `Array []`;
352+
353+
exports[`loader should work and use the "index" file in package when the "index" value is not in the "mainFiles" resolve option (dart-sass) (scss): errors 1`] = `Array []`;
354+
355+
exports[`loader should work and use the "index" file in package when the "index" value is not in the "mainFiles" resolve option (dart-sass) (scss): warnings 1`] = `Array []`;
356+
357+
exports[`loader should work and use the "index" file in package when the "index" value is not in the "mainFiles" resolve option (node-sass) (sass): errors 1`] = `Array []`;
358+
359+
exports[`loader should work and use the "index" file in package when the "index" value is not in the "mainFiles" resolve option (node-sass) (sass): warnings 1`] = `Array []`;
360+
361+
exports[`loader should work and use the "index" file in package when the "index" value is not in the "mainFiles" resolve option (node-sass) (scss): errors 1`] = `Array []`;
362+
363+
exports[`loader should work and use the "index" file in package when the "index" value is not in the "mainFiles" resolve option (node-sass) (scss): warnings 1`] = `Array []`;
316364
317365
exports[`loader should work and use the "main" field (dart-sass) (sass): errors 1`] = `Array []`;
318366
@@ -330,6 +378,38 @@ exports[`loader should work and use the "main" field (node-sass) (scss): errors
330378
331379
exports[`loader should work and use the "main" field (node-sass) (scss): warnings 1`] = `Array []`;
332380
381+
exports[`loader should work and use the "main" field when the "main" value already in the "mainFields" resolve option (dart-sass) (sass): errors 1`] = `Array []`;
382+
383+
exports[`loader should work and use the "main" field when the "main" value already in the "mainFields" resolve option (dart-sass) (sass): warnings 1`] = `Array []`;
384+
385+
exports[`loader should work and use the "main" field when the "main" value already in the "mainFields" resolve option (dart-sass) (scss): errors 1`] = `Array []`;
386+
387+
exports[`loader should work and use the "main" field when the "main" value already in the "mainFields" resolve option (dart-sass) (scss): warnings 1`] = `Array []`;
388+
389+
exports[`loader should work and use the "main" field when the "main" value already in the "mainFields" resolve option (node-sass) (sass): errors 1`] = `Array []`;
390+
391+
exports[`loader should work and use the "main" field when the "main" value already in the "mainFields" resolve option (node-sass) (sass): warnings 1`] = `Array []`;
392+
393+
exports[`loader should work and use the "main" field when the "main" value already in the "mainFields" resolve option (node-sass) (scss): errors 1`] = `Array []`;
394+
395+
exports[`loader should work and use the "main" field when the "main" value already in the "mainFields" resolve option (node-sass) (scss): warnings 1`] = `Array []`;
396+
397+
exports[`loader should work and use the "main" field when the "main" value is not in the "mainFields" resolve option (dart-sass) (sass): errors 1`] = `Array []`;
398+
399+
exports[`loader should work and use the "main" field when the "main" value is not in the "mainFields" resolve option (dart-sass) (sass): warnings 1`] = `Array []`;
400+
401+
exports[`loader should work and use the "main" field when the "main" value is not in the "mainFields" resolve option (dart-sass) (scss): errors 1`] = `Array []`;
402+
403+
exports[`loader should work and use the "main" field when the "main" value is not in the "mainFields" resolve option (dart-sass) (scss): warnings 1`] = `Array []`;
404+
405+
exports[`loader should work and use the "main" field when the "main" value is not in the "mainFields" resolve option (node-sass) (sass): errors 1`] = `Array []`;
406+
407+
exports[`loader should work and use the "main" field when the "main" value is not in the "mainFields" resolve option (node-sass) (sass): warnings 1`] = `Array []`;
408+
409+
exports[`loader should work and use the "main" field when the "main" value is not in the "mainFields" resolve option (node-sass) (scss): errors 1`] = `Array []`;
410+
411+
exports[`loader should work and use the "main" field when the "main" value is not in the "mainFields" resolve option (node-sass) (scss): warnings 1`] = `Array []`;
412+
333413
exports[`loader should work and use the "sass" field (dart-sass) (sass): errors 1`] = `Array []`;
334414
335415
exports[`loader should work and use the "sass" field (dart-sass) (sass): warnings 1`] = `Array []`;
@@ -362,6 +442,54 @@ exports[`loader should work and use the "style" field (node-sass) (scss): errors
362442
363443
exports[`loader should work and use the "style" field (node-sass) (scss): warnings 1`] = `Array []`;
364444
445+
exports[`loader should work when "@import" at-rules starting with "_" (dart-sass) (sass): errors 1`] = `Array []`;
446+
447+
exports[`loader should work when "@import" at-rules starting with "_" (dart-sass) (sass): warnings 1`] = `Array []`;
448+
449+
exports[`loader should work when "@import" at-rules starting with "_" (dart-sass) (scss): errors 1`] = `Array []`;
450+
451+
exports[`loader should work when "@import" at-rules starting with "_" (dart-sass) (scss): warnings 1`] = `Array []`;
452+
453+
exports[`loader should work when "@import" at-rules starting with "_" (node-sass) (sass): errors 1`] = `Array []`;
454+
455+
exports[`loader should work when "@import" at-rules starting with "_" (node-sass) (sass): warnings 1`] = `Array []`;
456+
457+
exports[`loader should work when "@import" at-rules starting with "_" (node-sass) (scss): errors 1`] = `Array []`;
458+
459+
exports[`loader should work when "@import" at-rules starting with "_" (node-sass) (scss): warnings 1`] = `Array []`;
460+
461+
exports[`loader should work when "@import" at-rules with extensions (dart-sass) (sass): errors 1`] = `Array []`;
462+
463+
exports[`loader should work when "@import" at-rules with extensions (dart-sass) (sass): warnings 1`] = `Array []`;
464+
465+
exports[`loader should work when "@import" at-rules with extensions (dart-sass) (scss): errors 1`] = `Array []`;
466+
467+
exports[`loader should work when "@import" at-rules with extensions (dart-sass) (scss): warnings 1`] = `Array []`;
468+
469+
exports[`loader should work when "@import" at-rules with extensions (node-sass) (sass): errors 1`] = `Array []`;
470+
471+
exports[`loader should work when "@import" at-rules with extensions (node-sass) (sass): warnings 1`] = `Array []`;
472+
473+
exports[`loader should work when "@import" at-rules with extensions (node-sass) (scss): errors 1`] = `Array []`;
474+
475+
exports[`loader should work when "@import" at-rules with extensions (node-sass) (scss): warnings 1`] = `Array []`;
476+
477+
exports[`loader should work when "@import" at-rules without extensions and do not start with "_" (dart-sass) (sass): errors 1`] = `Array []`;
478+
479+
exports[`loader should work when "@import" at-rules without extensions and do not start with "_" (dart-sass) (sass): warnings 1`] = `Array []`;
480+
481+
exports[`loader should work when "@import" at-rules without extensions and do not start with "_" (dart-sass) (scss): errors 1`] = `Array []`;
482+
483+
exports[`loader should work when "@import" at-rules without extensions and do not start with "_" (dart-sass) (scss): warnings 1`] = `Array []`;
484+
485+
exports[`loader should work when "@import" at-rules without extensions and do not start with "_" (node-sass) (sass): errors 1`] = `Array []`;
486+
487+
exports[`loader should work when "@import" at-rules without extensions and do not start with "_" (node-sass) (sass): warnings 1`] = `Array []`;
488+
489+
exports[`loader should work when "@import" at-rules without extensions and do not start with "_" (node-sass) (scss): errors 1`] = `Array []`;
490+
491+
exports[`loader should work when "@import" at-rules without extensions and do not start with "_" (node-sass) (scss): warnings 1`] = `Array []`;
492+
365493
exports[`loader should work when an "@import" at-rule from scoped npm packages (dart-sass) (sass): errors 1`] = `Array []`;
366494
367495
exports[`loader should work when an "@import" at-rule from scoped npm packages (dart-sass) (sass): warnings 1`] = `Array []`;

0 commit comments

Comments
 (0)