Skip to content

Commit ad7d447

Browse files
committed
refactor: port vuetify nuxt module from #86
1 parent 9892f24 commit ad7d447

File tree

1 file changed

+30
-5
lines changed

1 file changed

+30
-5
lines changed

template/typescript/nuxt/modules/vuetify.ts

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
44
import path from 'upath'
55
import { isObject, resolveVuetifyBase } from '@vuetify/loader-shared'
66
import { pathToFileURL } from 'node:url'
7+
import fs from 'node:fs'
8+
import fsp from 'node:fs/promises'
79

810
export type { ModuleOptions }
911

@@ -22,6 +24,7 @@ export default defineNuxtModule<ModuleOptions>({
2224
let sassVariables = false
2325
const PREFIX = 'vuetify-styles/'
2426
const SSR_PREFIX = `/@${PREFIX}`
27+
const resolveCss = resolveCssFactory()
2528

2629
nuxt.hook('vite:extendConfig', viteInlineConfig => {
2730
// add vuetify transformAssetUrls
@@ -39,6 +42,8 @@ export default defineNuxtModule<ModuleOptions>({
3942
viteInlineConfig.css.preprocessorOptions ??= {}
4043
viteInlineConfig.css.preprocessorOptions.sass ??= {}
4144
viteInlineConfig.css.preprocessorOptions.sass.api = 'modern-compiler'
45+
viteInlineConfig.css.preprocessorOptions.scss ??= {}
46+
viteInlineConfig.css.preprocessorOptions.scss.api = 'modern-compiler'
4247

4348
viteInlineConfig.plugins.push({
4449
name: 'vuetify:nuxt:styles',
@@ -59,7 +64,7 @@ export default defineNuxtModule<ModuleOptions>({
5964
},
6065
async resolveId (source, importer, { custom, ssr }) {
6166
if (source.startsWith(PREFIX) || source.startsWith(SSR_PREFIX)) {
62-
if (source.endsWith('.sass')) {
67+
if (source.match(/\.s[ca]ss$/)) {
6368
return source
6469
}
6570

@@ -74,16 +79,15 @@ export default defineNuxtModule<ModuleOptions>({
7479
)
7580
) {
7681
if (options.styles === 'sass') {
77-
const target = source.replace(/\.css$/, '.sass')
78-
return this.resolve(target, importer, { skipSelf: true, custom })
82+
return this.resolve(await resolveCss(source), importer, { skipSelf: true, custom })
7983
}
8084

8185
const resolution = await this.resolve(source, importer, { skipSelf: true, custom })
8286

8387
if (!resolution)
8488
return undefined
8589

86-
const target = resolution.id.replace(/\.css$/, '.sass')
90+
const target = await resolveCss(resolution.id)
8791
if (isNone) {
8892
noneFiles.add(target)
8993
return target
@@ -103,8 +107,9 @@ export default defineNuxtModule<ModuleOptions>({
103107
: undefined
104108

105109
if (target) {
110+
const suffix = target.match(/\.scss/) ? ';\n' : '\n'
106111
return {
107-
code: `@use "${configFile}"\n@use "${pathToFileURL(target).href}"`,
112+
code: `@use "${configFile}"${suffix}@use "${pathToFileURL(target).href}"${suffix}`,
108113
map: {
109114
mappings: '',
110115
},
@@ -119,6 +124,26 @@ export default defineNuxtModule<ModuleOptions>({
119124
},
120125
})
121126

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(/\.css$/, '.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(/\.css$/, '.scss')
140+
}
141+
mappings.set(source, mapping)
142+
}
143+
return mapping
144+
}
145+
}
146+
122147
function isSubdir (root: string, test: string) {
123148
const relative = path.relative(root, test)
124149
return relative && !relative.startsWith('..') && !path.isAbsolute(relative)

0 commit comments

Comments
 (0)