diff --git a/src/utils.js b/src/utils.js index 14f63b31..e55576c1 100644 --- a/src/utils.js +++ b/src/utils.js @@ -303,6 +303,8 @@ const MODULE_REQUEST_REGEX = /^[^?]*~/; const IS_MODULE_IMPORT = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/; +const IS_PKG_SCHEME = /^pkg:/i; + /** * When `sass`/`node-sass` tries to resolve an import, it uses a special algorithm. * Since the `sass-loader` uses webpack to resolve the modules, we need to simulate that algorithm. @@ -331,7 +333,13 @@ function getPossibleRequests( request = request.replace(MODULE_REQUEST_REGEX, ""); } - if (IS_MODULE_IMPORT.test(url)) { + if (IS_PKG_SCHEME.test(url)) { + request = `${request.slice(4)}`; + + return [...new Set([request, url])]; + } + + if (IS_MODULE_IMPORT.test(url) || IS_PKG_SCHEME.test(url)) { request = request[request.length - 1] === "/" ? request : `${request}/`; return [...new Set([request, url])]; @@ -538,6 +546,8 @@ function getWebpackResolver( const needEmulateSassResolver = // `sass` doesn't support module import !IS_SPECIAL_MODULE_IMPORT.test(request) && + // don't handle `pkg:` scheme + !IS_PKG_SCHEME.test(request) && // We need improve absolute paths handling. // Absolute paths should be resolved: // - Server-relative URLs - `/path/to/file.ext` (where `` is root context) diff --git a/test/__snapshots__/loader.test.js.snap b/test/__snapshots__/loader.test.js.snap index 6bb93381..44cb366b 100644 --- a/test/__snapshots__/loader.test.js.snap +++ b/test/__snapshots__/loader.test.js.snap @@ -359192,6 +359192,46 @@ exports[`loader should work with "bootstrap" package v5, import as a package ('s exports[`loader should work with "bootstrap" package v5, import as a package ('sass-embedded', 'legacy' API, 'scss' syntax): warnings 1`] = `[]`; +exports[`loader should work with "pkg" prefix in "@use" ('dart-sass', 'legacy' API, 'sass' syntax) with "@charset "UTF-8";": css 1`] = ` +".foo { + color: red; +}" +`; + +exports[`loader should work with "pkg" prefix in "@use" ('dart-sass', 'legacy' API, 'sass' syntax) with "@charset "UTF-8";": errors 1`] = `[]`; + +exports[`loader should work with "pkg" prefix in "@use" ('dart-sass', 'legacy' API, 'sass' syntax) with "@charset "UTF-8";": warnings 1`] = `[]`; + +exports[`loader should work with "pkg" prefix in "@use" ('dart-sass', 'legacy' API, 'scss' syntax) with "@charset "UTF-8";": css 1`] = ` +".foo { + color: red; +}" +`; + +exports[`loader should work with "pkg" prefix in "@use" ('dart-sass', 'legacy' API, 'scss' syntax) with "@charset "UTF-8";": errors 1`] = `[]`; + +exports[`loader should work with "pkg" prefix in "@use" ('dart-sass', 'legacy' API, 'scss' syntax) with "@charset "UTF-8";": warnings 1`] = `[]`; + +exports[`loader should work with "pkg" prefix in "@use" ('sass-embedded', 'legacy' API, 'sass' syntax) with "@charset "UTF-8";": css 1`] = ` +".foo { + color: red; +}" +`; + +exports[`loader should work with "pkg" prefix in "@use" ('sass-embedded', 'legacy' API, 'sass' syntax) with "@charset "UTF-8";": errors 1`] = `[]`; + +exports[`loader should work with "pkg" prefix in "@use" ('sass-embedded', 'legacy' API, 'sass' syntax) with "@charset "UTF-8";": warnings 1`] = `[]`; + +exports[`loader should work with "pkg" prefix in "@use" ('sass-embedded', 'legacy' API, 'scss' syntax) with "@charset "UTF-8";": css 1`] = ` +".foo { + color: red; +}" +`; + +exports[`loader should work with "pkg" prefix in "@use" ('sass-embedded', 'legacy' API, 'scss' syntax) with "@charset "UTF-8";": errors 1`] = `[]`; + +exports[`loader should work with "pkg" prefix in "@use" ('sass-embedded', 'legacy' API, 'scss' syntax) with "@charset "UTF-8";": warnings 1`] = `[]`; + exports[`loader should work with a package with "sass" and "exports" fields ('dart-sass', 'legacy' API, 'sass' syntax): css 1`] = ` ".load-me { color: red; diff --git a/test/loader.test.js b/test/loader.test.js index c2d5bc80..a311ad49 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -2142,6 +2142,23 @@ describe("loader", () => { expect(getErrors(stats)).toMatchSnapshot("errors"); }); } + + if (!isModernAPI) { + it(`should work with "pkg" prefix in "@use" ('${implementationName}', '${api}' API, '${syntax}' syntax) with "@charset "UTF-8";"`, async () => { + const testId = getTestId("use-pkg", syntax); + const options = { + implementation, + api, + }; + const compiler = getCompiler(testId, { loader: { options } }); + const stats = await compile(compiler); + const codeFromBundle = getCodeFromBundle(stats, compiler); + + expect(codeFromBundle.css).toMatchSnapshot("css"); + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + }); + } } }); }); diff --git a/test/node_modules/pkg/package.json b/test/node_modules/pkg/package.json new file mode 100644 index 00000000..370c56e7 --- /dev/null +++ b/test/node_modules/pkg/package.json @@ -0,0 +1,7 @@ +{ + "name": "pkg", + "version": "1.0.0", + "exports": { + "sass": "styles/index.scss" + } +} diff --git a/test/node_modules/pkg/styles/index.scss b/test/node_modules/pkg/styles/index.scss new file mode 100644 index 00000000..a15c877a --- /dev/null +++ b/test/node_modules/pkg/styles/index.scss @@ -0,0 +1,3 @@ +.foo { + color: red; +} diff --git a/test/sass/use-pkg.sass b/test/sass/use-pkg.sass new file mode 100644 index 00000000..7503b2cf --- /dev/null +++ b/test/sass/use-pkg.sass @@ -0,0 +1 @@ +@use 'pkg:pkg' diff --git a/test/scss/use-pkg.scss b/test/scss/use-pkg.scss new file mode 100644 index 00000000..bc450ab2 --- /dev/null +++ b/test/scss/use-pkg.scss @@ -0,0 +1 @@ +@use 'pkg:pkg';