1
1
import type { LoaderContext } from 'webpack'
2
2
import { ECacheKey , ILightningCssLoaderConfig } from './interface'
3
- import { transform as _transform } from 'lightningcss'
3
+ import lightningcss from 'lightningcss'
4
4
import { Buffer } from 'buffer'
5
5
import { getTargets } from './utils'
6
6
7
7
const LOADER_NAME = `lightningcss-loader`
8
+
9
+ // match `Custom media query {} is not defined`
10
+ // https://github.com/parcel-bundler/lightningcss/blob/master/src/error.rs#L375
11
+ const CUSTOM_MEDIA_ERROR_REG = / C u s t o m m e d i a q u e r y ( .+ ?) i s n o t d e f i n e d /
12
+ const isCustomMediaError = ( err ?: Error ) => {
13
+ const msg = err ?. message
14
+ if ( ! msg ?. length ) {
15
+ return false
16
+ }
17
+ const isMatch = CUSTOM_MEDIA_ERROR_REG . test ( msg )
18
+ return isMatch
19
+ }
20
+
8
21
export async function LightningCssLoader (
9
22
this : LoaderContext < ILightningCssLoaderConfig > ,
10
23
source : string ,
@@ -23,21 +36,53 @@ export async function LightningCssLoader(
23
36
return
24
37
}
25
38
26
- const transform = implementation ?. transform ?? _transform
39
+ const transform = implementation ?. transform ?? lightningcss . transform
40
+ const bundle = implementation ?. bundle ?? lightningcss . bundle
41
+
42
+ const filename = this . resourcePath
43
+ const enableSourceMap = this . sourceMap
44
+ const targets = getTargets ( { default : userTargets , key : ECacheKey . loader } )
45
+ const inputSourceMap =
46
+ enableSourceMap && prevMap ? JSON . stringify ( prevMap ) : undefined
27
47
28
48
try {
49
+ const codeBuffer = Buffer . from ( source )
50
+
29
51
const { code, map } = transform ( {
30
- filename : this . resourcePath ,
31
- code : Buffer . from ( source ) ,
32
- sourceMap : this . sourceMap ,
33
- targets : getTargets ( { default : userTargets , key : ECacheKey . loader } ) ,
34
- inputSourceMap :
35
- this . sourceMap && prevMap ? JSON . stringify ( prevMap ) : undefined ,
52
+ filename,
53
+ code : codeBuffer ,
54
+ sourceMap : enableSourceMap ,
55
+ targets,
56
+ inputSourceMap,
36
57
...opts ,
37
58
} )
38
59
const codeAsString = code . toString ( )
39
60
done ( null , codeAsString , map && JSON . parse ( map . toString ( ) ) )
40
61
} catch ( error : unknown ) {
62
+ // support @custom -media queries
63
+ const isCustomMediaEnabled = opts ?. drafts ?. customMedia === true
64
+ if ( isCustomMediaEnabled ) {
65
+ const canBundle =
66
+ typeof bundle === 'function' &&
67
+ isCustomMediaError ( error as Error ) &&
68
+ filename
69
+ if ( canBundle ) {
70
+ // fallback to bundle API
71
+ try {
72
+ const { code, map } = bundle ( {
73
+ filename,
74
+ sourceMap : enableSourceMap ,
75
+ targets,
76
+ inputSourceMap,
77
+ ...opts ,
78
+ } )
79
+ const codeAsString = code . toString ( )
80
+ done ( null , codeAsString , map && JSON . parse ( map . toString ( ) ) )
81
+ return
82
+ } catch { }
83
+ }
84
+ }
85
+
41
86
done ( error as Error )
42
87
}
43
88
}
0 commit comments