@@ -2266,7 +2266,7 @@ type PreprocessorAdditionalData =
2266
2266
2267
2267
export type SassPreprocessorOptions = {
2268
2268
additionalData ?: PreprocessorAdditionalData
2269
- } & ( { api ?: 'modern' | 'modern-compiler' } & SassModernPreprocessBaseOptions )
2269
+ } & SassModernPreprocessBaseOptions
2270
2270
2271
2271
export type LessPreprocessorOptions = {
2272
2272
additionalData ?: PreprocessorAdditionalData
@@ -2389,153 +2389,30 @@ function cleanScssBugUrl(url: string) {
2389
2389
2390
2390
// #region Sass
2391
2391
// .scss/.sass processor
2392
- const makeModernScssWorker = (
2392
+ const makeScssWorker = (
2393
2393
environment : PartialEnvironment ,
2394
2394
resolvers : CSSAtImportResolvers ,
2395
- maxWorkers : number | undefined ,
2395
+ _maxWorkers : number | undefined ,
2396
2396
) => {
2397
- const internalCanonicalize = async (
2398
- url : string ,
2399
- importer : string ,
2400
- ) : Promise < string | null > => {
2401
- importer = cleanScssBugUrl ( importer )
2402
- const resolved = await resolvers . sass ( environment , url , importer )
2403
- return resolved ?? null
2404
- }
2405
-
2406
- const skipRebaseUrls = ( unquotedUrl : string , rawUrl : string ) => {
2407
- const isQuoted = rawUrl [ 0 ] === '"' || rawUrl [ 0 ] === "'"
2408
- // matches `url($foo)`
2409
- if ( ! isQuoted && unquotedUrl [ 0 ] === '$' ) {
2410
- return true
2411
- }
2412
- // matches `url(#{foo})` and `url('#{foo}')`
2413
- return unquotedUrl . startsWith ( '#{' )
2414
- }
2415
-
2416
- const internalLoad = async ( file : string , rootFile : string ) => {
2417
- const result = await rebaseUrls (
2418
- environment ,
2419
- file ,
2420
- rootFile ,
2421
- resolvers . sass ,
2422
- skipRebaseUrls ,
2423
- )
2424
- if ( result . contents ) {
2425
- return result . contents
2426
- }
2427
- return await fsp . readFile ( result . file , 'utf-8' )
2428
- }
2397
+ let compilerPromise : Promise < Sass . AsyncCompiler > | undefined
2429
2398
2430
- const worker = new WorkerWithFallback (
2431
- ( ) =>
2432
- async (
2399
+ // we use the compiler api provided by sass
2400
+ // instead of creating a worker pool on our own
2401
+ type WorkerType = InstanceType <
2402
+ typeof WorkerWithFallback <
2403
+ [
2433
2404
sassPath : string ,
2434
2405
data : string ,
2435
2406
// additionalData can a function that is not cloneable but it won't be used
2436
2407
options : SassStylePreprocessorInternalOptions & {
2437
- api : 'modern'
2438
2408
additionalData : undefined
2439
2409
} ,
2440
- ) => {
2441
- // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker
2442
- const sass : typeof Sass = require ( sassPath )
2443
- // eslint-disable-next-line no-restricted-globals
2444
- const path : typeof import ( 'node:path' ) = require ( 'node:path' )
2445
-
2446
- const { fileURLToPath, pathToFileURL } : typeof import ( 'node:url' ) =
2447
- // eslint-disable-next-line no-restricted-globals
2448
- require ( 'node:url' )
2449
-
2450
- const sassOptions = { ...options } as Sass . StringOptions < 'async' >
2451
- sassOptions . url = pathToFileURL ( options . filename )
2452
- sassOptions . sourceMap = options . enableSourcemap
2453
-
2454
- const internalImporter : Sass . Importer < 'async' > = {
2455
- async canonicalize ( url , context ) {
2456
- const importer = context . containingUrl
2457
- ? fileURLToPath ( context . containingUrl )
2458
- : options . filename
2459
- const resolved = await internalCanonicalize ( url , importer )
2460
- if (
2461
- resolved &&
2462
- // only limit to these extensions because:
2463
- // - for the `@import`/`@use`s written in file loaded by `load` function,
2464
- // the `canonicalize` function of that `importer` is called first
2465
- // - the `load` function of an importer is only called for the importer
2466
- // that returned a non-null result from its `canonicalize` function
2467
- ( resolved . endsWith ( '.css' ) ||
2468
- resolved . endsWith ( '.scss' ) ||
2469
- resolved . endsWith ( '.sass' ) )
2470
- ) {
2471
- return pathToFileURL ( resolved )
2472
- }
2473
- return null
2474
- } ,
2475
- async load ( canonicalUrl ) {
2476
- const ext = path . extname ( canonicalUrl . pathname )
2477
- let syntax : Sass . Syntax = 'scss'
2478
- if ( ext === '.sass' ) {
2479
- syntax = 'indented'
2480
- } else if ( ext === '.css' ) {
2481
- syntax = 'css'
2482
- }
2483
- const contents = await internalLoad (
2484
- fileURLToPath ( canonicalUrl ) ,
2485
- options . filename ,
2486
- )
2487
- return { contents, syntax, sourceMapUrl : canonicalUrl }
2488
- } ,
2489
- }
2490
- sassOptions . importers = [
2491
- ...( sassOptions . importers ?? [ ] ) ,
2492
- internalImporter ,
2493
- ]
2494
-
2495
- const result = await sass . compileStringAsync ( data , sassOptions )
2496
- return {
2497
- css : result . css ,
2498
- map : result . sourceMap ? JSON . stringify ( result . sourceMap ) : undefined ,
2499
- stats : {
2500
- includedFiles : result . loadedUrls
2501
- . filter ( ( url ) => url . protocol === 'file:' )
2502
- . map ( ( url ) => fileURLToPath ( url ) ) ,
2503
- } ,
2504
- } satisfies ScssWorkerResult
2505
- } ,
2506
- {
2507
- parentFunctions : {
2508
- internalCanonicalize,
2509
- internalLoad,
2510
- } ,
2511
- shouldUseFake ( _sassPath , _data , options ) {
2512
- // functions and importer is a function and is not serializable
2513
- // in that case, fallback to running in main thread
2514
- return ! ! (
2515
- ( options . functions && Object . keys ( options . functions ) . length > 0 ) ||
2516
- ( options . importers &&
2517
- ( ! Array . isArray ( options . importers ) ||
2518
- options . importers . length > 0 ) ) ||
2519
- options . logger
2520
- )
2521
- } ,
2522
- max : maxWorkers ,
2523
- } ,
2524
- )
2525
- return worker
2526
- }
2527
-
2528
- // this is mostly a copy&paste of makeModernScssWorker
2529
- // however sharing code between two is hard because
2530
- // makeModernScssWorker above needs function inlined for worker.
2531
- const makeModernCompilerScssWorker = (
2532
- environment : PartialEnvironment ,
2533
- resolvers : CSSAtImportResolvers ,
2534
- _maxWorkers : number | undefined ,
2535
- ) => {
2536
- let compilerPromise : Promise < Sass . AsyncCompiler > | undefined
2410
+ ] ,
2411
+ ScssWorkerResult
2412
+ >
2413
+ >
2537
2414
2538
- const worker : Awaited < ReturnType < typeof makeModernScssWorker > > = {
2415
+ const worker : WorkerType = {
2539
2416
async run ( sassPath , data , options ) {
2540
2417
// need pathToFileURL for windows since import("D:...") fails
2541
2418
// https://github.com/nodejs/node/issues/31710
@@ -2632,25 +2509,15 @@ type ScssWorkerResult = {
2632
2509
const scssProcessor = (
2633
2510
maxWorkers : number | undefined ,
2634
2511
) : StylePreprocessor < SassStylePreprocessorInternalOptions > => {
2635
- let worker :
2636
- | ReturnType <
2637
- typeof makeModernScssWorker | typeof makeModernCompilerScssWorker
2638
- >
2639
- | undefined
2512
+ let worker : ReturnType < typeof makeScssWorker > | undefined
2640
2513
2641
2514
return {
2642
2515
close ( ) {
2643
2516
worker ?. stop ( )
2644
2517
} ,
2645
2518
async process ( environment , source , root , options , resolvers ) {
2646
2519
const sassPackage = loadSassPackage ( root )
2647
- const api =
2648
- options . api ??
2649
- ( sassPackage . name === 'sass-embedded' ? 'modern-compiler' : 'modern' )
2650
- worker ??=
2651
- api === 'modern-compiler'
2652
- ? makeModernCompilerScssWorker ( environment , resolvers , maxWorkers )
2653
- : makeModernScssWorker ( environment , resolvers , maxWorkers )
2520
+ worker ??= makeScssWorker ( environment , resolvers , maxWorkers )
2654
2521
2655
2522
const { content : data , map : additionalMap } = await getSource (
2656
2523
source ,
@@ -2667,7 +2534,6 @@ const scssProcessor = (
2667
2534
const result = await worker . run (
2668
2535
sassPackage . path ,
2669
2536
data ,
2670
- // @ts -expect-error the correct worker is selected for `options.type`
2671
2537
optionsWithoutAdditionalData ,
2672
2538
)
2673
2539
const deps = result . stats . includedFiles . map ( ( f ) => cleanScssBugUrl ( f ) )
0 commit comments