Skip to content

Commit 98ef110

Browse files
userquinKaelWD
andauthored
fix(styles): resolve new scss component styles (#345)
Co-authored-by: Kael <[email protected]>
1 parent d576a17 commit 98ef110

File tree

5 files changed

+51
-8
lines changed

5 files changed

+51
-8
lines changed

dev/src/App.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<v-card-text>
1010
<v-text-field></v-text-field>
1111
<v-btn></v-btn>
12+
<v-icon-btn icon="$vuetify"></v-icon-btn>
1213
<!-- <v-list>-->
1314
<!-- <v-list-item title="List"></v-list-item>-->
1415
<!-- <v-list-group>-->

dev/vite.config.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ export default defineConfig(({ command }) => ({
1010
plugins: [
1111
vue(),
1212
vuetify({
13-
autoImport: true,
13+
autoImport: {
14+
labs: true,
15+
},
1416
styles: {
1517
configFile: 'settings.scss',
1618
},

dev/webpack.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ module.exports = {
9191
plugins: [
9292
new VueLoaderPlugin(),
9393
new VuetifyPlugin({
94+
autoImport: {
95+
labs: true,
96+
},
9497
styles: {
9598
configFile: './src/settings.scss',
9699
},

packages/vite-plugin/src/stylesPlugin.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from 'upath'
2+
import fs from 'node:fs/promises'
23
import { resolveVuetifyBase, normalizePath, isObject } from '@vuetify/loader-shared'
34

45
import type { Plugin } from 'vite'
@@ -18,6 +19,23 @@ export function stylesPlugin (options: Options): Plugin {
1819

1920
let configFile: string
2021
const tempFiles = new Map<string, string>()
22+
const mappings = new Map<string, string>()
23+
24+
async function resolveCss(target: string) {
25+
let mapping = mappings.get(target)
26+
if (!mapping) {
27+
try {
28+
mapping = target.replace(/\.css$/, '.sass')
29+
await fs.access(mapping, fs.constants.R_OK)
30+
} catch (err) {
31+
if (!(err instanceof Error && 'code' in err && err.code === 'ENOENT')) throw err
32+
mapping = target.replace(/\.css$/, '.scss')
33+
}
34+
mappings.set(target, mapping)
35+
}
36+
37+
return mapping
38+
}
2139

2240
return {
2341
name: 'vuetify:styles',
@@ -42,16 +60,17 @@ export function stylesPlugin (options: Options): Plugin {
4260
if (options.styles === 'none') {
4361
return `${PLUGIN_VIRTUAL_PREFIX}__void__`
4462
} else if (options.styles === 'sass') {
45-
const target = source.replace(/\.css$/, '.sass')
63+
const target = await resolveCss(source)
4664
return this.resolve(target, importer, { skipSelf: true, custom })
4765
} else if (isObject(options.styles)) {
4866
const resolution = await this.resolve(source, importer, { skipSelf: true, custom })
4967

5068
if (!resolution) return null
5169

52-
const target = resolution.id.replace(/\.css$/, '.sass')
70+
const target = await resolveCss(resolution.id)
5371
const file = path.relative(path.join(vuetifyBase, 'lib'), target)
54-
const contents = `@use "${normalizePath(configFile)}"\n@use "${normalizePath(target)}"`
72+
const suffix = target.match(/\.scss/) ? ';\n' : '\n'
73+
const contents = `@use "${normalizePath(configFile)}"${suffix}@use "${normalizePath(target)}"${suffix}`
5574

5675
tempFiles.set(file, contents)
5776

packages/webpack-plugin/src/plugin.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { URLSearchParams } from 'url'
2-
import { writeFile } from 'fs/promises'
2+
import fs from 'fs/promises'
33

44
import path from 'upath'
55
import mkdirp from 'mkdirp'
@@ -76,6 +76,22 @@ export class VuetifyPlugin {
7676
})
7777
}
7878

79+
const stylesCache = new Map<string, string>()
80+
async function resolveCSS (target: string) {
81+
let result = stylesCache.get(target)
82+
if (!result) {
83+
try {
84+
result = target.replace(/\.css$/, '.sass')
85+
await fs.access(result, fs.constants.R_OK)
86+
} catch (err) {
87+
if (!(err instanceof Error && 'code' in err && err.code === 'ENOENT')) throw err
88+
result = target.replace(/\.css$/, '.scss')
89+
}
90+
stylesCache.set(target, result)
91+
}
92+
return result
93+
}
94+
7995
if (this.options.styles === 'none') {
8096
compiler.options.module.rules.push({
8197
enforce: 'pre',
@@ -85,7 +101,7 @@ export class VuetifyPlugin {
85101
loader: 'null-loader',
86102
})
87103
} else if (this.options.styles === 'sass') {
88-
hookResolve(file => file.replace(/\.css$/, '.sass'))
104+
hookResolve(resolveCSS)
89105
} else if (isObject(this.options.styles)) {
90106
const findCacheDir = (await import('find-cache-dir')).default
91107
const cacheDir = findCacheDir({
@@ -100,12 +116,14 @@ export class VuetifyPlugin {
100116
)
101117

102118
hookResolve(async request => {
103-
const target = request.replace(/\.css$/, '.sass')
119+
const target = await resolveCSS(request)
104120
const file = path.relative(vuetifyBase, target)
105121
const cacheFile = path.join(cacheDir, file)
122+
const suffix = target.match(/\.scss/) ? ';\n' : '\n'
123+
const contents = `@use "${normalizePath(configFile)}"${suffix}@use "${normalizePath(target)}"${suffix}`
106124

107125
await mkdirp(path.dirname(cacheFile))
108-
await writeFile(cacheFile, `@use "${normalizePath(configFile)}"\n@use "${normalizePath(target)}"`)
126+
await fs.writeFile(cacheFile, contents)
109127

110128
return cacheFile
111129
})

0 commit comments

Comments
 (0)