Skip to content

Commit 9e87b6b

Browse files
authoredJun 9, 2023
fix(perf): avoid using klona for sass options (#1145)
1 parent 7d2deb3 commit 9e87b6b

File tree

5 files changed

+596
-68
lines changed

5 files changed

+596
-68
lines changed
 

‎package.json

-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
}
6464
},
6565
"dependencies": {
66-
"klona": "^2.0.6",
6766
"neo-async": "^2.6.2"
6867
},
6968
"devDependencies": {

‎src/utils.js

+62-59
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import url from "url";
22
import path from "path";
33

4-
import { klona } from "klona/full";
54
import async from "neo-async";
65

76
function 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

312315
const MODULE_REQUEST_REGEX = /^[^?]*~/;

0 commit comments

Comments
 (0)
Please sign in to comment.