sass-loader 11.1.1 → 12.0.0

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.
Files changed (2) hide show
  1. package/dist/utils.js +69 -23
  2. package/package.json +17 -16
package/dist/utils.js CHANGED
@@ -40,9 +40,7 @@ function getDefaultSassImplementation() {
40
40
  return require(sassImplPkg);
41
41
  }
42
42
  /**
43
- * @public
44
- * This function is not Webpack-specific and can be used by tools wishing to
45
- * mimic `sass-loader`'s behaviour, so its signature should not be changed.
43
+ * This function is not Webpack-specific and can be used by tools wishing to mimic `sass-loader`'s behaviour, so its signature should not be changed.
46
44
  */
47
45
 
48
46
 
@@ -86,6 +84,11 @@ function getSassImplementation(loaderContext, implementation) {
86
84
 
87
85
  loaderContext.emitError(new Error(`Unknown Sass implementation "${implementationName}".`));
88
86
  }
87
+ /**
88
+ * @param {any} loaderContext
89
+ * @returns {boolean}
90
+ */
91
+
89
92
 
90
93
  function isProductionLikeMode(loaderContext) {
91
94
  return loaderContext.mode === "production" || !loaderContext.mode;
@@ -93,8 +96,10 @@ function isProductionLikeMode(loaderContext) {
93
96
 
94
97
  function proxyCustomImporters(importers, loaderContext) {
95
98
  return [].concat(importers).map(importer => function proxyImporter(...args) {
96
- this.webpackLoaderContext = loaderContext;
97
- return importer.apply(this, args);
99
+ const self = { ...this,
100
+ webpackLoaderContext: loaderContext
101
+ };
102
+ return importer.apply(self, args);
98
103
  });
99
104
  }
100
105
 
@@ -203,12 +208,12 @@ const IS_MODULE_IMPORT = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/
203
208
  *
204
209
  * @param {string} url
205
210
  * @param {boolean} forWebpackResolver
206
- * @param {string} rootContext
211
+ * @param {boolean} fromImport
207
212
  * @returns {Array<string>}
208
213
  */
209
214
 
210
215
  function getPossibleRequests( // eslint-disable-next-line no-shadow
211
- url, forWebpackResolver = false) {
216
+ url, forWebpackResolver = false, fromImport = false) {
212
217
  let request = url; // In case there is module request, send this to webpack resolver
213
218
 
214
219
  if (forWebpackResolver) {
@@ -224,7 +229,7 @@ url, forWebpackResolver = false) {
224
229
  // @see https://github.com/webpack-contrib/sass-loader/issues/167
225
230
 
226
231
 
227
- const ext = _path.default.extname(request).toLowerCase(); // Because @import is also defined in CSS, Sass needs a way of compiling plain CSS @imports without trying to import the files at compile time.
232
+ const extension = _path.default.extname(request).toLowerCase(); // Because @import is also defined in CSS, Sass needs a way of compiling plain CSS @imports without trying to import the files at compile time.
228
233
  // To accomplish this, and to ensure SCSS is as much of a superset of CSS as possible, Sass will compile any @imports with the following characteristics to plain CSS imports:
229
234
  // - imports where the URL ends with .css.
230
235
  // - imports where the URL begins http:// or https://.
@@ -234,15 +239,19 @@ url, forWebpackResolver = false) {
234
239
  // The `node-sass` package sends `@import` ending on `.css` to importer, it is bug, so we skip resolve
235
240
 
236
241
 
237
- if (ext === ".css") {
242
+ if (extension === ".css") {
238
243
  return [];
239
244
  }
240
245
 
241
246
  const dirname = _path.default.dirname(request);
242
247
 
248
+ const normalizedDirname = dirname === "." ? "" : `${dirname}/`;
249
+
243
250
  const basename = _path.default.basename(request);
244
251
 
245
- return [...new Set([`${dirname}/_${basename}`, request].concat(forWebpackResolver ? [`${_path.default.dirname(url)}/_${basename}`, url] : []))];
252
+ const basenameWithoutExtension = _path.default.basename(request, extension);
253
+
254
+ return [...new Set([].concat(fromImport ? [`${normalizedDirname}_${basenameWithoutExtension}.import${extension}`, `${normalizedDirname}${basenameWithoutExtension}.import${extension}`] : []).concat([`${normalizedDirname}_${basename}`, `${normalizedDirname}${basename}`]).concat(forWebpackResolver ? [url] : []))];
246
255
  }
247
256
 
248
257
  function promiseResolve(callbackResolve) {
@@ -313,8 +322,16 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [])
313
322
  }
314
323
  }
315
324
 
316
- const isDartSass = implementation.info.includes("dart-sass");
317
- const sassResolve = promiseResolve(resolverFactory({
325
+ const isDartSass = implementation.info.includes("dart-sass"); // We only have one difference with the built-in sass resolution logic and out resolution logic:
326
+ // First, we look at the files starting with `_`, then without `_` (i.e. `_name.sass`, `_name.scss`, `_name.css`, `name.sass`, `name.scss`, `name.css`),
327
+ // although `sass` look together by extensions (i.e. `_name.sass`/`name.sass`/`_name.scss`/`name.scss`/`_name.css`/`name.css`).
328
+ // It shouldn't be a problem because `sass` throw errors:
329
+ // - on having `_name.sass` and `name.sass` (extension can be `sass`, `scss` or `css`) in the same directory
330
+ // - on having `_name.sass` and `_name.scss` in the same directory
331
+ //
332
+ // Also `sass` prefer `sass`/`scss` over `css`.
333
+
334
+ const sassModuleResolve = promiseResolve(resolverFactory({
318
335
  alias: [],
319
336
  aliasFields: [],
320
337
  conditionNames: [],
@@ -327,7 +344,20 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [])
327
344
  restrictions: [/\.((sa|sc|c)ss)$/i],
328
345
  preferRelative: true
329
346
  }));
330
- const webpackResolve = promiseResolve(resolverFactory({
347
+ const sassImportResolve = promiseResolve(resolverFactory({
348
+ alias: [],
349
+ aliasFields: [],
350
+ conditionNames: [],
351
+ descriptionFiles: [],
352
+ extensions: [".sass", ".scss", ".css"],
353
+ exportsFields: [],
354
+ mainFields: [],
355
+ mainFiles: ["_index.import", "_index", "index.import", "index"],
356
+ modules: [],
357
+ restrictions: [/\.((sa|sc|c)ss)$/i],
358
+ preferRelative: true
359
+ }));
360
+ const webpackModuleResolve = promiseResolve(resolverFactory({
331
361
  dependencyType: "sass",
332
362
  conditionNames: ["sass", "style"],
333
363
  mainFields: ["sass", "style", "main", "..."],
@@ -336,7 +366,16 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [])
336
366
  restrictions: [/\.((sa|sc|c)ss)$/i],
337
367
  preferRelative: true
338
368
  }));
339
- return (context, request) => {
369
+ const webpackImportResolve = promiseResolve(resolverFactory({
370
+ dependencyType: "sass",
371
+ conditionNames: ["sass", "style"],
372
+ mainFields: ["sass", "style", "main", "..."],
373
+ mainFiles: ["_index.import", "_index", "index.import", "index", "..."],
374
+ extensions: [".sass", ".scss", ".css"],
375
+ restrictions: [/\.((sa|sc|c)ss)$/i],
376
+ preferRelative: true
377
+ }));
378
+ return (context, request, fromImport) => {
340
379
  // See https://github.com/webpack/webpack/issues/12340
341
380
  // Because `node-sass` calls our importer before `1. Filesystem imports relative to the base file.`
342
381
  // custom importer may not return `{ file: '/path/to/name.ext' }` and therefore our `context` will be relative
@@ -375,11 +414,11 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [])
375
414
  // 5. Filesystem imports relative to a `SASS_PATH` path.
376
415
  //
377
416
  // `sass` run custom importers before `3`, `4` and `5` points, we need to emulate this behavior to avoid wrong resolution.
378
- const sassPossibleRequests = getPossibleRequests(request); // `node-sass` calls our importer before `1. Filesystem imports relative to the base file.`, so we need emulate this too
417
+ const sassPossibleRequests = getPossibleRequests(request, false, fromImport); // `node-sass` calls our importer before `1. Filesystem imports relative to the base file.`, so we need emulate this too
379
418
 
380
419
  if (!isDartSass) {
381
420
  resolutionMap = resolutionMap.concat({
382
- resolve: sassResolve,
421
+ resolve: fromImport ? sassImportResolve : sassModuleResolve,
383
422
  context: _path.default.dirname(context),
384
423
  possibleRequests: sassPossibleRequests
385
424
  });
@@ -388,16 +427,16 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [])
388
427
  resolutionMap = resolutionMap.concat( // eslint-disable-next-line no-shadow
389
428
  includePaths.map(context => {
390
429
  return {
391
- resolve: sassResolve,
430
+ resolve: fromImport ? sassImportResolve : sassModuleResolve,
392
431
  context,
393
432
  possibleRequests: sassPossibleRequests
394
433
  };
395
434
  }));
396
435
  }
397
436
 
398
- const webpackPossibleRequests = getPossibleRequests(request, true);
437
+ const webpackPossibleRequests = getPossibleRequests(request, true, fromImport);
399
438
  resolutionMap = resolutionMap.concat({
400
- resolve: webpackResolve,
439
+ resolve: fromImport ? webpackImportResolve : webpackModuleResolve,
401
440
  context: _path.default.dirname(context),
402
441
  possibleRequests: webpackPossibleRequests
403
442
  });
@@ -405,19 +444,22 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [])
405
444
  };
406
445
  }
407
446
 
408
- const matchCss = /\.css$/i;
447
+ const MATCH_CSS = /\.css$/i;
409
448
 
410
449
  function getWebpackImporter(loaderContext, implementation, includePaths) {
411
450
  const resolve = getWebpackResolver(loaderContext.getResolve, implementation, includePaths);
412
- return (originalUrl, prev, done) => {
413
- resolve(prev, originalUrl).then(result => {
451
+ return function importer(originalUrl, prev, done) {
452
+ const {
453
+ fromImport
454
+ } = this;
455
+ resolve(prev, originalUrl, fromImport).then(result => {
414
456
  // Add the result as dependency.
415
457
  // Although we're also using stats.includedFiles, this might come in handy when an error occurs.
416
458
  // In this case, we don't get stats.includedFiles from node-sass/sass.
417
459
  loaderContext.addDependency(_path.default.normalize(result)); // By removing the CSS file extension, we trigger node-sass to include the CSS file instead of just linking it.
418
460
 
419
461
  done({
420
- file: result.replace(matchCss, "")
462
+ file: result.replace(MATCH_CSS, "")
421
463
  });
422
464
  }) // Catch all resolving errors, return the original file and pass responsibility back to other custom importers
423
465
  .catch(() => {
@@ -455,6 +497,10 @@ function getRenderFunctionFromSassImplementation(implementation) {
455
497
  }
456
498
 
457
499
  const ABSOLUTE_SCHEME = /^[A-Za-z0-9+\-.]+:/;
500
+ /**
501
+ * @param {string} source
502
+ * @returns {"absolute" | "scheme-relative" | "path-absolute" | "path-absolute"}
503
+ */
458
504
 
459
505
  function getURLType(source) {
460
506
  if (source[0] === "/") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sass-loader",
3
- "version": "11.1.1",
3
+ "version": "12.0.0",
4
4
  "description": "Sass loader for webpack",
5
5
  "license": "MIT",
6
6
  "repository": "webpack-contrib/sass-loader",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "main": "dist/cjs.js",
15
15
  "engines": {
16
- "node": ">= 10.13.0"
16
+ "node": ">= 12.13.0"
17
17
  },
18
18
  "scripts": {
19
19
  "start": "npm run build -- -w",
@@ -59,28 +59,29 @@
59
59
  "neo-async": "^2.6.2"
60
60
  },
61
61
  "devDependencies": {
62
- "@babel/cli": "^7.13.16",
63
- "@babel/core": "^7.14.0",
64
- "@babel/preset-env": "^7.14.1",
65
- "@commitlint/cli": "^12.1.1",
66
- "@commitlint/config-conventional": "^12.1.1",
62
+ "@babel/cli": "^7.14.3",
63
+ "@babel/core": "^7.14.3",
64
+ "@babel/preset-env": "^7.14.2",
65
+ "@commitlint/cli": "^12.1.4",
66
+ "@commitlint/config-conventional": "^12.1.4",
67
67
  "@webpack-contrib/eslint-config-webpack": "^3.0.0",
68
- "babel-jest": "^26.6.3",
69
- "bootstrap": "^4.5.3",
68
+ "babel-jest": "^27.0.1",
70
69
  "bootstrap-sass": "^3.4.1",
70
+ "bootstrap-v4": "npm:bootstrap@^4.5.3",
71
+ "bootstrap-v5": "npm:bootstrap@^5.0.1",
71
72
  "cross-env": "^7.0.3",
72
- "css-loader": "^5.2.4",
73
+ "css-loader": "^5.2.6",
73
74
  "del": "^6.0.0",
74
75
  "del-cli": "^3.0.1",
75
- "enhanced-resolve": "^5.8.0",
76
- "eslint": "^7.26.0",
76
+ "enhanced-resolve": "^5.8.2",
77
+ "eslint": "^7.27.0",
77
78
  "eslint-config-prettier": "^8.3.0",
78
- "eslint-plugin-import": "^2.22.1",
79
+ "eslint-plugin-import": "^2.23.3",
79
80
  "fibers": "^5.0.0",
80
81
  "file-loader": "^6.2.0",
81
82
  "foundation-sites": "^6.6.3",
82
83
  "husky": "^6.0.0",
83
- "jest": "^26.6.3",
84
+ "jest": "^27.0.1",
84
85
  "lint-staged": "^11.0.0",
85
86
  "material-components-web": "^8.0.0",
86
87
  "memfs": "^3.2.2",
@@ -88,11 +89,11 @@
88
89
  "node-sass-glob-importer": "^5.3.2",
89
90
  "npm-run-all": "^4.1.5",
90
91
  "prettier": "^2.3.0",
91
- "sass": "^1.32.12",
92
+ "sass": "^1.34.0",
92
93
  "semver": "^7.3.5",
93
94
  "standard-version": "^9.3.0",
94
95
  "style-loader": "^2.0.0",
95
- "webpack": "^5.36.2"
96
+ "webpack": "^5.37.1"
96
97
  },
97
98
  "keywords": [
98
99
  "sass",