-
-
Notifications
You must be signed in to change notification settings - Fork 431
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Refactor resolving and simplify webpack config aliases (#479)
- Make it easier to alias modules via the webpack config - Make importsToResolve algorithm more readable BREAKING CHANGE: This slightly changes the resolving algorithm. Should not break in normal usage, but might break in complex configurations.
- Loading branch information
1 parent
6439cef
commit e0fde1a
Showing
11 changed files
with
73 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,60 @@ | ||
"use strict"; | ||
|
||
const path = require("path"); | ||
const utils = require("loader-utils"); | ||
|
||
// libsass uses this precedence when importing files without extension | ||
const extPrecedence = [".scss", ".sass", ".css"]; | ||
const matchModuleImport = /^~([^\/]+|@[^\/]+[\/][^\/]+)$/g; | ||
|
||
/** | ||
* When libsass 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. This function | ||
* returns an array of import paths to try. | ||
* returns an array of import paths to try. The first entry in the array is always the original url | ||
* to enable straight-forward webpack.config aliases. | ||
* | ||
* @param {string} request | ||
* @param {string} url | ||
* @returns {Array<string>} | ||
*/ | ||
function importsToResolve(request) { | ||
function importsToResolve(url) { | ||
const request = utils.urlToRequest(url); | ||
// Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot. | ||
// @see https://github.com/webpack-contrib/sass-loader/issues/167 | ||
const ext = path.extname(request); | ||
|
||
if (matchModuleImport.test(url)) { | ||
return [url, request]; | ||
} | ||
|
||
// libsass' import algorithm works like this: | ||
// In case there is no file extension... | ||
// - Prefer modules starting with '_'. | ||
// - File extension precedence: .scss, .sass, .css. | ||
|
||
// In case there is a file extension... | ||
// - If the file is a CSS-file, do not include it all, but just link it via @import url(). | ||
// - The exact file name must match (no auto-resolving of '_'-modules). | ||
if (ext === ".css") { | ||
return []; | ||
} | ||
if (ext === ".scss" || ext === ".sass") { | ||
return [url, request]; | ||
} | ||
|
||
// Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot. | ||
// @see https://github.com/webpack-contrib/sass-loader/issues/167 | ||
const ext = path.extname(request); | ||
// In case there is no file extension... | ||
// - Prefer modules starting with '_'. | ||
// - File extension precedence: .scss, .sass, .css. | ||
const basename = path.basename(request); | ||
const dirname = path.dirname(request); | ||
const startsWithUnderscore = basename.charAt(0) === "_"; | ||
const hasCssExt = ext === ".css"; | ||
const hasSassExt = ext === ".scss" || ext === ".sass"; | ||
|
||
// a module import is an identifier like 'bootstrap-sass' | ||
// We also need to check for dirname since it might also be a deep import like 'bootstrap-sass/something' | ||
let isModuleImport = request.charAt(0) !== "." && dirname === "."; | ||
|
||
if (dirname.charAt(0) === "@") { | ||
// Check whether it is a deep import from scoped npm package | ||
// (i.e. @pkg/foo/file), if so, process import as file import; | ||
// otherwise, if we import from root npm scoped package (i.e. @pkg/foo) | ||
// process import as a module import. | ||
isModuleImport = !(dirname.indexOf("/") > -1); | ||
|
||
if (basename.charAt(0) === "_") { | ||
return [ | ||
url, | ||
`${ request }.scss`, `${ request }.sass`, `${ request }.css` | ||
]; | ||
} | ||
|
||
return (isModuleImport && [request]) || // Do not modify module imports | ||
(hasCssExt && []) || // Do not import css files | ||
(hasSassExt && [request]) || // Do not modify imports with explicit extensions | ||
(startsWithUnderscore ? [] : extPrecedence) // Do not add underscore imports if there is already an underscore | ||
.map(ext => "_" + basename + ext) | ||
.concat( | ||
extPrecedence.map(ext => basename + ext) | ||
).map( | ||
file => dirname + "/" + file // No path.sep required here, because imports inside SASS are usually with / | ||
); | ||
const dirname = path.dirname(request); | ||
|
||
return [ | ||
url, | ||
`${ dirname }/_${ basename }.scss`, `${ dirname }/_${ basename }.sass`, `${ dirname }/_${ basename }.css`, | ||
`${ request }.scss`, `${ request }.sass`, `${ request }.css` | ||
]; | ||
} | ||
|
||
module.exports = importsToResolve; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
a | ||
color: red | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@import path-to-alias |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
// Special behavior of node-sass/libsass with CSS-files | ||
// 1. CSS-files are not included, but linked with @import url(path/to/css) | ||
@import ../node_modules/css/some-css-module.css | ||
@import ~css/some-css-module.css | ||
// 2. It does not matter whether the CSS-file exists or not, the file is just linked | ||
@import ./does/not/exist.css | ||
// 3. When the .css extension is missing, the file is included just like scss | ||
@import ../node_modules/css/some-css-module | ||
@import ~css/some-css-module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
a { | ||
color: red; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@import 'path-to-alias'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters