sass-loader 10.2.1 → 11.1.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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <div align="center">
2
- <img height="100"
2
+ <img height="170"
3
3
  src="https://worldvectorlogo.com/logos/sass-1.svg">
4
4
  <a href="https://github.com/webpack/webpack">
5
5
  <img width="200" height="200"
@@ -31,9 +31,9 @@ npm install sass-loader sass webpack --save-dev
31
31
 
32
32
  This allows you to control the versions of all your dependencies, and to choose which Sass implementation to use.
33
33
 
34
- > ℹ️ We recommend using [Dart Sass](https://github.com/sass/dart-sass).
34
+ > ℹ️ We highly recommend using [Dart Sass](https://github.com/sass/dart-sass).
35
35
 
36
- > ⚠ [Node Sass](https://github.com/sass/node-sass) does not work with [Yarn PnP](https://classic.yarnpkg.com/en/docs/pnp/) feature.
36
+ > ⚠ [Node Sass](https://github.com/sass/node-sass) does not work with [Yarn PnP](https://classic.yarnpkg.com/en/docs/pnp/) feature and doesn't support [@use rule](https://sass-lang.com/documentation/at-rules/use).
37
37
 
38
38
  Chain the `sass-loader` with the [css-loader](https://github.com/webpack-contrib/css-loader) and the [style-loader](https://github.com/webpack-contrib/style-loader) to immediately apply all styles to the DOM or the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) to extract it into a separate file.
39
39
 
@@ -83,13 +83,23 @@ 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 can you remove it? The loader will first try to resolve `@import` as a relative path. If it cannot be resolved, then the loader will try to resolve `@import` inside [`node_modules`](https://webpack.js.org/configuration/resolve/#resolvemodules).
95
+
96
+ Prepending module paths with a `~` tells webpack to search through [`node_modules`](https://webpack.js.org/configuration/resolve/#resolvemodules).
87
97
 
88
98
  ```scss
89
99
  @import "~bootstrap";
90
100
  ```
91
101
 
92
- It's important to only prepend it with `~`, because `~/` resolves to the home directory.
102
+ It's important to prepend it with only `~`, because `~/` resolves to the home directory.
93
103
  Webpack needs to distinguish between `bootstrap` and `~bootstrap` because CSS and Sass files have no special syntax for importing relative files.
94
104
  Writing `@import "style.scss"` is the same as `@import "./style.scss";`
95
105
 
@@ -571,7 +581,7 @@ For production builds it's recommended to extract the CSS from your bundle being
571
581
 
572
582
  There are two possibilities to extract a style sheet from the bundle:
573
583
 
574
- - [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)
584
+ - [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin)
575
585
  - [extract-loader](https://github.com/peerigon/extract-loader) (simpler, but specialized on the css-loader's output)
576
586
 
577
587
  **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
@@ -3,24 +3,20 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getRenderFunctionFromSassImplementation = getRenderFunctionFromSassImplementation;
7
6
  exports.getSassImplementation = getSassImplementation;
8
7
  exports.getSassOptions = getSassOptions;
9
- exports.getWebpackImporter = getWebpackImporter;
10
8
  exports.getWebpackResolver = getWebpackResolver;
11
- exports.isSupportedFibers = isSupportedFibers;
9
+ exports.getWebpackImporter = getWebpackImporter;
10
+ exports.getRenderFunctionFromSassImplementation = getRenderFunctionFromSassImplementation;
12
11
  exports.normalizeSourceMap = normalizeSourceMap;
12
+ exports.isSupportedFibers = isSupportedFibers;
13
13
 
14
14
  var _url = _interopRequireDefault(require("url"));
15
15
 
16
16
  var _path = _interopRequireDefault(require("path"));
17
17
 
18
- var _semver = _interopRequireDefault(require("semver"));
19
-
20
18
  var _full = require("klona/full");
21
19
 
22
- var _loaderUtils = require("loader-utils");
23
-
24
20
  var _neoAsync = _interopRequireDefault(require("neo-async"));
25
21
 
26
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -78,32 +74,19 @@ function getSassImplementation(loaderContext, implementation) {
78
74
  return;
79
75
  }
80
76
 
81
- const [implementationName, version] = infoParts;
77
+ const [implementationName] = infoParts;
82
78
 
83
79
  if (implementationName === "dart-sass") {
84
- if (!_semver.default.satisfies(version, "^1.3.0")) {
85
- loaderContext.emitError(new Error(`Dart Sass version ${version} is incompatible with ^1.3.0.`));
86
- } // eslint-disable-next-line consistent-return
87
-
88
-
80
+ // eslint-disable-next-line consistent-return
89
81
  return resolvedImplementation;
90
82
  } else if (implementationName === "node-sass") {
91
- if (!_semver.default.satisfies(version, "^4.0.0 || ^5.0.0 || ^6.0.0")) {
92
- loaderContext.emitError(new Error(`Node Sass version ${version} is incompatible with ^4.0.0 || ^5.0.0 || ^6.0.0.`));
93
- } // eslint-disable-next-line consistent-return
94
-
95
-
83
+ // eslint-disable-next-line consistent-return
96
84
  return resolvedImplementation;
97
85
  }
98
86
 
99
87
  loaderContext.emitError(new Error(`Unknown Sass implementation "${implementationName}".`));
100
88
  }
101
89
 
102
- function isSupportedFibers() {
103
- const [nodeVersion] = process.versions.node.split(".");
104
- return Number(nodeVersion) < 16;
105
- }
106
-
107
90
  function isProductionLikeMode(loaderContext) {
108
91
  return loaderContext.mode === "production" || !loaderContext.mode;
109
92
  }
@@ -114,6 +97,11 @@ function proxyCustomImporters(importers, loaderContext) {
114
97
  return importer.apply(this, args);
115
98
  });
116
99
  }
100
+
101
+ function isSupportedFibers() {
102
+ const [nodeVersion] = process.versions.node.split(".");
103
+ return Number(nodeVersion) < 16;
104
+ }
117
105
  /**
118
106
  * Derives the sass options from the loader context and normalizes its values with sane defaults.
119
107
  *
@@ -193,7 +181,9 @@ async function getSassOptions(loaderContext, loaderOptions, content, implementat
193
181
  options.includePaths = [].concat(process.cwd()).concat( // We use `includePaths` in context for resolver, so it should be always absolute
194
182
  (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" ? ";" : ":") : []);
195
183
  return options;
196
- } // Examples:
184
+ }
185
+
186
+ const MODULE_REQUEST_REGEX = /^[^?]*~/; // Examples:
197
187
  // - ~package
198
188
  // - ~package/
199
189
  // - ~@org
@@ -201,8 +191,7 @@ async function getSassOptions(loaderContext, loaderOptions, content, implementat
201
191
  // - ~@org/package
202
192
  // - ~@org/package/
203
193
 
204
-
205
- const isModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;
194
+ const IS_MODULE_IMPORT = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;
206
195
  /**
207
196
  * When `sass`/`node-sass` tries to resolve an import, it uses a special algorithm.
208
197
  * Since the `sass-loader` uses webpack to resolve the modules, we need to simulate that algorithm.
@@ -219,12 +208,18 @@ const isModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+
219
208
  */
220
209
 
221
210
  function getPossibleRequests( // eslint-disable-next-line no-shadow
222
- url, forWebpackResolver = false, rootContext = false) {
223
- const request = (0, _loaderUtils.urlToRequest)(url, // Maybe it is server-relative URLs
224
- forWebpackResolver && rootContext); // In case there is module request, send this to webpack resolver
211
+ url, forWebpackResolver = false) {
212
+ let request = url; // In case there is module request, send this to webpack resolver
213
+
214
+ if (forWebpackResolver) {
215
+ if (MODULE_REQUEST_REGEX.test(url)) {
216
+ request = request.replace(MODULE_REQUEST_REGEX, "");
217
+ }
225
218
 
226
- if (forWebpackResolver && isModuleImport.test(url)) {
227
- return [...new Set([request, url])];
219
+ if (IS_MODULE_IMPORT.test(url)) {
220
+ request = request[request.length - 1] === "/" ? request : `${request}/`;
221
+ return [...new Set([request, url])];
222
+ }
228
223
  } // Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.
229
224
  // @see https://github.com/webpack-contrib/sass-loader/issues/167
230
225
 
@@ -279,12 +274,11 @@ const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;
279
274
  * @param {Object} implementation - The imported Sass implementation, both
280
275
  * `sass` (Dart Sass) and `node-sass` are supported.
281
276
  * @param {string[]} [includePaths] - The list of include paths passed to Sass.
282
- * @param {boolean} [rootContext] - The configured Webpack root context.
283
277
  *
284
278
  * @throws If a compatible Sass implementation cannot be found.
285
279
  */
286
280
 
287
- function getWebpackResolver(resolverFactory, implementation, includePaths = [], rootContext = false) {
281
+ function getWebpackResolver(resolverFactory, implementation, includePaths = []) {
288
282
  async function startResolving(resolutionMap) {
289
283
  if (resolutionMap.length === 0) {
290
284
  return Promise.reject();
@@ -330,16 +324,26 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [],
330
324
  mainFields: [],
331
325
  mainFiles: ["_index", "index"],
332
326
  modules: [],
333
- restrictions: [/\.((sa|sc|c)ss)$/i]
327
+ restrictions: [/\.((sa|sc|c)ss)$/i],
328
+ preferRelative: true
334
329
  }));
335
330
  const webpackResolve = promiseResolve(resolverFactory({
331
+ dependencyType: "sass",
336
332
  conditionNames: ["sass", "style"],
337
333
  mainFields: ["sass", "style", "main", "..."],
338
334
  mainFiles: ["_index", "index", "..."],
339
335
  extensions: [".sass", ".scss", ".css"],
340
- restrictions: [/\.((sa|sc|c)ss)$/i]
336
+ restrictions: [/\.((sa|sc|c)ss)$/i],
337
+ preferRelative: true
341
338
  }));
342
339
  return (context, request) => {
340
+ // See https://github.com/webpack/webpack/issues/12340
341
+ // Because `node-sass` calls our importer before `1. Filesystem imports relative to the base file.`
342
+ // custom importer may not return `{ file: '/path/to/name.ext' }` and therefore our `context` will be relative
343
+ if (!isDartSass && !_path.default.isAbsolute(context)) {
344
+ return Promise.reject();
345
+ }
346
+
343
347
  const originalRequest = request;
344
348
  const isFileScheme = originalRequest.slice(0, 5).toLowerCase() === "file:";
345
349
 
@@ -370,7 +374,7 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [],
370
374
  // 4. Filesystem imports relative to an `includePaths` path.
371
375
  // 5. Filesystem imports relative to a `SASS_PATH` path.
372
376
  //
373
- // Because `sass`/`node-sass` run custom importers before `3`, `4` and `5` points, we need to emulate this behavior to avoid wrong resolution.
377
+ // `sass` run custom importers before `3`, `4` and `5` points, we need to emulate this behavior to avoid wrong resolution.
374
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
375
379
 
376
380
  if (!isDartSass) {
@@ -391,7 +395,7 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [],
391
395
  }));
392
396
  }
393
397
 
394
- const webpackPossibleRequests = getPossibleRequests(request, true, rootContext);
398
+ const webpackPossibleRequests = getPossibleRequests(request, true);
395
399
  resolutionMap = resolutionMap.concat({
396
400
  resolve: webpackResolve,
397
401
  context: _path.default.dirname(context),
@@ -404,7 +408,7 @@ function getWebpackResolver(resolverFactory, implementation, includePaths = [],
404
408
  const matchCss = /\.css$/i;
405
409
 
406
410
  function getWebpackImporter(loaderContext, implementation, includePaths) {
407
- const resolve = getWebpackResolver(loaderContext.getResolve, implementation, includePaths, loaderContext.rootContext);
411
+ const resolve = getWebpackResolver(loaderContext.getResolve, implementation, includePaths);
408
412
  return (originalUrl, prev, done) => {
409
413
  resolve(prev, originalUrl).then(result => {
410
414
  // Add the result as dependency.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sass-loader",
3
- "version": "10.2.1",
3
+ "version": "11.1.1",
4
4
  "description": "Sass loader for webpack",
5
5
  "license": "MIT",
6
6
  "repository": "webpack-contrib/sass-loader",
@@ -31,9 +31,8 @@
31
31
  "test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
32
32
  "pretest": "npm run lint",
33
33
  "test": "npm run test:coverage",
34
- "prepare": "npm run build",
35
- "release": "standard-version",
36
- "defaults": "webpack-defaults"
34
+ "prepare": "husky install && npm run build",
35
+ "release": "standard-version"
37
36
  },
38
37
  "files": [
39
38
  "dist"
@@ -42,7 +41,7 @@
42
41
  "fibers": ">= 3.1.0",
43
42
  "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0",
44
43
  "sass": "^1.3.0",
45
- "webpack": "^4.36.0 || ^5.0.0"
44
+ "webpack": "^5.0.0"
46
45
  },
47
46
  "peerDependenciesMeta": {
48
47
  "node-sass": {
@@ -57,45 +56,43 @@
57
56
  },
58
57
  "dependencies": {
59
58
  "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"
59
+ "neo-async": "^2.6.2"
64
60
  },
65
61
  "devDependencies": {
66
- "@babel/cli": "^7.12.1",
67
- "@babel/core": "^7.12.3",
68
- "@babel/preset-env": "^7.12.1",
69
- "@commitlint/cli": "^11.0.0",
70
- "@commitlint/config-conventional": "^11.0.0",
71
- "@webpack-contrib/defaults": "^6.3.0",
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",
72
67
  "@webpack-contrib/eslint-config-webpack": "^3.0.0",
73
68
  "babel-jest": "^26.6.3",
74
69
  "bootstrap": "^4.5.3",
75
70
  "bootstrap-sass": "^3.4.1",
76
- "cross-env": "^7.0.2",
77
- "css-loader": "^5.0.1",
71
+ "cross-env": "^7.0.3",
72
+ "css-loader": "^5.2.4",
78
73
  "del": "^6.0.0",
79
74
  "del-cli": "^3.0.1",
80
- "enhanced-resolve": "^5.5.0",
81
- "eslint": "^7.13.0",
82
- "eslint-config-prettier": "^7.1.0",
75
+ "enhanced-resolve": "^5.8.0",
76
+ "eslint": "^7.26.0",
77
+ "eslint-config-prettier": "^8.3.0",
83
78
  "eslint-plugin-import": "^2.22.1",
84
79
  "fibers": "^5.0.0",
85
80
  "file-loader": "^6.2.0",
86
81
  "foundation-sites": "^6.6.3",
87
- "husky": "^4.3.0",
82
+ "husky": "^6.0.0",
88
83
  "jest": "^26.6.3",
89
- "lint-staged": "^10.5.1",
84
+ "lint-staged": "^11.0.0",
90
85
  "material-components-web": "^8.0.0",
91
- "memfs": "^3.2.0",
92
- "node-sass": "^6.0.1",
86
+ "memfs": "^3.2.2",
87
+ "node-sass": "^6.0.0",
88
+ "node-sass-glob-importer": "^5.3.2",
93
89
  "npm-run-all": "^4.1.5",
94
- "prettier": "^2.1.2",
95
- "sass": "^1.29.0",
96
- "standard-version": "^9.0.0",
90
+ "prettier": "^2.3.0",
91
+ "sass": "^1.32.12",
92
+ "semver": "^7.3.5",
93
+ "standard-version": "^9.3.0",
97
94
  "style-loader": "^2.0.0",
98
- "webpack": "^5.12.2"
95
+ "webpack": "^5.36.2"
99
96
  },
100
97
  "keywords": [
101
98
  "sass",