diff --git a/src/getPossibleRequests.js b/src/getPossibleRequests.js index b337e50f..262df2bc 100644 --- a/src/getPossibleRequests.js +++ b/src/getPossibleRequests.js @@ -1,6 +1,6 @@ import path from 'path'; -import utils from 'loader-utils'; +import { urlToRequest } from 'loader-utils'; // Examples: // - ~package @@ -9,7 +9,7 @@ import utils from 'loader-utils'; // - ~@org/ // - ~@org/package // - ~@org/package/ -const matchModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/; +const isModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/; /** * When libsass tries to resolve an import, it uses a special algorithm. @@ -22,10 +22,10 @@ const matchModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^ * @returns {Array} */ export default function getPossibleRequests(url, forWebpackResolver = false) { - const request = utils.urlToRequest(url); + const request = urlToRequest(url); // In case there is module request, send this to webpack resolver - if (forWebpackResolver && matchModuleImport.test(url)) { + if (forWebpackResolver && isModuleImport.test(url)) { return [request, url]; } diff --git a/src/webpackImporter.js b/src/webpackImporter.js index 1ea6bfff..7e6498b6 100644 --- a/src/webpackImporter.js +++ b/src/webpackImporter.js @@ -11,6 +11,7 @@ import path from 'path'; import getPossibleRequests from './getPossibleRequests'; const matchCss = /\.css$/i; +const isModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/; /** * Returns an importer that uses webpack's resolving algorithm. @@ -84,7 +85,7 @@ function webpackImporter(loaderContext, includePaths) { let resolutionMap = []; - if (includePaths.length > 0 && !isFileScheme) { + if (includePaths.length > 0 && !isFileScheme && !isModuleImport.test(url)) { // The order of import precedence is as follows: // // 1. Filesystem imports relative to the base file. diff --git a/test/__snapshots__/loader.test.js.snap b/test/__snapshots__/loader.test.js.snap index 8c82f3ac..bf2fb763 100644 --- a/test/__snapshots__/loader.test.js.snap +++ b/test/__snapshots__/loader.test.js.snap @@ -292,6 +292,60 @@ exports[`loader should prefer "mainFiles" over "mainFields" when the field conta exports[`loader should prefer "mainFiles" over "mainFields" when the field contains "js" file (node-sass) (scss): warnings 1`] = `Array []`; +exports[`loader should prefer "mainFiles" with extension over without (dart-sass) (sass): css 1`] = ` +".load-me { + color: red; +} + +.class { + color: blue; +}" +`; + +exports[`loader should prefer "mainFiles" with extension over without (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`loader should prefer "mainFiles" with extension over without (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`loader should prefer "mainFiles" with extension over without (dart-sass) (scss): css 1`] = ` +".load-me { + color: red; +} + +.class { + color: blue; +}" +`; + +exports[`loader should prefer "mainFiles" with extension over without (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`loader should prefer "mainFiles" with extension over without (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`loader should prefer "mainFiles" with extension over without (node-sass) (sass): css 1`] = ` +".load-me { + color: red; } + +.class { + color: blue; } +" +`; + +exports[`loader should prefer "mainFiles" with extension over without (node-sass) (sass): errors 1`] = `Array []`; + +exports[`loader should prefer "mainFiles" with extension over without (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`loader should prefer "mainFiles" with extension over without (node-sass) (scss): css 1`] = ` +".load-me { + color: red; } + +.class { + color: blue; } +" +`; + +exports[`loader should prefer "mainFiles" with extension over without (node-sass) (scss): errors 1`] = `Array []`; + +exports[`loader should prefer "mainFiles" with extension over without (node-sass) (scss): warnings 1`] = `Array []`; + exports[`loader should respect resolving directory with the "index" file from "process.cwd()" (dart-sass) (sass): css 1`] = ` ".dir-with-underscore-index { color: red; diff --git a/test/helpers/getCodeFromSass.js b/test/helpers/getCodeFromSass.js index 924da905..a0d06f2b 100644 --- a/test/helpers/getCodeFromSass.js +++ b/test/helpers/getCodeFromSass.js @@ -256,6 +256,10 @@ function getCodeFromSass(testId, options) { testFolder, 'node_modules/package-with-js-main-field/index.scss' ); + const pathToPackageWithIndex = path.resolve( + testFolder, + 'node_modules/package-with-index/_index.scss' + ); const pathToLanguage = isSass ? path.resolve(testFolder, 'sass/language.sass') : path.resolve(testFolder, 'scss/language.scss'); @@ -718,6 +722,7 @@ function getCodeFromSass(testId, options) { pathToPackageWithJsAndCssMainFiles ) .replace(/^~package-with-js-main-field/, pathToPackageWithJsMainField) + .replace(/^~package-with-index/, pathToPackageWithIndex) .replace(/^file:language/, pathToLanguage) .replace(/^~/, testNodeModules); } diff --git a/test/loader.test.js b/test/loader.test.js index 10c364e6..5af0847f 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -445,6 +445,28 @@ describe('loader', () => { expect(getErrors(stats)).toMatchSnapshot('errors'); }); + it(`should prefer "mainFiles" with extension over without (${implementationName}) (${syntax})`, async () => { + const testId = getTestId( + 'import-prefer-main-files-with-extension', + syntax + ); + const options = { + implementation: getImplementationByName(implementationName), + sassOptions: { + includePaths: ['node_modules/foundation-sites/scss'], + }, + }; + const compiler = getCompiler(testId, { loader: { options } }); + const stats = await compile(compiler); + const codeFromBundle = getCodeFromBundle(stats, compiler); + const codeFromSass = getCodeFromSass(testId, options); + + expect(codeFromBundle.css).toBe(codeFromSass.css); + expect(codeFromBundle.css).toMatchSnapshot('css'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + }); + it(`should work and use the "_index" file in package (${implementationName}) (${syntax})`, async () => { const testId = getTestId('import-_index', syntax); const options = { diff --git a/test/node_modules/package-with-index/_index.scss b/test/node_modules/package-with-index/_index.scss new file mode 100644 index 00000000..b11fa36b --- /dev/null +++ b/test/node_modules/package-with-index/_index.scss @@ -0,0 +1,3 @@ +.load-me { + color: red; +} diff --git a/test/node_modules/package-with-index/index b/test/node_modules/package-with-index/index new file mode 100644 index 00000000..e69de29b diff --git a/test/sass/import-prefer-main-files-with-extension.sass b/test/sass/import-prefer-main-files-with-extension.sass new file mode 100644 index 00000000..5f4dc6e3 --- /dev/null +++ b/test/sass/import-prefer-main-files-with-extension.sass @@ -0,0 +1,4 @@ +@import "~package-with-index" + +.class + color: blue diff --git a/test/scss/import-prefer-main-files-with-extension.scss b/test/scss/import-prefer-main-files-with-extension.scss new file mode 100644 index 00000000..7337418e --- /dev/null +++ b/test/scss/import-prefer-main-files-with-extension.scss @@ -0,0 +1,5 @@ +@import "~package-with-index"; + +.class { + color: blue; +}