UNPKG

24.3 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.getCompileFn = getCompileFn;
7exports.getModernWebpackImporter = getModernWebpackImporter;
8exports.getSassImplementation = getSassImplementation;
9exports.getSassOptions = getSassOptions;
10exports.getWebpackImporter = getWebpackImporter;
11exports.getWebpackResolver = getWebpackResolver;
12exports.isSupportedFibers = isSupportedFibers;
13exports.normalizeSourceMap = normalizeSourceMap;
14
15var _url = _interopRequireDefault(require("url"));
16
17var _path = _interopRequireDefault(require("path"));
18
19var _full = require("klona/full");
20
21var _neoAsync = _interopRequireDefault(require("neo-async"));
22
23var _SassWarning = _interopRequireDefault(require("./SassWarning"));
24
25function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
27function getDefaultSassImplementation() {
28 let sassImplPkg = "sass";
29
30 try {
31 require.resolve("sass");
32 } catch (ignoreError) {
33 try {
34 require.resolve("node-sass");
35
36 sassImplPkg = "node-sass";
37 } catch (_ignoreError) {
38 try {
39 require.resolve("sass-embedded");
40
41 sassImplPkg = "sass-embedded";
42 } catch (__ignoreError) {
43 sassImplPkg = "sass";
44 }
45 }
46 } // eslint-disable-next-line import/no-dynamic-require, global-require
47
48
49 return require(sassImplPkg);
50}
51/**
52 * 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.
53 */
54
55
56function getSassImplementation(loaderContext, implementation) {
57 let resolvedImplementation = implementation;
58
59 if (!resolvedImplementation) {
60 try {
61 resolvedImplementation = getDefaultSassImplementation();
62 } catch (error) {
63 loaderContext.emitError(error);
64 return;
65 }
66 }
67
68 if (typeof resolvedImplementation === "string") {
69 try {
70 // eslint-disable-next-line import/no-dynamic-require, global-require
71 resolvedImplementation = require(resolvedImplementation);
72 } catch (error) {
73 loaderContext.emitError(error); // eslint-disable-next-line consistent-return
74
75 return;
76 }
77 }
78
79 const {
80 info
81 } = resolvedImplementation;
82
83 if (!info) {
84 loaderContext.emitError(new Error("Unknown Sass implementation."));
85 return;
86 }
87
88 const infoParts = info.split("\t");
89
90 if (infoParts.length < 2) {
91 loaderContext.emitError(new Error(`Unknown Sass implementation "${info}".`));
92 return;
93 }
94
95 const [implementationName] = infoParts;
96
97 if (implementationName === "dart-sass") {
98 // eslint-disable-next-line consistent-return
99 return resolvedImplementation;
100 } else if (implementationName === "node-sass") {
101 // eslint-disable-next-line consistent-return
102 return resolvedImplementation;
103 } else if (implementationName === "sass-embedded") {
104 // eslint-disable-next-line consistent-return
105 return resolvedImplementation;
106 }
107
108 loaderContext.emitError(new Error(`Unknown Sass implementation "${implementationName}".`));
109}
110/**
111 * @param {any} loaderContext
112 * @returns {boolean}
113 */
114
115
116function isProductionLikeMode(loaderContext) {
117 return loaderContext.mode === "production" || !loaderContext.mode;
118}
119
120function proxyCustomImporters(importers, loaderContext) {
121 return [].concat(importers).map(importer => function proxyImporter(...args) {
122 const self = { ...this,
123 webpackLoaderContext: loaderContext
124 };
125 return importer.apply(self, args);
126 });
127}
128
129function isSupportedFibers() {
130 const [nodeVersion] = process.versions.node.split(".");
131 return Number(nodeVersion) < 16;
132}
133/**
134 * Derives the sass options from the loader context and normalizes its values with sane defaults.
135 *
136 * @param {object} loaderContext
137 * @param {object} loaderOptions
138 * @param {string} content
139 * @param {object} implementation
140 * @param {boolean} useSourceMap
141 * @returns {Object}
142 */
143
144
145async function getSassOptions(loaderContext, loaderOptions, content, implementation, useSourceMap) {
146 const options = (0, _full.klona)(loaderOptions.sassOptions ? typeof loaderOptions.sassOptions === "function" ? loaderOptions.sassOptions(loaderContext) || {} : loaderOptions.sassOptions : {});
147 const isDartSass = implementation.info.includes("dart-sass");
148 const isModernAPI = loaderOptions.api === "modern";
149 options.data = loaderOptions.additionalData ? typeof loaderOptions.additionalData === "function" ? await loaderOptions.additionalData(content, loaderContext) : `${loaderOptions.additionalData}\n${content}` : content;
150
151 if (!options.logger) {
152 const needEmitWarning = loaderOptions.warnRuleAsWarning !== false;
153 const logger = loaderContext.getLogger("sass-loader");
154
155 const formatSpan = span => `${span.url || "-"}:${span.start.line}:${span.start.column}: `;
156
157 const formatDebugSpan = span => `[debug:${span.start.line}:${span.start.column}] `;
158
159 options.logger = {
160 debug(message, loggerOptions) {
161 let builtMessage = "";
162
163 if (loggerOptions.span) {
164 builtMessage = formatDebugSpan(loggerOptions.span);
165 }
166
167 builtMessage += message;
168 logger.debug(builtMessage);
169 },
170
171 warn(message, loggerOptions) {
172 let builtMessage = "";
173
174 if (loggerOptions.deprecation) {
175 builtMessage += "Deprecation ";
176 }
177
178 if (loggerOptions.span && !loggerOptions.stack) {
179 builtMessage = formatSpan(loggerOptions.span);
180 }
181
182 builtMessage += message;
183
184 if (loggerOptions.stack) {
185 builtMessage += `\n\n${loggerOptions.stack}`;
186 }
187
188 if (needEmitWarning) {
189 loaderContext.emitWarning(new _SassWarning.default(builtMessage, loggerOptions));
190 } else {
191 logger.warn(builtMessage);
192 }
193 }
194
195 };
196 }
197
198 const {
199 resourcePath
200 } = loaderContext;
201
202 if (isModernAPI) {
203 options.url = _url.default.pathToFileURL(resourcePath); // opt.outputStyle
204
205 if (!options.style && isProductionLikeMode(loaderContext)) {
206 options.style = "compressed";
207 }
208
209 if (useSourceMap) {
210 options.sourceMap = true;
211 } // If we are compiling sass and indentedSyntax isn't set, automatically set it.
212
213
214 if (typeof options.syntax === "undefined") {
215 const ext = _path.default.extname(resourcePath);
216
217 if (ext && ext.toLowerCase() === ".scss") {
218 options.syntax = "scss";
219 } else if (ext && ext.toLowerCase() === ".sass") {
220 options.syntax = "indented";
221 } else if (ext && ext.toLowerCase() === ".css") {
222 options.syntax = "css";
223 }
224 }
225
226 options.importers = options.importers ? Array.isArray(options.importers) ? options.importers : [options.importers] : [];
227 } else {
228 options.file = resourcePath;
229
230 if (isDartSass && isSupportedFibers()) {
231 const shouldTryToResolveFibers = !options.fiber && options.fiber !== false;
232
233 if (shouldTryToResolveFibers) {
234 let fibers;
235
236 try {
237 fibers = require.resolve("fibers");
238 } catch (_error) {// Nothing
239 }
240
241 if (fibers) {
242 // eslint-disable-next-line global-require, import/no-dynamic-require
243 options.fiber = require(fibers);
244 }
245 } else if (options.fiber === false) {
246 // Don't pass the `fiber` option for `sass` (`Dart Sass`)
247 delete options.fiber;
248 }
249 } else {
250 // Don't pass the `fiber` option for `node-sass`
251 delete options.fiber;
252 } // opt.outputStyle
253
254
255 if (!options.outputStyle && isProductionLikeMode(loaderContext)) {
256 options.outputStyle = "compressed";
257 }
258
259 if (useSourceMap) {
260 // Deliberately overriding the sourceMap option here.
261 // node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
262 // In case it is a string, options.sourceMap should be a path where the source map is written.
263 // But since we're using the data option, the source map will not actually be written, but
264 // all paths in sourceMap.sources will be relative to that path.
265 // Pretty complicated... :(
266 options.sourceMap = true;
267 options.outFile = _path.default.join(loaderContext.rootContext, "style.css.map");
268 options.sourceMapContents = true;
269 options.omitSourceMapUrl = true;
270 options.sourceMapEmbed = false;
271 }
272
273 const ext = _path.default.extname(resourcePath); // If we are compiling sass and indentedSyntax isn't set, automatically set it.
274
275
276 if (ext && ext.toLowerCase() === ".sass" && typeof options.indentedSyntax === "undefined") {
277 options.indentedSyntax = true;
278 } else {
279 options.indentedSyntax = Boolean(options.indentedSyntax);
280 } // Allow passing custom importers to `sass`/`node-sass`. Accepts `Function` or an array of `Function`s.
281
282
283 options.importer = options.importer ? proxyCustomImporters(Array.isArray(options.importer) ? options.importer : [options.importer], loaderContext) : [];
284 options.includePaths = [].concat(process.cwd()).concat( // We use `includePaths` in context for resolver, so it should be always absolute
285 (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" ? ";" : ":") : []);
286
287 if (typeof options.charset === "undefined") {
288 options.charset = true;
289 }
290 }
291
292 return options;
293}
294
295const MODULE_REQUEST_REGEX = /^[^?]*~/; // Examples:
296// - ~package
297// - ~package/
298// - ~@org
299// - ~@org/
300// - ~@org/package
301// - ~@org/package/
302
303const IS_MODULE_IMPORT = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;
304/**
305 * When `sass`/`node-sass` tries to resolve an import, it uses a special algorithm.
306 * Since the `sass-loader` uses webpack to resolve the modules, we need to simulate that algorithm.
307 * This function returns an array of import paths to try.
308 * The last entry in the array is always the original url to enable straight-forward webpack.config aliases.
309 *
310 * We don't need emulate `dart-sass` "It's not clear which file to import." errors (when "file.ext" and "_file.ext" files are present simultaneously in the same directory).
311 * This reduces performance and `dart-sass` always do it on own side.
312 *
313 * @param {string} url
314 * @param {boolean} forWebpackResolver
315 * @param {boolean} fromImport
316 * @returns {Array<string>}
317 */
318
319function getPossibleRequests( // eslint-disable-next-line no-shadow
320url, forWebpackResolver = false, fromImport = false) {
321 let request = url; // In case there is module request, send this to webpack resolver
322
323 if (forWebpackResolver) {
324 if (MODULE_REQUEST_REGEX.test(url)) {
325 request = request.replace(MODULE_REQUEST_REGEX, "");
326 }
327
328 if (IS_MODULE_IMPORT.test(url)) {
329 request = request[request.length - 1] === "/" ? request : `${request}/`;
330 return [...new Set([request, url])];
331 }
332 } // Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.
333 // @see https://github.com/webpack-contrib/sass-loader/issues/167
334
335
336 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.
337 // 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:
338 // - imports where the URL ends with .css.
339 // - imports where the URL begins http:// or https://.
340 // - imports where the URL is written as a url().
341 // - imports that have media queries.
342 //
343 // The `node-sass` package sends `@import` ending on `.css` to importer, it is bug, so we skip resolve
344
345
346 if (extension === ".css") {
347 return [];
348 }
349
350 const dirname = _path.default.dirname(request);
351
352 const normalizedDirname = dirname === "." ? "" : `${dirname}/`;
353
354 const basename = _path.default.basename(request);
355
356 const basenameWithoutExtension = _path.default.basename(request, extension);
357
358 return [...new Set([].concat(fromImport ? [`${normalizedDirname}_${basenameWithoutExtension}.import${extension}`, `${normalizedDirname}${basenameWithoutExtension}.import${extension}`] : []).concat([`${normalizedDirname}_${basename}`, `${normalizedDirname}${basename}`]).concat(forWebpackResolver ? [url] : []))];
359}
360
361function promiseResolve(callbackResolve) {
362 return (context, request) => new Promise((resolve, reject) => {
363 callbackResolve(context, request, (error, result) => {
364 if (error) {
365 reject(error);
366 } else {
367 resolve(result);
368 }
369 });
370 });
371}
372
373async function startResolving(resolutionMap) {
374 if (resolutionMap.length === 0) {
375 return Promise.reject();
376 }
377
378 const [{
379 possibleRequests
380 }] = resolutionMap;
381
382 if (possibleRequests.length === 0) {
383 return Promise.reject();
384 }
385
386 const [{
387 resolve,
388 context
389 }] = resolutionMap;
390
391 try {
392 return await resolve(context, possibleRequests[0]);
393 } catch (_ignoreError) {
394 const [, ...tailResult] = possibleRequests;
395
396 if (tailResult.length === 0) {
397 const [, ...tailResolutionMap] = resolutionMap;
398 return startResolving(tailResolutionMap);
399 } // eslint-disable-next-line no-param-reassign
400
401
402 resolutionMap[0].possibleRequests = tailResult;
403 return startResolving(resolutionMap);
404 }
405}
406
407const IS_SPECIAL_MODULE_IMPORT = /^~[^/]+$/; // `[drive_letter]:\` + `\\[server]\[sharename]\`
408
409const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;
410/**
411 * @public
412 * Create the resolve function used in the custom Sass importer.
413 *
414 * Can be used by external tools to mimic how `sass-loader` works, for example
415 * in a Jest transform. Such usages will want to wrap `resolve.create` from
416 * [`enhanced-resolve`]{@link https://github.com/webpack/enhanced-resolve} to
417 * pass as the `resolverFactory` argument.
418 *
419 * @param {Function} resolverFactory - A factory function for creating a Webpack
420 * resolver.
421 * @param {Object} implementation - The imported Sass implementation, both
422 * `sass` (Dart Sass) and `node-sass` are supported.
423 * @param {string[]} [includePaths] - The list of include paths passed to Sass.
424 *
425 * @throws If a compatible Sass implementation cannot be found.
426 */
427
428function getWebpackResolver(resolverFactory, implementation, includePaths = []) {
429 const isDartSass = implementation && implementation.info.includes("dart-sass"); // We only have one difference with the built-in sass resolution logic and out resolution logic:
430 // First, we look at the files starting with `_`, then without `_` (i.e. `_name.sass`, `_name.scss`, `_name.css`, `name.sass`, `name.scss`, `name.css`),
431 // although `sass` look together by extensions (i.e. `_name.sass`/`name.sass`/`_name.scss`/`name.scss`/`_name.css`/`name.css`).
432 // It shouldn't be a problem because `sass` throw errors:
433 // - on having `_name.sass` and `name.sass` (extension can be `sass`, `scss` or `css`) in the same directory
434 // - on having `_name.sass` and `_name.scss` in the same directory
435 //
436 // Also `sass` prefer `sass`/`scss` over `css`.
437
438 const sassModuleResolve = promiseResolve(resolverFactory({
439 alias: [],
440 aliasFields: [],
441 conditionNames: [],
442 descriptionFiles: [],
443 extensions: [".sass", ".scss", ".css"],
444 exportsFields: [],
445 mainFields: [],
446 mainFiles: ["_index", "index"],
447 modules: [],
448 restrictions: [/\.((sa|sc|c)ss)$/i],
449 preferRelative: true
450 }));
451 const sassImportResolve = promiseResolve(resolverFactory({
452 alias: [],
453 aliasFields: [],
454 conditionNames: [],
455 descriptionFiles: [],
456 extensions: [".sass", ".scss", ".css"],
457 exportsFields: [],
458 mainFields: [],
459 mainFiles: ["_index.import", "_index", "index.import", "index"],
460 modules: [],
461 restrictions: [/\.((sa|sc|c)ss)$/i],
462 preferRelative: true
463 }));
464 const webpackModuleResolve = promiseResolve(resolverFactory({
465 dependencyType: "sass",
466 conditionNames: ["sass", "style"],
467 mainFields: ["sass", "style", "main", "..."],
468 mainFiles: ["_index", "index", "..."],
469 extensions: [".sass", ".scss", ".css"],
470 restrictions: [/\.((sa|sc|c)ss)$/i],
471 preferRelative: true
472 }));
473 const webpackImportResolve = promiseResolve(resolverFactory({
474 dependencyType: "sass",
475 conditionNames: ["sass", "style"],
476 mainFields: ["sass", "style", "main", "..."],
477 mainFiles: ["_index.import", "_index", "index.import", "index", "..."],
478 extensions: [".sass", ".scss", ".css"],
479 restrictions: [/\.((sa|sc|c)ss)$/i],
480 preferRelative: true
481 }));
482 return (context, request, fromImport) => {
483 // See https://github.com/webpack/webpack/issues/12340
484 // Because `node-sass` calls our importer before `1. Filesystem imports relative to the base file.`
485 // custom importer may not return `{ file: '/path/to/name.ext' }` and therefore our `context` will be relative
486 if (!isDartSass && !_path.default.isAbsolute(context)) {
487 return Promise.reject();
488 }
489
490 const originalRequest = request;
491 const isFileScheme = originalRequest.slice(0, 5).toLowerCase() === "file:";
492
493 if (isFileScheme) {
494 try {
495 // eslint-disable-next-line no-param-reassign
496 request = _url.default.fileURLToPath(originalRequest);
497 } catch (ignoreError) {
498 // eslint-disable-next-line no-param-reassign
499 request = request.slice(7);
500 }
501 }
502
503 let resolutionMap = [];
504 const needEmulateSassResolver = // `sass` doesn't support module import
505 !IS_SPECIAL_MODULE_IMPORT.test(request) && // We need improve absolute paths handling.
506 // Absolute paths should be resolved:
507 // - Server-relative URLs - `<context>/path/to/file.ext` (where `<context>` is root context)
508 // - Absolute path - `/full/path/to/file.ext` or `C:\\full\path\to\file.ext`
509 !isFileScheme && !originalRequest.startsWith("/") && !IS_NATIVE_WIN32_PATH.test(originalRequest);
510
511 if (includePaths.length > 0 && needEmulateSassResolver) {
512 // The order of import precedence is as follows:
513 //
514 // 1. Filesystem imports relative to the base file.
515 // 2. Custom importer imports.
516 // 3. Filesystem imports relative to the working directory.
517 // 4. Filesystem imports relative to an `includePaths` path.
518 // 5. Filesystem imports relative to a `SASS_PATH` path.
519 //
520 // `sass` run custom importers before `3`, `4` and `5` points, we need to emulate this behavior to avoid wrong resolution.
521 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
522
523 if (!isDartSass) {
524 resolutionMap = resolutionMap.concat({
525 resolve: fromImport ? sassImportResolve : sassModuleResolve,
526 context: _path.default.dirname(context),
527 possibleRequests: sassPossibleRequests
528 });
529 }
530
531 resolutionMap = resolutionMap.concat( // eslint-disable-next-line no-shadow
532 includePaths.map(context => {
533 return {
534 resolve: fromImport ? sassImportResolve : sassModuleResolve,
535 context,
536 possibleRequests: sassPossibleRequests
537 };
538 }));
539 }
540
541 const webpackPossibleRequests = getPossibleRequests(request, true, fromImport);
542 resolutionMap = resolutionMap.concat({
543 resolve: fromImport ? webpackImportResolve : webpackModuleResolve,
544 context: _path.default.dirname(context),
545 possibleRequests: webpackPossibleRequests
546 });
547 return startResolving(resolutionMap);
548 };
549}
550
551const MATCH_CSS = /\.css$/i;
552
553function getModernWebpackImporter() {
554 return {
555 async canonicalize() {
556 return null;
557 },
558
559 load() {// TODO implement
560 }
561
562 };
563}
564
565function getWebpackImporter(loaderContext, implementation, includePaths) {
566 const resolve = getWebpackResolver(loaderContext.getResolve, implementation, includePaths);
567 return function importer(originalUrl, prev, done) {
568 const {
569 fromImport
570 } = this;
571 resolve(prev, originalUrl, fromImport).then(result => {
572 // Add the result as dependency.
573 // Although we're also using stats.includedFiles, this might come in handy when an error occurs.
574 // In this case, we don't get stats.includedFiles from node-sass/sass.
575 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.
576
577 done({
578 file: result.replace(MATCH_CSS, "")
579 });
580 }) // Catch all resolving errors, return the original file and pass responsibility back to other custom importers
581 .catch(() => {
582 done({
583 file: originalUrl
584 });
585 });
586 };
587}
588
589let nodeSassJobQueue = null;
590/**
591 * Verifies that the implementation and version of Sass is supported by this loader.
592 *
593 * @param {Object} implementation
594 * @param {Object} options
595 * @returns {Function}
596 */
597
598function getCompileFn(implementation, options) {
599 const isNewSass = implementation.info.includes("dart-sass") || implementation.info.includes("sass-embedded");
600
601 if (isNewSass) {
602 if (options.api === "modern") {
603 return sassOptions => {
604 const {
605 data,
606 ...rest
607 } = sassOptions;
608 return implementation.compileStringAsync(data, rest);
609 };
610 }
611
612 return sassOptions => new Promise((resolve, reject) => {
613 implementation.render(sassOptions, (error, result) => {
614 if (error) {
615 reject(error);
616 return;
617 }
618
619 resolve(result);
620 });
621 });
622 }
623
624 if (options.api === "modern") {
625 throw new Error("Modern API is not supported for 'node-sass'");
626 } // There is an issue with node-sass when async custom importers are used
627 // See https://github.com/sass/node-sass/issues/857#issuecomment-93594360
628 // We need to use a job queue to make sure that one thread is always available to the UV lib
629
630
631 if (nodeSassJobQueue === null) {
632 const threadPoolSize = Number(process.env.UV_THREADPOOL_SIZE || 4);
633 nodeSassJobQueue = _neoAsync.default.queue(implementation.render.bind(implementation), threadPoolSize - 1);
634 }
635
636 return sassOptions => new Promise((resolve, reject) => {
637 nodeSassJobQueue.push.bind(nodeSassJobQueue)(sassOptions, (error, result) => {
638 if (error) {
639 reject(error);
640 return;
641 }
642
643 resolve(result);
644 });
645 });
646}
647
648const ABSOLUTE_SCHEME = /^[A-Za-z0-9+\-.]+:/;
649/**
650 * @param {string} source
651 * @returns {"absolute" | "scheme-relative" | "path-absolute" | "path-absolute"}
652 */
653
654function getURLType(source) {
655 if (source[0] === "/") {
656 if (source[1] === "/") {
657 return "scheme-relative";
658 }
659
660 return "path-absolute";
661 }
662
663 if (IS_NATIVE_WIN32_PATH.test(source)) {
664 return "path-absolute";
665 }
666
667 return ABSOLUTE_SCHEME.test(source) ? "absolute" : "path-relative";
668}
669
670function normalizeSourceMap(map, rootContext) {
671 const newMap = map; // result.map.file is an optional property that provides the output filename.
672 // Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
673 // eslint-disable-next-line no-param-reassign
674
675 if (typeof newMap.file !== "undefined") {
676 delete newMap.file;
677 } // eslint-disable-next-line no-param-reassign
678
679
680 newMap.sourceRoot = ""; // node-sass returns POSIX paths, that's why we need to transform them back to native paths.
681 // This fixes an error on windows where the source-map module cannot resolve the source maps.
682 // @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
683 // eslint-disable-next-line no-param-reassign
684
685 newMap.sources = newMap.sources.map(source => {
686 const sourceType = getURLType(source); // Do no touch `scheme-relative`, `path-absolute` and `absolute` types (except `file:`)
687
688 if (sourceType === "absolute" && /^file:/i.test(source)) {
689 return _url.default.fileURLToPath(source);
690 } else if (sourceType === "path-relative") {
691 return _path.default.resolve(rootContext, _path.default.normalize(source));
692 }
693
694 return source;
695 });
696 return newMap;
697}
\No newline at end of file