@@ -858,6 +858,72 @@ function getCssResolversKeys(
858858 return Object . keys ( resolvers ) as unknown as Array < keyof CSSAtImportResolvers >
859859}
860860
861+ async function compileCSSPreprocessors (
862+ id : string ,
863+ lang : PreprocessLang ,
864+ code : string ,
865+ config : ResolvedConfig ,
866+ ) : Promise < { code : string ; map ?: ExistingRawSourceMap ; deps ?: Set < string > } > {
867+ const { preprocessorOptions, devSourcemap } = config . css ?? { }
868+ const atImportResolvers = getAtImportResolvers ( config )
869+
870+ const preProcessor = preProcessors [ lang ]
871+ let opts = ( preprocessorOptions && preprocessorOptions [ lang ] ) || { }
872+ // support @import from node dependencies by default
873+ switch ( lang ) {
874+ case PreprocessLang . scss :
875+ case PreprocessLang . sass :
876+ opts = {
877+ includePaths : [ 'node_modules' ] ,
878+ alias : config . resolve . alias ,
879+ ...opts ,
880+ }
881+ break
882+ case PreprocessLang . less :
883+ case PreprocessLang . styl :
884+ case PreprocessLang . stylus :
885+ opts = {
886+ paths : [ 'node_modules' ] ,
887+ alias : config . resolve . alias ,
888+ ...opts ,
889+ }
890+ }
891+ // important: set this for relative import resolving
892+ opts . filename = cleanUrl ( id )
893+ opts . enableSourcemap = devSourcemap ?? false
894+
895+ const preprocessResult = await preProcessor (
896+ code ,
897+ config . root ,
898+ opts ,
899+ atImportResolvers ,
900+ )
901+ if ( preprocessResult . error ) {
902+ throw preprocessResult . error
903+ }
904+
905+ let deps : Set < string > | undefined
906+ if ( preprocessResult . deps ) {
907+ const normalizedFilename = normalizePath ( opts . filename )
908+ // sometimes sass registers the file itself as a dep
909+ deps = new Set (
910+ [ ...preprocessResult . deps ] . filter (
911+ ( dep ) => normalizePath ( dep ) !== normalizedFilename ,
912+ ) ,
913+ )
914+ }
915+
916+ return {
917+ code : preprocessResult . code ,
918+ map : combineSourcemapsIfExists (
919+ opts . filename ,
920+ preprocessResult . map ,
921+ preprocessResult . additionalMap ,
922+ ) ,
923+ deps,
924+ }
925+ }
926+
861927const configToAtImportResolvers = new WeakMap <
862928 ResolvedConfig ,
863929 CSSAtImportResolvers
@@ -887,11 +953,7 @@ async function compileCSS(
887953 return compileLightningCSS ( id , code , config , urlReplacer )
888954 }
889955
890- const {
891- modules : modulesOptions ,
892- preprocessorOptions,
893- devSourcemap,
894- } = config . css || { }
956+ const { modules : modulesOptions , devSourcemap } = config . css || { }
895957 const isModule = modulesOptions !== false && cssModuleRE . test ( id )
896958 // although at serve time it can work without processing, we do need to
897959 // crawl them in order to register watch dependencies.
@@ -911,68 +973,25 @@ async function compileCSS(
911973 return { code, map : null }
912974 }
913975
914- let preprocessorMap : ExistingRawSourceMap | undefined
915976 let modules : Record < string , string > | undefined
916977 const deps = new Set < string > ( )
917978
918- const atImportResolvers = getAtImportResolvers ( config )
919-
920979 // 2. pre-processors: sass etc.
980+ let preprocessorMap : ExistingRawSourceMap | undefined
921981 if ( isPreProcessor ( lang ) ) {
922- const preProcessor = preProcessors [ lang ]
923- let opts = ( preprocessorOptions && preprocessorOptions [ lang ] ) || { }
924- // support @import from node dependencies by default
925- switch ( lang ) {
926- case PreprocessLang . scss :
927- case PreprocessLang . sass :
928- opts = {
929- includePaths : [ 'node_modules' ] ,
930- alias : config . resolve . alias ,
931- ...opts ,
932- }
933- break
934- case PreprocessLang . less :
935- case PreprocessLang . styl :
936- case PreprocessLang . stylus :
937- opts = {
938- paths : [ 'node_modules' ] ,
939- alias : config . resolve . alias ,
940- ...opts ,
941- }
942- }
943- // important: set this for relative import resolving
944- opts . filename = cleanUrl ( id )
945- opts . enableSourcemap = devSourcemap ?? false
946-
947- const preprocessResult = await preProcessor (
982+ const preprocessorResult = await compileCSSPreprocessors (
983+ id ,
984+ lang ,
948985 code ,
949- config . root ,
950- opts ,
951- atImportResolvers ,
986+ config ,
952987 )
953-
954- if ( preprocessResult . error ) {
955- throw preprocessResult . error
956- }
957-
958- code = preprocessResult . code
959- preprocessorMap = combineSourcemapsIfExists (
960- opts . filename ,
961- preprocessResult . map ,
962- preprocessResult . additionalMap ,
963- )
964-
965- if ( preprocessResult . deps ) {
966- preprocessResult . deps . forEach ( ( dep ) => {
967- // sometimes sass registers the file itself as a dep
968- if ( normalizePath ( dep ) !== normalizePath ( opts . filename ) ) {
969- deps . add ( dep )
970- }
971- } )
972- }
988+ code = preprocessorResult . code
989+ preprocessorMap = preprocessorResult . map
990+ preprocessorResult . deps ?. forEach ( ( dep ) => deps . add ( dep ) )
973991 }
974992
975993 // 3. postcss
994+ const atImportResolvers = getAtImportResolvers ( config )
976995 const postcssOptions = ( postcssConfig && postcssConfig . options ) || { }
977996
978997 const postcssPlugins =
@@ -1010,10 +1029,15 @@ async function compileCSS(
10101029 return id
10111030 } ,
10121031 async load ( id ) {
1013- const code = fs . readFileSync ( id , 'utf-8' )
1014- const result = await compileCSS ( id , code , config )
1015- result . deps ?. forEach ( ( dep ) => deps . add ( dep ) )
1016- return result . code
1032+ const code = await fs . promises . readFile ( id , 'utf-8' )
1033+ const lang = id . match ( CSS_LANGS_RE ) ?. [ 1 ] as CssLang | undefined
1034+ if ( isPreProcessor ( lang ) ) {
1035+ const result = await compileCSSPreprocessors ( id , lang , code , config )
1036+ result . deps ?. forEach ( ( dep ) => deps . add ( dep ) )
1037+ // TODO: support source map
1038+ return result . code
1039+ }
1040+ return code
10171041 } ,
10181042 nameLayer ( index ) {
10191043 return `vite--anon-layer-${ getHash ( id ) } -${ index } `
0 commit comments