Skip to content

Commit 4584c90

Browse files
fix: resolution algorithm for node-sass (#866)
1 parent eabf500 commit 4584c90

12 files changed

+118
-2
lines changed

src/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ function loader(content) {
3737
if (shouldUseWebpackImporter) {
3838
const { includePaths } = sassOptions;
3939

40-
sassOptions.importer.push(getWebpackImporter(this, includePaths));
40+
sassOptions.importer.push(
41+
getWebpackImporter(this, implementation, includePaths)
42+
);
4143
}
4244

4345
const callback = this.async();

src/utils.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ const isSpecialModuleImport = /^~[^/]+$/;
267267
// `[drive_letter]:\` + `\\[server]\[sharename]\`
268268
const isNativeWin32Path = /^[a-zA-Z]:[/\\]|^\\\\/i;
269269

270-
function getWebpackImporter(loaderContext, includePaths) {
270+
function getWebpackImporter(loaderContext, implementation, includePaths) {
271271
function startResolving(resolutionMap) {
272272
if (resolutionMap.length === 0) {
273273
return Promise.reject();
@@ -359,6 +359,16 @@ function getWebpackImporter(loaderContext, includePaths) {
359359
//
360360
// Because `sass`/`node-sass` run custom importers before `3`, `4` and `5` points, we need to emulate this behavior to avoid wrong resolution.
361361
const sassPossibleRequests = getPossibleRequests(loaderContext, request);
362+
const isDartSass = implementation.info.includes('dart-sass');
363+
364+
// `node-sass` calls our importer before `1. Filesystem imports relative to the base file.`, so we need emulate this too
365+
if (!isDartSass) {
366+
resolutionMap = resolutionMap.concat({
367+
resolve: sassResolve,
368+
context: path.dirname(prev),
369+
possibleRequests: sassPossibleRequests,
370+
});
371+
}
362372

363373
resolutionMap = resolutionMap.concat(
364374
includePaths.map((context) => ({

test/__snapshots__/loader.test.js.snap

+54
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,60 @@ exports[`loader should prefer "mainFiles" with extension over without (node-sass
346346

347347
exports[`loader should prefer "mainFiles" with extension over without (node-sass) (scss): warnings 1`] = `Array []`;
348348

349+
exports[`loader should prefer relative import (dart-sass) (sass): css 1`] = `
350+
".class {
351+
color: blue;
352+
}
353+
354+
a {
355+
color: red;
356+
}"
357+
`;
358+
359+
exports[`loader should prefer relative import (dart-sass) (sass): errors 1`] = `Array []`;
360+
361+
exports[`loader should prefer relative import (dart-sass) (sass): warnings 1`] = `Array []`;
362+
363+
exports[`loader should prefer relative import (dart-sass) (scss): css 1`] = `
364+
".class {
365+
color: blue;
366+
}
367+
368+
a {
369+
color: red;
370+
}"
371+
`;
372+
373+
exports[`loader should prefer relative import (dart-sass) (scss): errors 1`] = `Array []`;
374+
375+
exports[`loader should prefer relative import (dart-sass) (scss): warnings 1`] = `Array []`;
376+
377+
exports[`loader should prefer relative import (node-sass) (sass): css 1`] = `
378+
".class {
379+
color: blue; }
380+
381+
a {
382+
color: red; }
383+
"
384+
`;
385+
386+
exports[`loader should prefer relative import (node-sass) (sass): errors 1`] = `Array []`;
387+
388+
exports[`loader should prefer relative import (node-sass) (sass): warnings 1`] = `Array []`;
389+
390+
exports[`loader should prefer relative import (node-sass) (scss): css 1`] = `
391+
".class {
392+
color: blue; }
393+
394+
a {
395+
color: red; }
396+
"
397+
`;
398+
399+
exports[`loader should prefer relative import (node-sass) (scss): errors 1`] = `Array []`;
400+
401+
exports[`loader should prefer relative import (node-sass) (scss): warnings 1`] = `Array []`;
402+
349403
exports[`loader should resolve absolute paths (dart-sass) (sass): css 1`] = `
350404
"@charset \\"UTF-8\\";
351405
body {

test/helpers/getCodeFromSass.js

+8
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,10 @@ function getCodeFromSass(testId, options) {
267267
const pathToLanguage = isSass
268268
? path.resolve(testFolder, 'sass/language.sass')
269269
: path.resolve(testFolder, 'scss/language.scss');
270+
const pathToPackageWithSameImport = path.resolve(
271+
testFolder,
272+
'node_modules/package-with-same-import/style.scss'
273+
);
270274

271275
// Pseudo importer for tests
272276
function testImporter(url) {
@@ -733,6 +737,10 @@ function getCodeFromSass(testId, options) {
733737
.replace(/^\/scss\/language.scss/, pathToLanguage)
734738
.replace(/^file:\/\/\/scss\/language.scss/, pathToLanguage)
735739
.replace(/^file:\/\/\/sass\/language.sass/, pathToLanguage)
740+
.replace(
741+
/^package-with-same-import\/style/,
742+
pathToPackageWithSameImport
743+
)
736744
.replace(/^~/, testNodeModules);
737745
}
738746

test/loader.test.js

+16
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,22 @@ describe('loader', () => {
884884
expect(getErrors(stats)).toMatchSnapshot('errors');
885885
});
886886

887+
it(`should prefer relative import (${implementationName}) (${syntax})`, async () => {
888+
const testId = getTestId('package-with-same-import', syntax);
889+
const options = {
890+
implementation: getImplementationByName(implementationName),
891+
};
892+
const compiler = getCompiler(testId, { loader: { options } });
893+
const stats = await compile(compiler);
894+
const codeFromBundle = getCodeFromBundle(stats, compiler);
895+
const codeFromSass = getCodeFromSass(testId, options);
896+
897+
expect(codeFromBundle.css).toBe(codeFromSass.css);
898+
expect(codeFromBundle.css).toMatchSnapshot('css');
899+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
900+
expect(getErrors(stats)).toMatchSnapshot('errors');
901+
});
902+
887903
if (implementation === dartSass) {
888904
it(`should output an understandable error with a problem in "@use" (${implementationName}) (${syntax})`, async () => {
889905
const testId = getTestId('error-use', syntax);

test/node_modules/package-with-same-import/package.json

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/node_modules/package-with-same-import/style.scss

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/node_modules/package-with-same-import/test/scss/package-with-package.scss

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/sass/package-with-package.sass

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "package-with-same-import/style"
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@import "package-with-package"
2+
3+
a
4+
color: red

test/scss/package-with-package.scss

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "package-with-same-import/style";
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import "package-with-package";
2+
3+
a {
4+
color: red;
5+
}

0 commit comments

Comments
 (0)