@@ -1279,10 +1279,6 @@ async function compileCSS(
1279
1279
deps ?: Set < string >
1280
1280
} > {
1281
1281
const { config } = environment
1282
- if ( config . css . transformer === 'lightningcss' ) {
1283
- return compileLightningCSS ( id , code , environment , urlResolver )
1284
- }
1285
-
1286
1282
const lang = CSS_LANGS_RE . exec ( id ) ?. [ 1 ] as CssLang | undefined
1287
1283
const deps = new Set < string > ( )
1288
1284
@@ -1299,8 +1295,71 @@ async function compileCSS(
1299
1295
code = preprocessorResult . code
1300
1296
preprocessorMap = preprocessorResult . map
1301
1297
preprocessorResult . deps ?. forEach ( ( dep ) => deps . add ( dep ) )
1298
+ } else if ( lang === 'sss' && config . css . transformer === 'lightningcss' ) {
1299
+ const sssResult = await transformSugarSS ( environment , id , code )
1300
+ code = sssResult . code
1301
+ preprocessorMap = sssResult . map
1302
+ }
1303
+
1304
+ const transformResult = await ( config . css . transformer === 'lightningcss'
1305
+ ? compileLightningCSS (
1306
+ environment ,
1307
+ id ,
1308
+ code ,
1309
+ deps ,
1310
+ workerController ,
1311
+ urlResolver ,
1312
+ )
1313
+ : compilePostCSS (
1314
+ environment ,
1315
+ id ,
1316
+ code ,
1317
+ deps ,
1318
+ lang ,
1319
+ workerController ,
1320
+ urlResolver ,
1321
+ ) )
1322
+
1323
+ if ( ! transformResult ) {
1324
+ return {
1325
+ code,
1326
+ map : config . css . devSourcemap ? preprocessorMap : { mappings : '' } ,
1327
+ deps,
1328
+ }
1302
1329
}
1303
1330
1331
+ return {
1332
+ ...transformResult ,
1333
+ map : config . css . devSourcemap
1334
+ ? combineSourcemapsIfExists (
1335
+ cleanUrl ( id ) ,
1336
+ typeof transformResult . map === 'string'
1337
+ ? JSON . parse ( transformResult . map )
1338
+ : transformResult . map ,
1339
+ preprocessorMap ,
1340
+ )
1341
+ : { mappings : '' } ,
1342
+ deps,
1343
+ }
1344
+ }
1345
+
1346
+ async function compilePostCSS (
1347
+ environment : PartialEnvironment ,
1348
+ id : string ,
1349
+ code : string ,
1350
+ deps : Set < string > ,
1351
+ lang : CssLang | undefined ,
1352
+ workerController : PreprocessorWorkerController ,
1353
+ urlResolver ?: CssUrlResolver ,
1354
+ ) : Promise <
1355
+ | {
1356
+ code : string
1357
+ map ?: Exclude < SourceMapInput , string >
1358
+ modules ?: Record < string , string >
1359
+ }
1360
+ | undefined
1361
+ > {
1362
+ const { config } = environment
1304
1363
const { modules : modulesOptions , devSourcemap } = config . css
1305
1364
const isModule = modulesOptions !== false && cssModuleRE . test ( id )
1306
1365
// although at serve time it can work without processing, we do need to
@@ -1319,7 +1378,7 @@ async function compileCSS(
1319
1378
! needInlineImport &&
1320
1379
! hasUrl
1321
1380
) {
1322
- return { code , map : preprocessorMap ?? null , deps }
1381
+ return
1323
1382
}
1324
1383
1325
1384
// postcss
@@ -1443,11 +1502,7 @@ async function compileCSS(
1443
1502
lang === 'sss' ? loadSss ( config . root ) : postcssOptions . parser
1444
1503
1445
1504
if ( ! postcssPlugins . length && ! postcssParser ) {
1446
- return {
1447
- code,
1448
- map : preprocessorMap ,
1449
- deps,
1450
- }
1505
+ return
1451
1506
}
1452
1507
1453
1508
let postcssResult : PostCSS . Result
@@ -1527,12 +1582,10 @@ async function compileCSS(
1527
1582
code : postcssResult . css ,
1528
1583
map : { mappings : '' } ,
1529
1584
modules,
1530
- deps,
1531
1585
}
1532
1586
}
1533
1587
1534
1588
const rawPostcssMap = postcssResult . map . toJSON ( )
1535
-
1536
1589
const postcssMap = await formatPostcssSourceMap (
1537
1590
// version property of rawPostcssMap is declared as string
1538
1591
// but actually it is a number
@@ -1542,9 +1595,92 @@ async function compileCSS(
1542
1595
1543
1596
return {
1544
1597
code : postcssResult . css ,
1545
- map : combineSourcemapsIfExists ( cleanUrl ( id ) , postcssMap , preprocessorMap ) ,
1598
+ map : postcssMap ,
1546
1599
modules,
1547
- deps,
1600
+ }
1601
+ }
1602
+
1603
+ // TODO: dedupe
1604
+ async function transformSugarSS (
1605
+ environment : PartialEnvironment ,
1606
+ id : string ,
1607
+ code : string ,
1608
+ ) {
1609
+ const { config } = environment
1610
+ const { devSourcemap } = config . css
1611
+
1612
+ let postcssResult : PostCSS . Result
1613
+ try {
1614
+ const source = removeDirectQuery ( id )
1615
+ const postcss = await importPostcss ( )
1616
+ // postcss is an unbundled dep and should be lazy imported
1617
+ postcssResult = await postcss . default ( ) . process ( code , {
1618
+ parser : loadSss ( config . root ) ,
1619
+ to : source ,
1620
+ from : source ,
1621
+ ...( devSourcemap
1622
+ ? {
1623
+ map : {
1624
+ inline : false ,
1625
+ annotation : false ,
1626
+ // postcss may return virtual files
1627
+ // we cannot obtain content of them, so this needs to be enabled
1628
+ sourcesContent : true ,
1629
+ // when "prev: preprocessorMap", the result map may include duplicate filename in `postcssResult.map.sources`
1630
+ // prev: preprocessorMap,
1631
+ } ,
1632
+ }
1633
+ : { } ) ,
1634
+ } )
1635
+
1636
+ for ( const message of postcssResult . messages ) {
1637
+ if ( message . type === 'warning' ) {
1638
+ const warning = message as PostCSS . Warning
1639
+ let msg = `[vite:css] ${ warning . text } `
1640
+ msg += `\n${ generateCodeFrame (
1641
+ code ,
1642
+ {
1643
+ line : warning . line ,
1644
+ column : warning . column - 1 , // 1-based
1645
+ } ,
1646
+ warning . endLine !== undefined && warning . endColumn !== undefined
1647
+ ? {
1648
+ line : warning . endLine ,
1649
+ column : warning . endColumn - 1 , // 1-based
1650
+ }
1651
+ : undefined ,
1652
+ ) } `
1653
+ environment . logger . warn ( colors . yellow ( msg ) )
1654
+ }
1655
+ }
1656
+ } catch ( e ) {
1657
+ e . message = `[postcss] ${ e . message } `
1658
+ e . code = code
1659
+ e . loc = {
1660
+ file : e . file ,
1661
+ line : e . line ,
1662
+ column : e . column - 1 , // 1-based
1663
+ }
1664
+ throw e
1665
+ }
1666
+
1667
+ if ( ! devSourcemap ) {
1668
+ return {
1669
+ code : postcssResult . css ,
1670
+ }
1671
+ }
1672
+
1673
+ const rawPostcssMap = postcssResult . map . toJSON ( )
1674
+ const postcssMap = await formatPostcssSourceMap (
1675
+ // version property of rawPostcssMap is declared as string
1676
+ // but actually it is a number
1677
+ rawPostcssMap as Omit < RawSourceMap , 'version' > as ExistingRawSourceMap ,
1678
+ cleanUrl ( id ) ,
1679
+ )
1680
+
1681
+ return {
1682
+ code : postcssResult . css ,
1683
+ map : postcssMap ,
1548
1684
}
1549
1685
}
1550
1686
@@ -3194,13 +3330,18 @@ function isPreProcessor(lang: any): lang is PreprocessLang {
3194
3330
3195
3331
const importLightningCSS = createCachedImport ( ( ) => import ( 'lightningcss' ) )
3196
3332
async function compileLightningCSS (
3333
+ environment : PartialEnvironment ,
3197
3334
id : string ,
3198
3335
src : string ,
3199
- environment : PartialEnvironment ,
3336
+ deps : Set < string > ,
3337
+ workerController : PreprocessorWorkerController ,
3200
3338
urlResolver ?: CssUrlResolver ,
3201
- ) : ReturnType < typeof compileCSS > {
3339
+ ) : Promise < {
3340
+ code : string
3341
+ map ?: string | undefined
3342
+ modules ?: Record < string , string >
3343
+ } > {
3202
3344
const { config } = environment
3203
- const deps = new Set < string > ( )
3204
3345
// replace null byte as lightningcss treats that as a string terminator
3205
3346
// https://github.com/parcel-bundler/lightningcss/issues/874
3206
3347
const filename = id . replace ( '\0' , NULL_BYTE_PLACEHOLDER )
@@ -3223,11 +3364,32 @@ async function compileLightningCSS(
3223
3364
// projectRoot is needed to get stable hash when using CSS modules
3224
3365
projectRoot : config . root ,
3225
3366
resolver : {
3226
- read ( filePath ) {
3367
+ async read ( filePath ) {
3227
3368
if ( filePath === filename ) {
3228
3369
return src
3229
3370
}
3230
- return fs . readFileSync ( filePath , 'utf-8' )
3371
+
3372
+ const code = fs . readFileSync ( filePath , 'utf-8' )
3373
+ const lang = CSS_LANGS_RE . exec ( filePath ) ?. [ 1 ] as
3374
+ | CssLang
3375
+ | undefined
3376
+ if ( isPreProcessor ( lang ) ) {
3377
+ const result = await compileCSSPreprocessors (
3378
+ environment ,
3379
+ id ,
3380
+ lang ,
3381
+ code ,
3382
+ workerController ,
3383
+ )
3384
+ result . deps ?. forEach ( ( dep ) => deps . add ( dep ) )
3385
+ // TODO: support source map
3386
+ return result . code
3387
+ } else if ( lang === 'sss' ) {
3388
+ const sssResult = await transformSugarSS ( environment , id , code )
3389
+ // TODO: support source map
3390
+ return sssResult . code
3391
+ }
3392
+ return code
3231
3393
} ,
3232
3394
async resolve ( id , from ) {
3233
3395
const publicFile = checkPublicFile (
@@ -3238,10 +3400,34 @@ async function compileLightningCSS(
3238
3400
return publicFile
3239
3401
}
3240
3402
3241
- const resolved = await getAtImportResolvers (
3403
+ // NOTE: with `transformer: 'postcss'`, CSS modules `composes` tried to resolve with
3404
+ // all resolvers, but in `transformer: 'lightningcss'`, only the one for the
3405
+ // current file type is used.
3406
+ const atImportResolvers = getAtImportResolvers (
3242
3407
environment . getTopLevelConfig ( ) ,
3243
- ) . css ( environment , id , from )
3408
+ )
3409
+ const lang = CSS_LANGS_RE . exec ( from ) ?. [ 1 ] as CssLang | undefined
3410
+ let resolver : ResolveIdFn
3411
+ switch ( lang ) {
3412
+ case 'css' :
3413
+ case 'sss' :
3414
+ case 'styl' :
3415
+ case 'stylus' :
3416
+ case undefined :
3417
+ resolver = atImportResolvers . css
3418
+ break
3419
+ case 'sass' :
3420
+ case 'scss' :
3421
+ resolver = atImportResolvers . sass
3422
+ break
3423
+ case 'less' :
3424
+ resolver = atImportResolvers . less
3425
+ break
3426
+ default :
3427
+ throw new Error ( `Unknown lang: ${ lang satisfies never } ` )
3428
+ }
3244
3429
3430
+ const resolved = await resolver ( environment , id , from )
3245
3431
if ( resolved ) {
3246
3432
deps . add ( resolved )
3247
3433
return resolved
@@ -3356,7 +3542,6 @@ async function compileLightningCSS(
3356
3542
return {
3357
3543
code : css ,
3358
3544
map : 'map' in res ? res . map ?. toString ( ) : undefined ,
3359
- deps,
3360
3545
modules,
3361
3546
}
3362
3547
}
0 commit comments