11import url from "url" ;
22import path from "path" ;
33
4- import { klona } from "klona/full" ;
54import async from "neo-async" ;
65
76function getDefaultSassImplementation ( ) {
@@ -112,32 +111,29 @@ async function getSassOptions(
112111 implementation ,
113112 useSourceMap
114113) {
115- const options = klona (
116- loaderOptions . sassOptions
117- ? typeof loaderOptions . sassOptions === "function"
118- ? loaderOptions . sassOptions ( loaderContext ) || { }
119- : loaderOptions . sassOptions
120- : { }
121- ) ;
122-
123- const isDartSass = implementation . info . includes ( "dart-sass" ) ;
124- const isModernAPI = loaderOptions . api === "modern" ;
125-
126- options . data = loaderOptions . additionalData
127- ? typeof loaderOptions . additionalData === "function"
128- ? await loaderOptions . additionalData ( content , loaderContext )
129- : `${ loaderOptions . additionalData } \n${ content } `
130- : content ;
114+ const options = loaderOptions . sassOptions
115+ ? typeof loaderOptions . sassOptions === "function"
116+ ? loaderOptions . sassOptions ( loaderContext ) || { }
117+ : loaderOptions . sassOptions
118+ : { } ;
119+ const sassOptions = {
120+ ...options ,
121+ data : loaderOptions . additionalData
122+ ? typeof loaderOptions . additionalData === "function"
123+ ? await loaderOptions . additionalData ( content , loaderContext )
124+ : `${ loaderOptions . additionalData } \n${ content } `
125+ : content ,
126+ } ;
131127
132- if ( ! options . logger ) {
128+ if ( ! sassOptions . logger ) {
133129 const needEmitWarning = loaderOptions . warnRuleAsWarning !== false ;
134130 const logger = loaderContext . getLogger ( "sass-loader" ) ;
135131 const formatSpan = ( span ) =>
136132 `${ span . url || "-" } :${ span . start . line } :${ span . start . column } : ` ;
137133 const formatDebugSpan = ( span ) =>
138134 `[debug:${ span . start . line } :${ span . start . column } ] ` ;
139135
140- options . logger = {
136+ sassOptions . logger = {
141137 debug ( message , loggerOptions ) {
142138 let builtMessage = "" ;
143139
@@ -180,44 +176,47 @@ async function getSassOptions(
180176 } ;
181177 }
182178
179+ const isModernAPI = loaderOptions . api === "modern" ;
183180 const { resourcePath } = loaderContext ;
184181
185182 if ( isModernAPI ) {
186- options . url = url . pathToFileURL ( resourcePath ) ;
183+ sassOptions . url = url . pathToFileURL ( resourcePath ) ;
187184
188185 // opt.outputStyle
189- if ( ! options . style && isProductionLikeMode ( loaderContext ) ) {
190- options . style = "compressed" ;
186+ if ( ! sassOptions . style && isProductionLikeMode ( loaderContext ) ) {
187+ sassOptions . style = "compressed" ;
191188 }
192189
193190 if ( useSourceMap ) {
194- options . sourceMap = true ;
191+ sassOptions . sourceMap = true ;
195192 }
196193
197194 // If we are compiling sass and indentedSyntax isn't set, automatically set it.
198- if ( typeof options . syntax === "undefined" ) {
195+ if ( typeof sassOptions . syntax === "undefined" ) {
199196 const ext = path . extname ( resourcePath ) ;
200197
201198 if ( ext && ext . toLowerCase ( ) === ".scss" ) {
202- options . syntax = "scss" ;
199+ sassOptions . syntax = "scss" ;
203200 } else if ( ext && ext . toLowerCase ( ) === ".sass" ) {
204- options . syntax = "indented" ;
201+ sassOptions . syntax = "indented" ;
205202 } else if ( ext && ext . toLowerCase ( ) === ".css" ) {
206- options . syntax = "css" ;
203+ sassOptions . syntax = "css" ;
207204 }
208205 }
209206
210- options . importers = options . importers
211- ? Array . isArray ( options . importers )
212- ? options . importers
213- : [ options . importers ]
207+ sassOptions . importers = sassOptions . importers
208+ ? Array . isArray ( sassOptions . importers )
209+ ? sassOptions . importers . slice ( )
210+ : [ sassOptions . importers ]
214211 : [ ] ;
215212 } else {
216- options . file = resourcePath ;
213+ sassOptions . file = resourcePath ;
214+
215+ const isDartSass = implementation . info . includes ( "dart-sass" ) ;
217216
218217 if ( isDartSass && isSupportedFibers ( ) ) {
219218 const shouldTryToResolveFibers =
220- ! options . fiber && options . fiber !== false ;
219+ ! sassOptions . fiber && sassOptions . fiber !== false ;
221220
222221 if ( shouldTryToResolveFibers ) {
223222 let fibers ;
@@ -230,20 +229,20 @@ async function getSassOptions(
230229
231230 if ( fibers ) {
232231 // eslint-disable-next-line global-require, import/no-dynamic-require
233- options . fiber = require ( fibers ) ;
232+ sassOptions . fiber = require ( fibers ) ;
234233 }
235- } else if ( options . fiber === false ) {
234+ } else if ( sassOptions . fiber === false ) {
236235 // Don't pass the `fiber` option for `sass` (`Dart Sass`)
237- delete options . fiber ;
236+ delete sassOptions . fiber ;
238237 }
239238 } else {
240239 // Don't pass the `fiber` option for `node-sass`
241- delete options . fiber ;
240+ delete sassOptions . fiber ;
242241 }
243242
244243 // opt.outputStyle
245- if ( ! options . outputStyle && isProductionLikeMode ( loaderContext ) ) {
246- options . outputStyle = "compressed" ;
244+ if ( ! sassOptions . outputStyle && isProductionLikeMode ( loaderContext ) ) {
245+ sassOptions . outputStyle = "compressed" ;
247246 }
248247
249248 if ( useSourceMap ) {
@@ -253,11 +252,14 @@ async function getSassOptions(
253252 // But since we're using the data option, the source map will not actually be written, but
254253 // all paths in sourceMap.sources will be relative to that path.
255254 // Pretty complicated... :(
256- options . sourceMap = true ;
257- options . outFile = path . join ( loaderContext . rootContext , "style.css.map" ) ;
258- options . sourceMapContents = true ;
259- options . omitSourceMapUrl = true ;
260- options . sourceMapEmbed = false ;
255+ sassOptions . sourceMap = true ;
256+ sassOptions . outFile = path . join (
257+ loaderContext . rootContext ,
258+ "style.css.map"
259+ ) ;
260+ sassOptions . sourceMapContents = true ;
261+ sassOptions . omitSourceMapUrl = true ;
262+ sassOptions . sourceMapEmbed = false ;
261263 }
262264
263265 const ext = path . extname ( resourcePath ) ;
@@ -266,31 +268,32 @@ async function getSassOptions(
266268 if (
267269 ext &&
268270 ext . toLowerCase ( ) === ".sass" &&
269- typeof options . indentedSyntax === "undefined"
271+ typeof sassOptions . indentedSyntax === "undefined"
270272 ) {
271- options . indentedSyntax = true ;
273+ sassOptions . indentedSyntax = true ;
272274 } else {
273- options . indentedSyntax = Boolean ( options . indentedSyntax ) ;
275+ sassOptions . indentedSyntax = Boolean ( sassOptions . indentedSyntax ) ;
274276 }
275277
276278 // Allow passing custom importers to `sass`/`node-sass`. Accepts `Function` or an array of `Function`s.
277- options . importer = options . importer
279+ sassOptions . importer = sassOptions . importer
278280 ? proxyCustomImporters (
279- Array . isArray ( options . importer )
280- ? options . importer
281- : [ options . importer ] ,
281+ Array . isArray ( sassOptions . importer )
282+ ? sassOptions . importer . slice ( )
283+ : [ sassOptions . importer ] ,
282284 loaderContext
283285 )
284286 : [ ] ;
285287
286- options . includePaths = [ ]
288+ sassOptions . includePaths = [ ]
287289 . concat ( process . cwd ( ) )
288290 . concat (
289291 // We use `includePaths` in context for resolver, so it should be always absolute
290- ( options . includePaths || [ ] ) . map ( ( includePath ) =>
291- path . isAbsolute ( includePath )
292- ? includePath
293- : path . join ( process . cwd ( ) , includePath )
292+ ( sassOptions . includePaths ? sassOptions . includePaths . slice ( ) : [ ] ) . map (
293+ ( includePath ) =>
294+ path . isAbsolute ( includePath )
295+ ? includePath
296+ : path . join ( process . cwd ( ) , includePath )
294297 )
295298 )
296299 . concat (
@@ -301,12 +304,12 @@ async function getSassOptions(
301304 : [ ]
302305 ) ;
303306
304- if ( typeof options . charset === "undefined" ) {
305- options . charset = true ;
307+ if ( typeof sassOptions . charset === "undefined" ) {
308+ sassOptions . charset = true ;
306309 }
307310 }
308311
309- return options ;
312+ return sassOptions ;
310313}
311314
312315const MODULE_REQUEST_REGEX = / ^ [ ^ ? ] * ~ / ;
0 commit comments