@@ -4,6 +4,8 @@ import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
4
4
import path from 'upath'
5
5
import { isObject , resolveVuetifyBase } from '@vuetify/loader-shared'
6
6
import { pathToFileURL } from 'node:url'
7
+ import fs from 'node:fs'
8
+ import fsp from 'node:fs/promises'
7
9
8
10
export type { ModuleOptions }
9
11
@@ -22,6 +24,7 @@ export default defineNuxtModule<ModuleOptions>({
22
24
let sassVariables = false
23
25
const PREFIX = 'vuetify-styles/'
24
26
const SSR_PREFIX = `/@${ PREFIX } `
27
+ const resolveCss = resolveCssFactory ( )
25
28
26
29
nuxt . hook ( 'vite:extendConfig' , viteInlineConfig => {
27
30
// add vuetify transformAssetUrls
@@ -39,6 +42,8 @@ export default defineNuxtModule<ModuleOptions>({
39
42
viteInlineConfig . css . preprocessorOptions ??= { }
40
43
viteInlineConfig . css . preprocessorOptions . sass ??= { }
41
44
viteInlineConfig . css . preprocessorOptions . sass . api = 'modern-compiler'
45
+ viteInlineConfig . css . preprocessorOptions . scss ??= { }
46
+ viteInlineConfig . css . preprocessorOptions . scss . api = 'modern-compiler'
42
47
43
48
viteInlineConfig . plugins . push ( {
44
49
name : 'vuetify:nuxt:styles' ,
@@ -59,7 +64,7 @@ export default defineNuxtModule<ModuleOptions>({
59
64
} ,
60
65
async resolveId ( source , importer , { custom, ssr } ) {
61
66
if ( source . startsWith ( PREFIX ) || source . startsWith ( SSR_PREFIX ) ) {
62
- if ( source . endsWith ( '.sass' ) ) {
67
+ if ( source . match ( / \. s [ c a ] s s $ / ) ) {
63
68
return source
64
69
}
65
70
@@ -74,16 +79,15 @@ export default defineNuxtModule<ModuleOptions>({
74
79
)
75
80
) {
76
81
if ( options . styles === 'sass' ) {
77
- const target = source . replace ( / \. c s s $ / , '.sass' )
78
- return this . resolve ( target , importer , { skipSelf : true , custom } )
82
+ return this . resolve ( await resolveCss ( source ) , importer , { skipSelf : true , custom } )
79
83
}
80
84
81
85
const resolution = await this . resolve ( source , importer , { skipSelf : true , custom } )
82
86
83
87
if ( ! resolution )
84
88
return undefined
85
89
86
- const target = resolution . id . replace ( / \. c s s $ / , '.sass' )
90
+ const target = await resolveCss ( resolution . id )
87
91
if ( isNone ) {
88
92
noneFiles . add ( target )
89
93
return target
@@ -103,8 +107,9 @@ export default defineNuxtModule<ModuleOptions>({
103
107
: undefined
104
108
105
109
if ( target ) {
110
+ const suffix = target . match ( / \. s c s s / ) ? ';\n' : '\n'
106
111
return {
107
- code : `@use "${ configFile } "\n @use "${ pathToFileURL ( target ) . href } "` ,
112
+ code : `@use "${ configFile } "${ suffix } @use "${ pathToFileURL ( target ) . href } "${ suffix } ` ,
108
113
map : {
109
114
mappings : '' ,
110
115
} ,
@@ -119,6 +124,26 @@ export default defineNuxtModule<ModuleOptions>({
119
124
} ,
120
125
} )
121
126
127
+ function resolveCssFactory ( ) {
128
+ const mappings = new Map < string , string > ( )
129
+ return async ( source : string ) => {
130
+ let mapping = mappings . get ( source )
131
+ if ( ! mapping ) {
132
+ try {
133
+ mapping = source . replace ( / \. c s s $ / , '.sass' )
134
+ await fsp . access ( mapping , fs . constants . R_OK )
135
+ }
136
+ catch ( err ) {
137
+ if ( ! ( err instanceof Error && 'code' in err && err . code === 'ENOENT' ) )
138
+ throw err
139
+ mapping = source . replace ( / \. c s s $ / , '.scss' )
140
+ }
141
+ mappings . set ( source , mapping )
142
+ }
143
+ return mapping
144
+ }
145
+ }
146
+
122
147
function isSubdir ( root : string , test : string ) {
123
148
const relative = path . relative ( root , test )
124
149
return relative && ! relative . startsWith ( '..' ) && ! path . isAbsolute ( relative )
0 commit comments