@@ -11,9 +11,14 @@ import type {
1111} from '@/types'
1212import path from 'node:path'
1313import process from 'node:process'
14+ import {
15+ normalizeUniAppXImportantApplyForSass ,
16+ restoreUniAppXImportantApplyMarker ,
17+ } from '@weapp-tailwindcss/postcss'
1418import { processCachedTask } from '@/bundlers/shared/cache'
1519import { hasTailwindApplyDirective , hasTailwindRootDirectives } from '@/bundlers/shared/generator-css/directives'
1620import { toAbsoluteOutputPath } from '@/bundlers/shared/module-graph'
21+ import { extractSfcStyleBlocks } from '@/bundlers/vite/generate-bundle/sfc-style-source'
1722import { parseVueRequest } from '@/bundlers/vite/query'
1823import { cleanUrl , formatPostcssSourceMap , isCSSRequest , normalizePath } from '@/bundlers/vite/utils'
1924import { logger } from '@/logger'
@@ -46,6 +51,9 @@ function loadTransformUVue(): Promise<TransformUVue> {
4651}
4752const UVUE_NVUE_QUERY_RE = / \. (?: u v u e | n v u e ) (?: \? .* ) ? $ /
4853const UVUE_NVUE_RE = / \. (?: u v u e | n v u e ) $ /
54+ function hasUniAppXImportantApply ( source : string ) {
55+ return extractSfcStyleBlocks ( source ) . some ( style => normalizeUniAppXImportantApplyForSass ( style . source ) !== style . source )
56+ }
4957function resolveUniAppXJsTransformEnabled ( uniAppX : InternalUserDefinedOptions [ 'uniAppX' ] | undefined ) {
5058 return uniAppX === undefined ? true : isUniAppXEnabled ( uniAppX )
5159}
@@ -92,6 +100,7 @@ export function createUniAppXPlugins(options: CreateUniAppXPluginsOptions): Plug
92100 }
93101 } > ( )
94102 const nativeLocalStyleModuleIds = new Set < string > ( )
103+ const knownSfcSources = new Map < string , string > ( )
95104 const webLocalStyle = createUniAppXWebLocalStyleBridge ( isWebGeneratorTarget )
96105 let componentLocalStyleEnabled : boolean | undefined
97106 const isNativeAppBuildTarget = createUniAppXNativeBuildTargetResolver ( getResolvedConfig )
@@ -169,7 +178,10 @@ export function createUniAppXPlugins(options: CreateUniAppXPluginsOptions): Plug
169178 if ( isCssModuleExport ( code ) ) {
170179 return
171180 }
172- const sourceCode = normalizeRelativeTailwindReferences ( code , id )
181+ const sourceCode = normalizeRelativeTailwindReferences (
182+ restoreUniAppXImportantApplyMarker ( code ) ,
183+ id ,
184+ )
173185 const hasTailwindRoot = hasTailwindRootDirectives ( sourceCode , { importFallback : true } )
174186 const hasTailwindApply = hasTailwindApplyDirective ( sourceCode )
175187 const shouldGenerateCss = hasTailwindRoot || hasTailwindApply
@@ -230,21 +242,45 @@ export function createUniAppXPlugins(options: CreateUniAppXPluginsOptions): Plug
230242 const cssPrePlugin : Plugin = {
231243 name : 'weapp-tailwindcss:uni-app-x:css:pre' ,
232244 enforce : 'pre' ,
233- async transform ( code , id ) {
234- if ( ! isEnabled ( ) ) {
235- return
236- }
237- await runtimeState . readyPromise
238- const { query } = parseVueRequest ( id )
239- const styleCode = query . vue && query . type === 'style' ? webLocalStyle . appendToStyle ( code , id ) : code
240- const preprocessor = resolvePreprocessorTransform ( styleCode , id , query . lang , {
241- isIosPlatform,
242- isNativeAppStyleTarget : isNativeAppStyleTarget ( ) ,
243- } )
244- if ( preprocessor ) {
245- return preprocessor . result ?? ( styleCode !== code ? { code : styleCode , map : null } : undefined )
246- }
247- return transformStyle ( styleCode , id , query , this )
245+ load : {
246+ order : 'pre' ,
247+ async handler ( id ) {
248+ const { filename, query } = parseVueRequest ( id )
249+ if ( ! query . vue || query . type !== 'style' || ! UVUE_NVUE_RE . test ( filename ) ) {
250+ return
251+ }
252+ const source = knownSfcSources . get ( filename )
253+ const style = source ? extractSfcStyleBlocks ( source ) [ query . index ?? 0 ] : undefined
254+ if ( ! style ) {
255+ return
256+ }
257+ const normalized = normalizeUniAppXImportantApplyForSass ( style . source )
258+ return normalized === style . source ? undefined : { code : normalized , map : null }
259+ } ,
260+ } ,
261+ transform : {
262+ order : 'pre' ,
263+ async handler ( code , id ) {
264+ if ( ! isEnabled ( ) ) {
265+ return
266+ }
267+ await runtimeState . readyPromise
268+ const { query } = parseVueRequest ( id )
269+ const styleCode = query . vue && query . type === 'style' ? webLocalStyle . appendToStyle ( code , id ) : code
270+ // Vite 热更新会绕过 SFC 主模块,直接把原始样式交给预处理器;先移除
271+ // Sass 无法解析的 important utility 后,再由后续 CSS 阶段还原。
272+ const preprocessorCode = query . vue && query . type === 'style'
273+ ? normalizeUniAppXImportantApplyForSass ( styleCode )
274+ : styleCode
275+ const preprocessor = resolvePreprocessorTransform ( preprocessorCode , id , query . lang , {
276+ isIosPlatform,
277+ isNativeAppStyleTarget : isNativeAppStyleTarget ( ) ,
278+ } )
279+ if ( preprocessor ) {
280+ return preprocessor . result ?? ( preprocessorCode !== code ? { code : preprocessorCode , map : null } : undefined )
281+ }
282+ return transformStyle ( preprocessorCode , id , query , this )
283+ } ,
248284 } ,
249285 }
250286 const cssPlugin : Plugin = {
@@ -261,6 +297,7 @@ export function createUniAppXPlugins(options: CreateUniAppXPluginsOptions): Plug
261297 const cssPlugins = [ cssPlugin , cssPrePlugin ]
262298
263299 async function transformSfc ( code : string , id : string , context : { addWatchFile ?: ( id : string ) => void } ) {
300+ knownSfcSources . set ( cleanUrl ( id ) , code )
264301 if ( isNativeAppBuildTarget ( id ) ) {
265302 nativeLocalStyleModuleIds . add ( id )
266303 nativeLocalStyleModuleIds . add ( cleanUrl ( id ) )
@@ -285,6 +322,7 @@ export function createUniAppXPlugins(options: CreateUniAppXPluginsOptions): Plug
285322 ...( disabledDefaultTemplateHandler ? { disabledDefaultTemplateHandler } : { } ) ,
286323 ...( enableComponentLocalStyle ? { enableComponentLocalStyle } : { } ) ,
287324 ...( enablePageLocalStyle ? { enablePageLocalStyle } : { } ) ,
325+ native : true ,
288326 pageMatcher : resolvedUniAppXOptions . componentLocalStyles . pageMatcher ,
289327 ...( isWebGeneratorTarget ( ) && customAttributesEntities . length > 0 ? { webCustomAttributeDeep : true } : { } ) ,
290328 ...( isWebGeneratorTarget ( ) ? { onWebLocalStyleRules : ( rules : string ) => webLocalStyle . remember ( id , rules ) } : { } ) ,
@@ -322,7 +360,7 @@ export function createUniAppXPlugins(options: CreateUniAppXPluginsOptions): Plug
322360 } ,
323361 } ,
324362 handleHotUpdate : {
325- order : 'post ' ,
363+ order : 'pre ' ,
326364 async handler ( ctx ) {
327365 if ( ! isEnabled ( ) || getResolvedConfig ( ) ?. command !== 'serve' ) {
328366 return
@@ -331,7 +369,12 @@ export function createUniAppXPlugins(options: CreateUniAppXPluginsOptions): Plug
331369 return
332370 }
333371 if ( isWebGeneratorTarget ( ) && UVUE_NVUE_RE . test ( ctx . file ) && typeof ctx . read === 'function' ) {
334- await transformSfc ( await ctx . read ( ) , ctx . file , this )
372+ const source = await ctx . read ( )
373+ if ( hasUniAppXImportantApply ( source ) ) {
374+ ctx . server . ws . send ( { type : 'full-reload' , path : ctx . file } )
375+ return [ ]
376+ }
377+ await transformSfc ( source , ctx . file , this )
335378 }
336379 return webLocalStyle . handleHotUpdate ( ctx ) ?? nativeHmrReloader . handleHotUpdate ( ctx )
337380 } ,
0 commit comments