sass-loader 10.1.1 → 11.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [11.0.1](https://github.com/webpack-contrib/sass-loader/compare/v11.0.0...v11.0.1) (2021-02-08)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * compatibility with custom importers for `node-sass` ([#927](https://github.com/webpack-contrib/sass-loader/issues/927)) ([af5a072](https://github.com/webpack-contrib/sass-loader/commit/af5a072c5170f96f3d0643dec658248d98f65ff7))
11
+
12
+ ## [11.0.0](https://github.com/webpack-contrib/sass-loader/compare/v10.1.1...v11.0.0) (2021-02-05)
13
+
14
+
15
+ ### Notes
16
+
17
+ * using `~` is deprecated and can be removed from your code (**we recommend it**), but we still support it for historical reasons.
18
+
19
+ Why you can removed it?
20
+ The loader will first try to resolve `@import`/`@use` as relative, if it cannot be resolved, the loader will try to resolve `@import`/`@use` inside [`node_modules`](https://webpack.js.org/configuration/resolve/#resolve-modules).
21
+
22
+ ### ⚠ BREAKING CHANGES
23
+
24
+ * minimum supported `webpack` version is `5`
25
+
26
+ ### Features
27
+
28
+ * supported the [`resolve.byDependency`](https://webpack.js.org/configuration/resolve/#resolvebydependency) option, you can setup `{ resolve: { byDependency: { sass: { mainFiles: ['custom', '...'] } } } }`
29
+
5
30
  ### [10.1.1](https://github.com/webpack-contrib/sass-loader/compare/v10.1.0...v10.1.1) (2021-01-11)
6
31
 
7
32
 
package/README.md CHANGED
@@ -83,7 +83,16 @@ Finally run `webpack` via your preferred method.
83
83
 
84
84
  Webpack provides an [advanced mechanism to resolve files](https://webpack.js.org/concepts/module-resolution/).
85
85
 
86
- The `sass-loader` uses Sass's custom importer feature to pass all queries to the Webpack resolving engine. Thus you can import your Sass modules from `node_modules`. Just prepend them with a `~` to tell Webpack that this is not a relative import:
86
+ The `sass-loader` uses Sass's custom importer feature to pass all queries to the Webpack resolving engine.
87
+ Thus you can import your Sass modules from `node_modules`.
88
+
89
+ ```scss
90
+ @import "bootstrap";
91
+ ```
92
+
93
+ Using `~` is deprecated and can be removed from your code (**we recommend it**), but we still support it for historical reasons.
94
+ Why you can removed it? The loader will first try to resolve `@import` as relative, if it cannot be resolved, the loader will try to resolve `@import` inside [`node_modules`](https://webpack.js.org/configuration/resolve/#resolve-modules).
95
+ Just prepend them with a `~` which tells webpack to look up the [`modules`](https://webpack.js.org/configuration/resolve/#resolve-modules).
87
96
 
88
97
  ```scss
89
98
  @import "~bootstrap";
@@ -569,7 +578,7 @@ For production builds it's recommended to extract the CSS from your bundle being
569
578
 
570
579
  There are two possibilities to extract a style sheet from the bundle:
571
580
 
572
- - [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) (use this, when using webpack 4 configuration. Works in all use-cases)
581
+ - [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin)
573
582
  - [extract-loader](https://github.com/peerigon/extract-loader) (simpler, but specialized on the css-loader's output)
574
583
 
575
584
  **webpack.config.js**
package/dist/index.js CHANGED
@@ -7,10 +7,6 @@ exports.default = void 0;
7
7
 
8
8
  var _path = _interopRequireDefault(require("path"));
9
9
 
10
- var _schemaUtils = require("schema-utils");
11
-
12
- var _loaderUtils = require("loader-utils");
13
-
14
10
  var _options = _interopRequireDefault(require("./options.json"));
15
11
 
16
12
  var _utils = require("./utils");
@@ -26,11 +22,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
26
22
  * @param {string} content
27
23
  */
28
24
  async function loader(content) {
29
- const options = (0, _loaderUtils.getOptions)(this);
30
- (0, _schemaUtils.validate)(_options.default, options, {
31
- name: "Sass Loader",
32
- baseDataPath: "options"
33
- });
25
+ const options = this.getOptions(_options.default);
34
26
  const callback = this.async();
35
27
  const implementation = (0, _utils.getSassImplementation)(this, options.implementation);
36
28
 
package/dist/options.json CHANGED
@@ -1,4 +1,5 @@
1
1
  {
2
+ "title": "Sass Loader options",
2
3
  "type": "object",
3
4
  "properties": {
4
5
  "implementation": {
package/dist/utils.js CHANGED
@@ -14,12 +14,8 @@ var _url = _interopRequireDefault(require("url"));
14
14
 
15
15
  var _path = _interopRequireDefault(require("path"));
16
16
 
17
- var _semver = _interopRequireDefault(require("semver"));
18
-
19
17
  var _full = require("klona/full");
20
18
 
21
- var _loaderUtils = require("loader-utils");
22
-
23
19
  var _neoAsync = _interopRequireDefault(require("neo-async"));
24
20
 
25
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -77,21 +73,13 @@ function getSassImplementation(loaderContext, implementation) {
77
73
  return;
78
74
  }
79
75
 
80
- const [implementationName, version] = infoParts;
76
+ const [implementationName] = infoParts;
81
77
 
82
78
  if (implementationName === "dart-sass") {
83
- if (!_semver.default.satisfies(version, "^1.3.0")) {
84
- loaderContext.emitError(new Error(`Dart Sass version ${version} is incompatible with ^1.3.0.`));
85
- } // eslint-disable-next-line consistent-return
86
-
87
-
79
+ // eslint-disable-next-line consistent-return
88
80
  return resolvedImplementation;
89
81
  } else if (implementationName === "node-sass") {
90
- if (!_semver.default.satisfies(version, "^4.0.0 || ^5.0.0")) {
91
- loaderContext.emitError(new Error(`Node Sass version ${version} is incompatible with ^4.0.0 || ^5.0.0.`));
92
- } // eslint-disable-next-line consistent-return
93
-
94
-
82
+ // eslint-disable-next-line consistent-return
95
83
  return resolvedImplementation;
96
84
  }
97
85
 
@@ -187,7 +175,9 @@ async function getSassOptions(loaderContext, loaderOptions, content, implementat
187
175
  options.includePaths = [].concat(process.cwd()).concat( // We use `includePaths` in context for resolver, so it should be always absolute
188
176
  (options.includePaths || []).map(includePath => _path.default.isAbsolute(includePath) ? includePath : _path.default.join(process.cwd(), includePath))).concat(process.env.SASS_PATH ? process.env.SASS_PATH.split(process.platform === "win32" ? ";" : ":") : []);
189
177
  return options;
190
- } // Examples:
178
+ }
179
+
180
+ const MODULE_REQUEST_REGEX = /^[^?]*~/; // Examples:
191
181
  // - ~package
192
182
  // - ~package/
193
183
  // - ~@org
@@ -195,8 +185,7 @@ async function getSassOptions(loaderContext, loaderOptions, content, implementat
195
185
  // - ~@org/package
196
186
  // - ~@org/package/
197
187
 
198
-
199
- const isModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;
188
+ const IS_MODULE_IMPORT = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;
200
189
  /**
201
190
  * When `sass`/`node-sass` tries to resolve an import, it uses a special algorithm.
202
191
  * Since the `sass-loader` uses webpack to resolve the modules, we need to simulate that algorithm.
@@ -213,12 +202,18 @@ const isModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+
213
202
  */
214
203
 
215
204
  function getPossibleRequests( // eslint-disable-next-line no-shadow
216
- url, forWebpackResolver = false, rootContext = false) {
217
- const request = (0, _loaderUtils.urlToRequest)(url, // Maybe it is server-relative URLs
218
- forWebpackResolver && rootContext); // In case there is module request, send this to webpack resolver
205
+ url, forWebpackResolver = false) {
206
+ let request = url; // In case there is module request, send this to webpack resolver
207
+
208
+ if (forWebpackResolver) {
209
+ if (MODULE_REQUEST_REGEX.test(url)) {
210
+ request = request.replace(MODULE_REQUEST_REGEX, "");
211
+ }
219
212
 
220
- if (forWebpackResolver && isModuleImport.test(url)) {
221
- return [...new Set([request, url])];
213
+ if (IS_MODULE_IMPORT.test(url)) {
214
+ request = request[request.length - 1] === "/" ? request : `${request}/`;
215
+ return [...new Set([request, url])];
216
+ }
222
217
  } // Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.
223
218
  // @see https://github.com/webpack-contrib/sass-loader/issues/167
224
219
 
@@ -273,12 +268,11 @@ const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;
273
268
  * @param {Object} implementation - The imported Sass implementation, both
274
269
  * `sass` (Dart Sass) and `node-sass` are supported.
275
270
  * @param {string[]} [includePaths] - The list of include paths passed to Sass.
276
- * @param {boolean} [rootContext] - The configured Webpack root context.
277
271
  *
278
272
  * @throws If a compatible Sass implementation cannot be found.
279
273
  */
280
274
 
281
- function getWebpackResolver(resolverFactory, implementation, includePaths = [], rootContext = false) {
275
+ function getWebpackResolver(resolverFactory, implementation, includePaths = []) {
282
276
  async function startResolving(resolutionMap) {
283
277
  if (resolutionMap.length === 0) {
284
278
  return Promise.reject();
@@ -324,16 +318,26 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [],
324
318
  mainFields: [],
325
319
  mainFiles: ["_index", "index"],
326
320
  modules: [],
327
- restrictions: [/\.((sa|sc|c)ss)$/i]
321
+ restrictions: [/\.((sa|sc|c)ss)$/i],
322
+ preferRelative: true
328
323
  }));
329
324
  const webpackResolve = promiseResolve(resolverFactory({
325
+ dependencyType: "sass",
330
326
  conditionNames: ["sass", "style"],
331
327
  mainFields: ["sass", "style", "main", "..."],
332
328
  mainFiles: ["_index", "index", "..."],
333
329
  extensions: [".sass", ".scss", ".css"],
334
- restrictions: [/\.((sa|sc|c)ss)$/i]
330
+ restrictions: [/\.((sa|sc|c)ss)$/i],
331
+ preferRelative: true
335
332
  }));
336
333
  return (context, request) => {
334
+ // See https://github.com/webpack/webpack/issues/12340
335
+ // Because `node-sass` calls our importer before `1. Filesystem imports relative to the base file.`
336
+ // custom importer may not return `{ file: '/path/to/name.ext' }` and therefore our `context` will be relative
337
+ if (!isDartSass && !_path.default.isAbsolute(context)) {
338
+ return Promise.reject();
339
+ }
340
+
337
341
  const originalRequest = request;
338
342
  const isFileScheme = originalRequest.slice(0, 5).toLowerCase() === "file:";
339
343
 
@@ -364,7 +368,7 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [],
364
368
  // 4. Filesystem imports relative to an `includePaths` path.
365
369
  // 5. Filesystem imports relative to a `SASS_PATH` path.
366
370
  //
367
- // Because `sass`/`node-sass` run custom importers before `3`, `4` and `5` points, we need to emulate this behavior to avoid wrong resolution.
371
+ // `sass` run custom importers before `3`, `4` and `5` points, we need to emulate this behavior to avoid wrong resolution.
368
372
  const sassPossibleRequests = getPossibleRequests(request); // `node-sass` calls our importer before `1. Filesystem imports relative to the base file.`, so we need emulate this too
369
373
 
370
374
  if (!isDartSass) {
@@ -385,7 +389,7 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [],
385
389
  }));
386
390
  }
387
391
 
388
- const webpackPossibleRequests = getPossibleRequests(request, true, rootContext);
392
+ const webpackPossibleRequests = getPossibleRequests(request, true);
389
393
  resolutionMap = resolutionMap.concat({
390
394
  resolve: webpackResolve,
391
395
  context: _path.default.dirname(context),
@@ -398,7 +402,7 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [],
398
402
  const matchCss = /\.css$/i;
399
403
 
400
404
  function getWebpackImporter(loaderContext, implementation, includePaths) {
401
- const resolve = getWebpackResolver(loaderContext.getResolve, implementation, includePaths, loaderContext.rootContext);
405
+ const resolve = getWebpackResolver(loaderContext.getResolve, implementation, includePaths);
402
406
  return (originalUrl, prev, done) => {
403
407
  resolve(prev, originalUrl).then(result => {
404
408
  // Add the result as dependency.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sass-loader",
3
- "version": "10.1.1",
3
+ "version": "11.0.1",
4
4
  "description": "Sass loader for webpack",
5
5
  "license": "MIT",
6
6
  "repository": "webpack-contrib/sass-loader",
@@ -39,10 +39,10 @@
39
39
  "dist"
40
40
  ],
41
41
  "peerDependencies": {
42
- "webpack": "^4.36.0 || ^5.0.0",
42
+ "fibers": ">= 3.1.0",
43
43
  "node-sass": "^4.0.0 || ^5.0.0",
44
44
  "sass": "^1.3.0",
45
- "fibers": ">= 3.1.0"
45
+ "webpack": "^5.0.0"
46
46
  },
47
47
  "peerDependenciesMeta": {
48
48
  "node-sass": {
@@ -57,15 +57,12 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "klona": "^2.0.4",
60
- "loader-utils": "^2.0.0",
61
- "neo-async": "^2.6.2",
62
- "schema-utils": "^3.0.0",
63
- "semver": "^7.3.2"
60
+ "neo-async": "^2.6.2"
64
61
  },
65
62
  "devDependencies": {
66
- "@babel/cli": "^7.12.1",
67
- "@babel/core": "^7.12.3",
68
- "@babel/preset-env": "^7.12.1",
63
+ "@babel/cli": "^7.12.10",
64
+ "@babel/core": "^7.12.10",
65
+ "@babel/preset-env": "^7.12.11",
69
66
  "@commitlint/cli": "^11.0.0",
70
67
  "@commitlint/config-conventional": "^11.0.0",
71
68
  "@webpack-contrib/defaults": "^6.3.0",
@@ -73,7 +70,7 @@
73
70
  "babel-jest": "^26.6.3",
74
71
  "bootstrap": "^4.5.3",
75
72
  "bootstrap-sass": "^3.4.1",
76
- "cross-env": "^7.0.2",
73
+ "cross-env": "^7.0.3",
77
74
  "css-loader": "^5.0.1",
78
75
  "del": "^6.0.0",
79
76
  "del-cli": "^3.0.1",
@@ -84,18 +81,20 @@
84
81
  "fibers": "^5.0.0",
85
82
  "file-loader": "^6.2.0",
86
83
  "foundation-sites": "^6.6.3",
87
- "husky": "^4.3.0",
84
+ "husky": "^4.3.6",
88
85
  "jest": "^26.6.3",
89
- "lint-staged": "^10.5.1",
86
+ "lint-staged": "^10.5.4",
90
87
  "material-components-web": "^8.0.0",
91
88
  "memfs": "^3.2.0",
92
89
  "node-sass": "^5.0.0",
90
+ "node-sass-glob-importer": "^5.3.2",
93
91
  "npm-run-all": "^4.1.5",
94
- "prettier": "^2.1.2",
95
- "sass": "^1.29.0",
96
- "standard-version": "^9.0.0",
92
+ "prettier": "^2.2.1",
93
+ "sass": "^1.32.0",
94
+ "semver": "^7.3.4",
95
+ "standard-version": "^9.1.0",
97
96
  "style-loader": "^2.0.0",
98
- "webpack": "^5.12.2"
97
+ "webpack": "^5.21.2"
99
98
  },
100
99
  "keywords": [
101
100
  "sass",