sass-loader 7.1.0 → 8.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.
package/package.json CHANGED
@@ -1,71 +1,105 @@
1
1
  {
2
2
  "name": "sass-loader",
3
- "version": "7.1.0",
3
+ "version": "8.0.0",
4
4
  "description": "Sass loader for webpack",
5
- "author": "J. Tangelder",
6
5
  "license": "MIT",
7
- "main": "lib/loader.js",
6
+ "repository": "webpack-contrib/sass-loader",
7
+ "author": "J. Tangelder",
8
+ "homepage": "https://github.com/webpack-contrib/sass-loader",
9
+ "bugs": "https://github.com/webpack-contrib/sass-loader/issues",
10
+ "main": "dist/cjs.js",
11
+ "engines": {
12
+ "node": ">= 8.9.0"
13
+ },
14
+ "scripts": {
15
+ "start": "npm run build -- -w",
16
+ "prebuild": "npm run clean",
17
+ "build": "cross-env NODE_ENV=production babel src -d dist --ignore \"src/**/*.test.js\" --copy-files",
18
+ "clean": "del-cli dist",
19
+ "commitlint": "commitlint --from=master",
20
+ "lint:prettier": "prettier \"{**/*,*}.{js,json,md,yml,css}\" --list-different",
21
+ "lint:js": "eslint --cache src test",
22
+ "lint": "npm-run-all -l -p \"lint:**\"",
23
+ "prepare": "npm run build",
24
+ "release": "standard-version",
25
+ "security": "npm audit",
26
+ "test:only": "cross-env NODE_ENV=test jest",
27
+ "test:watch": "cross-env NODE_ENV=test jest --watch",
28
+ "test:manual": "npm run build && webpack-dev-server test/manual/src/index.js --open --config test/manual/webpack.config.js",
29
+ "test:coverage": "cross-env NODE_ENV=test jest --collectCoverageFrom=\"src/**/*.js\" --coverage",
30
+ "pretest": "npm run lint",
31
+ "test": "cross-env NODE_ENV=test npm run test:coverage",
32
+ "defaults": "webpack-defaults"
33
+ },
8
34
  "files": [
9
- "lib"
35
+ "dist"
10
36
  ],
11
- "scripts": {
12
- "appveyor:test": "npm test",
13
- "create-spec": "node test/tools/runCreateSpec.js",
14
- "lint": "eslint lib test",
15
- "test": "nyc --all mocha -R spec -t 10000",
16
- "test-bootstrap-sass": "webpack-dev-server --config test/bootstrapSass/webpack.config.js --content-base ./test/bootstrapSass",
17
- "test-source-map": "webpack-dev-server --config test/sourceMap/webpack.config.js --content-base ./test/sourceMap --inline",
18
- "test-watch": "webpack --config test/watch/webpack.config.js",
19
- "test-extract-text": "webpack --config test/extractText/webpack.config.js",
20
- "test-hmr": "webpack-dev-server --config test/hmr/webpack.config.js --content-base ./test/hmr --hot --inline",
21
- "travis:lint": "npm run lint",
22
- "travis:test": "npm run test",
23
- "travis:coverage": "npm run test",
24
- "pretest": "npm run create-spec",
25
- "posttest": "npm run lint",
26
- "release": "standard-version"
37
+ "peerDependencies": {
38
+ "webpack": "^4.36.0",
39
+ "node-sass": "^4.0.0",
40
+ "sass": "^1.3.0",
41
+ "fibers": ">= 3.1.0"
42
+ },
43
+ "peerDependenciesMeta": {
44
+ "node-sass": {
45
+ "optional": true
46
+ },
47
+ "sass": {
48
+ "optional": true
49
+ },
50
+ "fibers": {
51
+ "optional": true
52
+ }
27
53
  },
28
54
  "dependencies": {
29
- "clone-deep": "^2.0.1",
30
- "loader-utils": "^1.0.1",
31
- "lodash.tail": "^4.1.1",
32
- "neo-async": "^2.5.0",
33
- "pify": "^3.0.0",
34
- "semver": "^5.5.0"
55
+ "clone-deep": "^4.0.1",
56
+ "loader-utils": "^1.2.3",
57
+ "neo-async": "^2.6.1",
58
+ "schema-utils": "^2.1.0",
59
+ "semver": "^6.3.0"
35
60
  },
36
61
  "devDependencies": {
37
- "bootstrap-sass": "^3.3.5",
38
- "css-loader": "^0.28.4",
39
- "eslint": "^3.16.0",
40
- "eslint-config-peerigon": "^9.0.0",
41
- "eslint-plugin-jsdoc": "^2.4.0",
42
- "file-loader": "^0.11.2",
43
- "mocha": "^3.0.2",
44
- "mock-require": "^3.0.1",
45
- "node-sass": "^4.5.0",
46
- "nyc": "^11.0.2",
47
- "raw-loader": "^0.5.1",
48
- "sass": "^1.3.0",
49
- "should": "^11.2.0",
50
- "standard-version": "^4.2.0",
51
- "style-loader": "^0.18.2",
52
- "webpack": "^4.5.0",
53
- "webpack-dev-server": "^2.4.1",
54
- "webpack-merge": "^4.0.0"
55
- },
56
- "engines": {
57
- "node": ">= 6.9.0 || >= 8.9.0"
58
- },
59
- "peerDependencies": {
60
- "webpack": "^3.0.0 || ^4.0.0"
62
+ "@babel/cli": "^7.5.5",
63
+ "@babel/core": "^7.5.5",
64
+ "@babel/preset-env": "^7.5.5",
65
+ "@commitlint/cli": "^8.1.0",
66
+ "@commitlint/config-conventional": "^8.1.0",
67
+ "@webpack-contrib/defaults": "^5.0.2",
68
+ "@webpack-contrib/eslint-config-webpack": "^3.0.0",
69
+ "babel-jest": "^24.9.0",
70
+ "bootstrap": "^4.3.1",
71
+ "bootstrap-sass": "^3.4.1",
72
+ "commitlint-azure-pipelines-cli": "^1.0.2",
73
+ "cross-env": "^5.2.0",
74
+ "css-loader": "^3.2.0",
75
+ "del": "^5.1.0",
76
+ "del-cli": "^2.0.0",
77
+ "eslint": "^6.2.2",
78
+ "eslint-config-prettier": "^6.1.0",
79
+ "eslint-plugin-import": "^2.18.2",
80
+ "fibers": "^4.0.1",
81
+ "file-loader": "^4.2.0",
82
+ "husky": "^3.0.4",
83
+ "jest": "^24.9.0",
84
+ "jest-junit": "^8.0.0",
85
+ "jquery": "^3.4.1",
86
+ "lint-staged": "^9.2.5",
87
+ "memory-fs": "^0.4.1",
88
+ "node-sass": "^4.12.0",
89
+ "npm-run-all": "^4.1.5",
90
+ "popper.js": "^1.15.0",
91
+ "prettier": "^1.18.2",
92
+ "sass": "^1.22.10",
93
+ "standard-version": "^7.0.0",
94
+ "style-loader": "^1.0.0",
95
+ "webpack": "^4.39.3",
96
+ "webpack-cli": "^3.3.7",
97
+ "webpack-dev-server": "^3.8.0"
61
98
  },
62
99
  "keywords": [
63
100
  "sass",
64
101
  "libsass",
65
102
  "webpack",
66
103
  "loader"
67
- ],
68
- "repository": "https://github.com/webpack-contrib/sass-loader.git",
69
- "bugs": "https://github.com/webpack-contrib/sass-loader/issues",
70
- "homepage": "https://github.com/webpack-contrib/sass-loader"
104
+ ]
71
105
  }
@@ -1,73 +0,0 @@
1
- "use strict";
2
-
3
- const path = require("path");
4
- const os = require("os");
5
- const fs = require("fs");
6
-
7
- // A typical sass error looks like this
8
- const SassError = { // eslint-disable-line no-unused-vars
9
- message: "invalid property name",
10
- column: 14,
11
- line: 1,
12
- file: "stdin",
13
- status: 1
14
- };
15
-
16
- /**
17
- * Enhances the sass error with additional information about what actually went wrong.
18
- *
19
- * @param {SassError} err
20
- * @param {string} resourcePath
21
- */
22
- function formatSassError(err, resourcePath) {
23
- // Instruct webpack to hide the JS stack from the console
24
- // Usually you're only interested in the SASS stack in this case.
25
- err.hideStack = true;
26
-
27
- // The file property is missing in rare cases.
28
- // No improvement in the error is possible.
29
- if (!err.file) {
30
- return;
31
- }
32
-
33
- let msg = err.message;
34
-
35
- if (err.file === "stdin") {
36
- err.file = resourcePath;
37
- }
38
- // node-sass returns UNIX-style paths
39
- err.file = path.normalize(err.file);
40
-
41
- // The 'Current dir' hint of node-sass does not help us, we're providing
42
- // additional information by reading the err.file property
43
- msg = msg.replace(/\s*Current dir:\s*/, "");
44
-
45
- err.message = getFileExcerptIfPossible(err) +
46
- msg.charAt(0).toUpperCase() + msg.slice(1) + os.EOL +
47
- " in " + err.file + " (line " + err.line + ", column " + err.column + ")";
48
- }
49
-
50
- /**
51
- * Tries to get an excerpt of the file where the error happened.
52
- * Uses err.line and err.column.
53
- *
54
- * Returns an empty string if the excerpt could not be retrieved.
55
- *
56
- * @param {SassError} err
57
- * @returns {string}
58
- */
59
- function getFileExcerptIfPossible(err) {
60
- try {
61
- const content = fs.readFileSync(err.file, "utf8");
62
-
63
- return os.EOL +
64
- content.split(os.EOL)[err.line - 1] + os.EOL +
65
- new Array(err.column - 1).join(" ") + "^" + os.EOL +
66
- " ";
67
- } catch (err) {
68
- // If anything goes wrong here, we don't want any errors to be reported to the user
69
- return "";
70
- }
71
- }
72
-
73
- module.exports = formatSassError;
@@ -1,60 +0,0 @@
1
- "use strict";
2
-
3
- const path = require("path");
4
- const utils = require("loader-utils");
5
-
6
- const matchModuleImport = /^~([^\/]+|@[^\/]+[\/][^\/]+)$/;
7
-
8
- /**
9
- * When libsass tries to resolve an import, it uses a special algorithm.
10
- * Since the sass-loader uses webpack to resolve the modules, we need to simulate that algorithm. This function
11
- * returns an array of import paths to try. The last entry in the array is always the original url
12
- * to enable straight-forward webpack.config aliases.
13
- *
14
- * @param {string} url
15
- * @returns {Array<string>}
16
- */
17
- function importsToResolve(url) {
18
- const request = utils.urlToRequest(url);
19
- // Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.
20
- // @see https://github.com/webpack-contrib/sass-loader/issues/167
21
- const ext = path.extname(request);
22
-
23
- if (matchModuleImport.test(url)) {
24
- return [request, url];
25
- }
26
-
27
- // libsass' import algorithm works like this:
28
-
29
- // In case there is a file extension...
30
- // - If the file is a CSS-file, do not include it all, but just link it via @import url().
31
- // - The exact file name must match (no auto-resolving of '_'-modules).
32
- if (ext === ".css") {
33
- return [];
34
- }
35
- if (ext === ".scss" || ext === ".sass") {
36
- return [request, url];
37
- }
38
-
39
- // In case there is no file extension...
40
- // - Prefer modules starting with '_'.
41
- // - File extension precedence: .scss, .sass, .css.
42
- const basename = path.basename(request);
43
-
44
- if (basename.charAt(0) === "_") {
45
- return [
46
- `${ request }.scss`, `${ request }.sass`, `${ request }.css`,
47
- url
48
- ];
49
- }
50
-
51
- const dirname = path.dirname(request);
52
-
53
- return [
54
- `${ dirname }/_${ basename }.scss`, `${ dirname }/_${ basename }.sass`, `${ dirname }/_${ basename }.css`,
55
- `${ request }.scss`, `${ request }.sass`, `${ request }.css`,
56
- url
57
- ];
58
- }
59
-
60
- module.exports = importsToResolve;
package/lib/loader.js DELETED
@@ -1,124 +0,0 @@
1
- "use strict";
2
-
3
- const path = require("path");
4
- const async = require("neo-async");
5
- const formatSassError = require("./formatSassError");
6
- const webpackImporter = require("./webpackImporter");
7
- const normalizeOptions = require("./normalizeOptions");
8
- const pify = require("pify");
9
- const semver = require("semver");
10
-
11
- let nodeSassJobQueue = null;
12
-
13
- /**
14
- * The sass-loader makes node-sass available to webpack modules.
15
- *
16
- * @this {LoaderContext}
17
- * @param {string} content
18
- */
19
- function sassLoader(content) {
20
- const callback = this.async();
21
- const isSync = typeof callback !== "function";
22
- const self = this;
23
- const resourcePath = this.resourcePath;
24
-
25
- function addNormalizedDependency(file) {
26
- // node-sass returns POSIX paths
27
- self.dependency(path.normalize(file));
28
- }
29
-
30
- if (isSync) {
31
- throw new Error("Synchronous compilation is not supported anymore. See https://github.com/webpack-contrib/sass-loader/issues/333");
32
- }
33
-
34
- const options = normalizeOptions(this, content, webpackImporter(
35
- resourcePath,
36
- pify(this.resolve.bind(this)),
37
- addNormalizedDependency
38
- ));
39
-
40
- // Skip empty files, otherwise it will stop webpack, see issue #21
41
- if (options.data.trim() === "") {
42
- callback(null, "");
43
- return;
44
- }
45
-
46
- const render = getRenderFuncFromSassImpl(options.implementation || require("node-sass"));
47
-
48
- render(options, (err, result) => {
49
- if (err) {
50
- formatSassError(err, this.resourcePath);
51
- err.file && this.dependency(err.file);
52
- callback(err);
53
- return;
54
- }
55
-
56
- if (result.map && result.map !== "{}") {
57
- result.map = JSON.parse(result.map);
58
- // result.map.file is an optional property that provides the output filename.
59
- // Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
60
- delete result.map.file;
61
- // The first source is 'stdin' according to node-sass because we've used the data input.
62
- // Now let's override that value with the correct relative path.
63
- // Since we specified options.sourceMap = path.join(process.cwd(), "/sass.map"); in normalizeOptions,
64
- // we know that this path is relative to process.cwd(). This is how node-sass works.
65
- result.map.sources[0] = path.relative(process.cwd(), resourcePath);
66
- // node-sass returns POSIX paths, that's why we need to transform them back to native paths.
67
- // This fixes an error on windows where the source-map module cannot resolve the source maps.
68
- // @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
69
- result.map.sourceRoot = path.normalize(result.map.sourceRoot);
70
- result.map.sources = result.map.sources.map(path.normalize);
71
- } else {
72
- result.map = null;
73
- }
74
-
75
- result.stats.includedFiles.forEach(addNormalizedDependency);
76
- callback(null, result.css.toString(), result.map);
77
- });
78
- }
79
-
80
- /**
81
- * Verifies that the implementation and version of Sass is supported by this loader.
82
- *
83
- * @param {Object} module
84
- * @returns {Function}
85
- */
86
- function getRenderFuncFromSassImpl(module) {
87
- const info = module.info;
88
- const components = info.split("\t");
89
-
90
- if (components.length < 2) {
91
- throw new Error("Unknown Sass implementation \"" + info + "\".");
92
- }
93
-
94
- const implementation = components[0];
95
- const version = components[1];
96
-
97
- if (!semver.valid(version)) {
98
- throw new Error("Invalid Sass version \"" + version + "\".");
99
- }
100
-
101
- if (implementation === "dart-sass") {
102
- if (!semver.satisfies(version, "^1.3.0")) {
103
- throw new Error("Dart Sass version " + version + " is incompatible with ^1.3.0.");
104
- }
105
- return module.render.bind(module);
106
- } else if (implementation === "node-sass") {
107
- if (!semver.satisfies(version, "^4.0.0")) {
108
- throw new Error("Node Sass version " + version + " is incompatible with ^4.0.0.");
109
- }
110
- // There is an issue with node-sass when async custom importers are used
111
- // See https://github.com/sass/node-sass/issues/857#issuecomment-93594360
112
- // We need to use a job queue to make sure that one thread is always available to the UV lib
113
- if (nodeSassJobQueue === null) {
114
- const threadPoolSize = Number(process.env.UV_THREADPOOL_SIZE || 4);
115
-
116
- nodeSassJobQueue = async.queue(module.render.bind(module), threadPoolSize - 1);
117
- }
118
-
119
- return nodeSassJobQueue.push.bind(nodeSassJobQueue);
120
- }
121
- throw new Error("Unknown Sass implementation \"" + implementation + "\".");
122
- }
123
-
124
- module.exports = sassLoader;
@@ -1,78 +0,0 @@
1
- "use strict";
2
-
3
- const os = require("os");
4
- const utils = require("loader-utils");
5
- const cloneDeep = require("clone-deep");
6
- const path = require("path");
7
- const proxyCustomImporters = require("./proxyCustomImporters");
8
-
9
- /**
10
- * Derives the sass options from the loader context and normalizes its values with sane defaults.
11
- *
12
- * Please note: If loaderContext.query is an options object, it will be re-used across multiple invocations.
13
- * That's why we must not modify the object directly.
14
- *
15
- * @param {LoaderContext} loaderContext
16
- * @param {string} content
17
- * @param {Function} webpackImporter
18
- * @returns {Object}
19
- */
20
- function normalizeOptions(loaderContext, content, webpackImporter) {
21
- const options = cloneDeep(utils.getOptions(loaderContext)) || {};
22
- const resourcePath = loaderContext.resourcePath;
23
-
24
- options.data = options.data ? (options.data + os.EOL + content) : content;
25
-
26
- // opt.outputStyle
27
- if (!options.outputStyle && loaderContext.minimize) {
28
- options.outputStyle = "compressed";
29
- }
30
-
31
- // opt.sourceMap
32
- // Not using the `this.sourceMap` flag because css source maps are different
33
- // @see https://github.com/webpack/css-loader/pull/40
34
- if (options.sourceMap) {
35
- // Deliberately overriding the sourceMap option here.
36
- // node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
37
- // In case it is a string, options.sourceMap should be a path where the source map is written.
38
- // But since we're using the data option, the source map will not actually be written, but
39
- // all paths in sourceMap.sources will be relative to that path.
40
- // Pretty complicated... :(
41
- options.sourceMap = path.join(process.cwd(), "/sass.map");
42
- if ("sourceMapRoot" in options === false) {
43
- options.sourceMapRoot = process.cwd();
44
- }
45
- if ("omitSourceMapUrl" in options === false) {
46
- // The source map url doesn't make sense because we don't know the output path
47
- // The css-loader will handle that for us
48
- options.omitSourceMapUrl = true;
49
- }
50
- if ("sourceMapContents" in options === false) {
51
- // If sourceMapContents option is not set, set it to true otherwise maps will be empty/null
52
- // when exported by webpack-extract-text-plugin.
53
- options.sourceMapContents = true;
54
- }
55
- }
56
-
57
- // indentedSyntax is a boolean flag.
58
- const ext = path.extname(resourcePath);
59
-
60
- // If we are compiling sass and indentedSyntax isn't set, automatically set it.
61
- if (ext && ext.toLowerCase() === ".sass" && "indentedSyntax" in options === false) {
62
- options.indentedSyntax = true;
63
- } else {
64
- options.indentedSyntax = Boolean(options.indentedSyntax);
65
- }
66
-
67
- // Allow passing custom importers to `node-sass`. Accepts `Function` or an array of `Function`s.
68
- options.importer = options.importer ? proxyCustomImporters(options.importer, resourcePath) : [];
69
- options.importer.push(webpackImporter);
70
-
71
- // `node-sass` uses `includePaths` to resolve `@import` paths. Append the currently processed file.
72
- options.includePaths = options.includePaths || [];
73
- options.includePaths.push(path.dirname(resourcePath));
74
-
75
- return options;
76
- }
77
-
78
- module.exports = normalizeOptions;
@@ -1,72 +0,0 @@
1
- "use strict";
2
-
3
- /**
4
- * @name PromisedResolve
5
- * @type {Function}
6
- * @param {string} dir
7
- * @param {string} request
8
- * @returns Promise
9
- */
10
-
11
- /**
12
- * @name Importer
13
- * @type {Function}
14
- * @param {string} url
15
- * @param {string} prev
16
- * @param {Function<Error, string>} done
17
- */
18
-
19
- const path = require("path");
20
- const tail = require("lodash.tail");
21
- const importsToResolve = require("./importsToResolve");
22
-
23
- const matchCss = /\.css$/;
24
-
25
- /**
26
- * Returns an importer that uses webpack's resolving algorithm.
27
- *
28
- * It's important that the returned function has the correct number of arguments
29
- * (based on whether the call is sync or async) because otherwise node-sass doesn't exit.
30
- *
31
- * @param {string} resourcePath
32
- * @param {PromisedResolve} resolve
33
- * @param {Function<string>} addNormalizedDependency
34
- * @returns {Importer}
35
- */
36
- function webpackImporter(resourcePath, resolve, addNormalizedDependency) {
37
- function dirContextFrom(fileContext) {
38
- return path.dirname(
39
- // The first file is 'stdin' when we're using the data option
40
- fileContext === "stdin" ? resourcePath : fileContext
41
- );
42
- }
43
-
44
- function startResolving(dir, importsToResolve) {
45
- return importsToResolve.length === 0 ?
46
- Promise.reject() :
47
- resolve(dir, importsToResolve[0])
48
- .then(resolvedFile => {
49
- // Add the resolvedFilename as dependency. Although we're also using stats.includedFiles, this might come
50
- // in handy when an error occurs. In this case, we don't get stats.includedFiles from node-sass.
51
- addNormalizedDependency(resolvedFile);
52
- return {
53
- // By removing the CSS file extension, we trigger node-sass to include the CSS file instead of just linking it.
54
- file: resolvedFile.replace(matchCss, "")
55
- };
56
- }, () => startResolving(
57
- dir,
58
- tail(importsToResolve)
59
- ));
60
- }
61
-
62
- return (url, prev, done) => {
63
- startResolving(
64
- dirContextFrom(prev),
65
- importsToResolve(url)
66
- ) // Catch all resolving errors, return the original file and pass responsibility back to other custom importers
67
- .catch(() => ({ file: url }))
68
- .then(done);
69
- };
70
- }
71
-
72
- module.exports = webpackImporter;