vite-plugin-theme-css 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -76,14 +76,16 @@ export default defineConfig({
76
76
  })
77
77
  ```
78
78
 
79
- ### 3. 引入 CSS 变量
79
+ ### 3. CSS 变量(自动注入)
80
80
 
81
- 在入口文件中导入虚拟 CSS:
81
+ 默认会在 HTML 里自动注入主题 CSS 变量,**无需**在入口手动写:
82
82
 
83
83
  ```ts
84
- import 'virtual:theme-css/css'
84
+ import 'virtual:theme-css/css' // 可省略
85
85
  ```
86
86
 
87
+ 若需关闭自动注入,可设置 `autoImportCss: false`,再自行在入口 import。
88
+
87
89
  生成示例:
88
90
 
89
91
  ```css
@@ -173,8 +175,11 @@ themeCss({
173
175
  syncHtmlDark: true,
174
176
 
175
177
  /** 排除自动注入 SCSS helper 的文件 */
176
- exclude: [/node_modules/]
178
+ exclude: [/node_modules/],
177
179
  // 或: (filename) => filename.includes('legacy')
180
+
181
+ /** 是否自动在 HTML 注入 CSS 变量,默认 true */
182
+ autoImportCss: true
178
183
  })
179
184
  ```
180
185
 
@@ -0,0 +1,7 @@
1
+ export declare const VIRTUAL_CSS_ID = "virtual:theme-css/css";
2
+ export declare const VIRTUAL_CSS_RESOLVED = "\0virtual:theme-css.css";
3
+ export declare const VIRTUAL_SCSS_ID = "virtual:theme-css/scss";
4
+ export declare const VIRTUAL_SCSS_RESOLVED = "\0virtual:theme-css.scss";
5
+ export declare const VIRTUAL_RUNTIME_ID = "@scope/theme-css";
6
+ export declare const VIRTUAL_RUNTIME_DATA_ID = "virtual:theme-css/runtime-data";
7
+ export declare const VIRTUAL_RUNTIME_DATA_RESOLVED = "\0virtual:theme-css/runtime-data";
package/dist/index.cjs CHANGED
@@ -36,17 +36,26 @@ __export(src_exports, {
36
36
  });
37
37
  module.exports = __toCommonJS(src_exports);
38
38
  var import_node_fs = require("fs");
39
- var import_node_path = __toESM(require("path"), 1);
40
- var import_node_url = require("url");
39
+ var import_node_path2 = __toESM(require("path"), 1);
41
40
  var import_node_module = require("module");
42
41
  var import_jiti = require("jiti");
43
42
 
43
+ // src/constants.ts
44
+ var VIRTUAL_CSS_ID = "virtual:theme-css/css";
45
+ var VIRTUAL_CSS_RESOLVED = "\0virtual:theme-css.css";
46
+ var VIRTUAL_SCSS_ID = "virtual:theme-css/scss";
47
+ var VIRTUAL_SCSS_RESOLVED = "\0virtual:theme-css.scss";
48
+ var VIRTUAL_RUNTIME_ID = "@scope/theme-css";
49
+ var VIRTUAL_RUNTIME_DATA_ID = "virtual:theme-css/runtime-data";
50
+ var VIRTUAL_RUNTIME_DATA_RESOLVED = "\0virtual:theme-css/runtime-data";
51
+
44
52
  // src/types.ts
45
53
  var defaultOptions = {
46
54
  config: "./theme.config.ts",
47
55
  scssNamespace: "token",
48
56
  syncHtmlDark: true,
49
- exclude: []
57
+ exclude: [],
58
+ autoImportCss: true
50
59
  };
51
60
 
52
61
  // src/utils/flatten.ts
@@ -86,8 +95,8 @@ var generateThemeCss = (config) => {
86
95
  return lines.join("\n");
87
96
  };
88
97
 
89
- // src/generate/scss/helper.scss
90
- var helper_default = `// \u5185\u90E8\u5DE5\u5177\uFF1A\u62FC\u63A5\u591A\u4E2A key\r
98
+ // src/generate/scss/index.ts
99
+ var generateScssHelper = () => `// \u5185\u90E8\u5DE5\u5177\uFF1A\u62FC\u63A5\u591A\u4E2A key\r
91
100
  @function _join-keys($keys...) {\r
92
101
  $result: '';\r
93
102
  @each $key in $keys {\r
@@ -118,9 +127,6 @@ var helper_default = `// \u5185\u90E8\u5DE5\u5177\uFF1A\u62FC\u63A5\u591A\u4E2A
118
127
  }\r
119
128
  `;
120
129
 
121
- // src/generate/scss/index.ts
122
- var generateScssHelper = () => helper_default;
123
-
124
130
  // src/generate/js/index.ts
125
131
  function generateJs(config, options) {
126
132
  return `export const config = ${JSON.stringify(config, null, 2)}
@@ -128,6 +134,28 @@ export const options = ${JSON.stringify(options)}
128
134
  `;
129
135
  }
130
136
 
137
+ // src/utils/sass-importer.ts
138
+ var canonicalUrl = new URL(`${VIRTUAL_SCSS_ID}.scss`);
139
+ function createVirtualScssImporter(getContent) {
140
+ return {
141
+ canonicalize(url) {
142
+ if (url === VIRTUAL_SCSS_ID) return canonicalUrl;
143
+ return null;
144
+ },
145
+ load(canonical) {
146
+ if (canonical.href === canonicalUrl.href) {
147
+ return { contents: getContent(), syntax: "scss" };
148
+ }
149
+ return null;
150
+ }
151
+ };
152
+ }
153
+
154
+ // src/plugin-dir.ts
155
+ var import_node_path = __toESM(require("path"), 1);
156
+ var pluginFilename = __filename;
157
+ var pluginDir = import_node_path.default.dirname(__filename);
158
+
131
159
  // src/defineTheme.ts
132
160
  function defineTheme(config) {
133
161
  return config;
@@ -171,33 +199,21 @@ function createThemeRuntime(config, options = {}) {
171
199
  }
172
200
 
173
201
  // src/index.ts
174
- var import_meta = {};
175
- var require2 = (0, import_node_module.createRequire)(import_meta.url);
202
+ var require2 = (0, import_node_module.createRequire)(pluginFilename);
176
203
  var babelTransform = (0, import_node_module.createRequire)(require2.resolve("jiti/package.json"))("./dist/babel.cjs");
177
- var VIRTUAL_CSS_ID = "virtual:theme-css/css";
178
- var VIRTUAL_CSS_RESOLVED = "\0virtual:theme-css.css";
179
- var VIRTUAL_SCSS_ID = "virtual:theme-css/scss";
180
- var VIRTUAL_SCSS_RESOLVED = "\0virtual:theme-css.scss";
181
- var VIRTUAL_RUNTIME_ID = "@scope/theme-css";
182
- var VIRTUAL_RUNTIME_DATA_ID = "virtual:theme-css/runtime-data";
183
- var VIRTUAL_RUNTIME_DATA_RESOLVED = "\0virtual:theme-css/runtime-data";
184
204
  function resolveRuntimeEntryPath() {
185
- const here = import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
186
- const distEntry = import_node_path.default.join(here, "runtime-entry.mjs");
205
+ const distEntry = import_node_path2.default.join(pluginDir, "runtime-entry.mjs");
187
206
  if ((0, import_node_fs.existsSync)(distEntry)) return distEntry;
188
- return import_node_path.default.join(here, "runtime", "virtual-entry.ts");
207
+ return import_node_path2.default.join(pluginDir, "runtime", "virtual-entry.ts");
189
208
  }
190
209
  function themeCss(options = {}) {
191
210
  const resolvedOptions = { ...defaultOptions, ...options };
192
- const { config: configPath, scssNamespace, syncHtmlDark, exclude } = resolvedOptions;
193
- let viteConfig;
194
- let themeConfig;
211
+ const { config: configPath, scssNamespace, syncHtmlDark, exclude, autoImportCss } = resolvedOptions;
195
212
  let cssContent = "";
196
- let scssHelperContent = "";
197
213
  let runtimeDataContent = "";
198
214
  const runtimeEntryPath = resolveRuntimeEntryPath();
199
215
  async function loadConfigAndGenerate() {
200
- const jiti = (0, import_jiti.createJiti)(import_meta.url, {
216
+ const jiti = (0, import_jiti.createJiti)(pluginFilename, {
201
217
  interopDefault: true,
202
218
  transform: (opts) => {
203
219
  let { source } = opts;
@@ -210,16 +226,14 @@ ${source}`;
210
226
  return babelTransform({ ...opts, source });
211
227
  }
212
228
  });
213
- const mod = await jiti.import(import_node_path.default.resolve(configPath));
214
- themeConfig = mod.default;
229
+ const mod = await jiti.import(import_node_path2.default.resolve(configPath));
230
+ const themeConfig = mod.default;
215
231
  cssContent = generateThemeCss(themeConfig);
216
- scssHelperContent = generateScssHelper();
217
232
  runtimeDataContent = generateJs(themeConfig, { syncHtmlDark });
218
233
  }
219
234
  return {
220
235
  name: "vite-plugin-theme-css",
221
- async configResolved(config) {
222
- viteConfig = config;
236
+ async configResolved() {
223
237
  await loadConfigAndGenerate();
224
238
  },
225
239
  resolveId(id) {
@@ -241,52 +255,73 @@ ${source}`;
241
255
  case VIRTUAL_CSS_RESOLVED:
242
256
  return cssContent;
243
257
  case VIRTUAL_SCSS_RESOLVED:
244
- return scssHelperContent;
258
+ return generateScssHelper();
245
259
  case VIRTUAL_RUNTIME_DATA_RESOLVED:
246
260
  return runtimeDataContent;
247
261
  default:
248
262
  return null;
249
263
  }
250
264
  },
265
+ async transformIndexHtml(html) {
266
+ if (!autoImportCss || html.includes("data-theme-css-vars")) return;
267
+ if (!cssContent) await loadConfigAndGenerate();
268
+ return [
269
+ {
270
+ tag: "style",
271
+ attrs: { "data-theme-css-vars": "" },
272
+ children: cssContent,
273
+ injectTo: "head-prepend"
274
+ }
275
+ ];
276
+ },
251
277
  config(userConfig) {
252
278
  const scssOptions = userConfig.css?.preprocessorOptions?.scss ?? {};
253
279
  const userAdditionalData = scssOptions.additionalData;
254
280
  const ourPrefix = `@use "${VIRTUAL_SCSS_ID}" as ${scssNamespace};
255
281
  `;
256
- const wrappedAdditionalData = async (source, filename) => {
257
- if (filename.includes("virtual:theme-css")) {
258
- return typeof userAdditionalData === "function" ? await userAdditionalData(source, filename) : userAdditionalData ?? "";
282
+ const applyUserAdditionalData = async (source, filename) => {
283
+ if (typeof userAdditionalData === "function") {
284
+ return userAdditionalData(source, filename);
285
+ }
286
+ if (userAdditionalData) {
287
+ return userAdditionalData + source;
259
288
  }
260
- const shouldExclude = Array.isArray(exclude) ? exclude.some((rule) => {
289
+ return source;
290
+ };
291
+ const wrappedAdditionalData = async (source, filename) => {
292
+ const skipInject = filename.includes("virtual:theme-css") || (Array.isArray(exclude) ? exclude.some((rule) => {
261
293
  if (typeof rule === "string") return filename.includes(rule);
262
294
  if (rule instanceof RegExp) return rule.test(filename);
263
295
  return false;
264
- }) : typeof exclude === "function" ? exclude(filename) : false;
265
- if (shouldExclude) {
266
- return typeof userAdditionalData === "function" ? await userAdditionalData(source, filename) : userAdditionalData ?? "";
296
+ }) : typeof exclude === "function" ? exclude(filename) : false);
297
+ if (skipInject) {
298
+ return applyUserAdditionalData(source, filename);
267
299
  }
268
- const userContent = typeof userAdditionalData === "function" ? await userAdditionalData(source, filename) : userAdditionalData ?? "";
269
- return ourPrefix + userContent;
300
+ return ourPrefix + await applyUserAdditionalData(source, filename);
270
301
  };
302
+ const userImporters = Array.isArray(scssOptions.importers) ? scssOptions.importers : [];
271
303
  return {
272
304
  css: {
273
305
  preprocessorOptions: {
274
306
  scss: {
275
307
  ...scssOptions,
276
- additionalData: wrappedAdditionalData
308
+ additionalData: wrappedAdditionalData,
309
+ importers: [
310
+ createVirtualScssImporter(generateScssHelper),
311
+ ...userImporters
312
+ ]
277
313
  }
278
314
  }
279
315
  }
280
316
  };
281
317
  },
282
318
  async handleHotUpdate(ctx) {
283
- const configAbsPath = import_node_path.default.resolve(configPath);
319
+ const configAbsPath = import_node_path2.default.resolve(configPath);
284
320
  if (ctx.file === configAbsPath) {
285
321
  await loadConfigAndGenerate();
286
322
  const moduleGraph = ctx.server.moduleGraph;
287
323
  for (const id of [
288
324
  VIRTUAL_CSS_RESOLVED,
289
- VIRTUAL_SCSS_RESOLVED,
290
325
  VIRTUAL_RUNTIME_DATA_RESOLVED,
291
326
  runtimeEntryPath
292
327
  ]) {
package/dist/index.mjs CHANGED
@@ -1,16 +1,25 @@
1
1
  // src/index.ts
2
2
  import { existsSync } from "fs";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
3
+ import path2 from "path";
5
4
  import { createRequire } from "module";
6
5
  import { createJiti } from "jiti";
7
6
 
7
+ // src/constants.ts
8
+ var VIRTUAL_CSS_ID = "virtual:theme-css/css";
9
+ var VIRTUAL_CSS_RESOLVED = "\0virtual:theme-css.css";
10
+ var VIRTUAL_SCSS_ID = "virtual:theme-css/scss";
11
+ var VIRTUAL_SCSS_RESOLVED = "\0virtual:theme-css.scss";
12
+ var VIRTUAL_RUNTIME_ID = "@scope/theme-css";
13
+ var VIRTUAL_RUNTIME_DATA_ID = "virtual:theme-css/runtime-data";
14
+ var VIRTUAL_RUNTIME_DATA_RESOLVED = "\0virtual:theme-css/runtime-data";
15
+
8
16
  // src/types.ts
9
17
  var defaultOptions = {
10
18
  config: "./theme.config.ts",
11
19
  scssNamespace: "token",
12
20
  syncHtmlDark: true,
13
- exclude: []
21
+ exclude: [],
22
+ autoImportCss: true
14
23
  };
15
24
 
16
25
  // src/utils/flatten.ts
@@ -50,8 +59,8 @@ var generateThemeCss = (config) => {
50
59
  return lines.join("\n");
51
60
  };
52
61
 
53
- // src/generate/scss/helper.scss
54
- var helper_default = `// \u5185\u90E8\u5DE5\u5177\uFF1A\u62FC\u63A5\u591A\u4E2A key\r
62
+ // src/generate/scss/index.ts
63
+ var generateScssHelper = () => `// \u5185\u90E8\u5DE5\u5177\uFF1A\u62FC\u63A5\u591A\u4E2A key\r
55
64
  @function _join-keys($keys...) {\r
56
65
  $result: '';\r
57
66
  @each $key in $keys {\r
@@ -82,9 +91,6 @@ var helper_default = `// \u5185\u90E8\u5DE5\u5177\uFF1A\u62FC\u63A5\u591A\u4E2A
82
91
  }\r
83
92
  `;
84
93
 
85
- // src/generate/scss/index.ts
86
- var generateScssHelper = () => helper_default;
87
-
88
94
  // src/generate/js/index.ts
89
95
  function generateJs(config, options) {
90
96
  return `export const config = ${JSON.stringify(config, null, 2)}
@@ -92,6 +98,29 @@ export const options = ${JSON.stringify(options)}
92
98
  `;
93
99
  }
94
100
 
101
+ // src/utils/sass-importer.ts
102
+ var canonicalUrl = new URL(`${VIRTUAL_SCSS_ID}.scss`);
103
+ function createVirtualScssImporter(getContent) {
104
+ return {
105
+ canonicalize(url) {
106
+ if (url === VIRTUAL_SCSS_ID) return canonicalUrl;
107
+ return null;
108
+ },
109
+ load(canonical) {
110
+ if (canonical.href === canonicalUrl.href) {
111
+ return { contents: getContent(), syntax: "scss" };
112
+ }
113
+ return null;
114
+ }
115
+ };
116
+ }
117
+
118
+ // src/plugin-dir.ts
119
+ import path from "path";
120
+ import { fileURLToPath } from "url";
121
+ var pluginFilename = fileURLToPath(import.meta.url);
122
+ var pluginDir = path.dirname(pluginFilename);
123
+
95
124
  // src/defineTheme.ts
96
125
  function defineTheme(config) {
97
126
  return config;
@@ -135,32 +164,21 @@ function createThemeRuntime(config, options = {}) {
135
164
  }
136
165
 
137
166
  // src/index.ts
138
- var require2 = createRequire(import.meta.url);
167
+ var require2 = createRequire(pluginFilename);
139
168
  var babelTransform = createRequire(require2.resolve("jiti/package.json"))("./dist/babel.cjs");
140
- var VIRTUAL_CSS_ID = "virtual:theme-css/css";
141
- var VIRTUAL_CSS_RESOLVED = "\0virtual:theme-css.css";
142
- var VIRTUAL_SCSS_ID = "virtual:theme-css/scss";
143
- var VIRTUAL_SCSS_RESOLVED = "\0virtual:theme-css.scss";
144
- var VIRTUAL_RUNTIME_ID = "@scope/theme-css";
145
- var VIRTUAL_RUNTIME_DATA_ID = "virtual:theme-css/runtime-data";
146
- var VIRTUAL_RUNTIME_DATA_RESOLVED = "\0virtual:theme-css/runtime-data";
147
169
  function resolveRuntimeEntryPath() {
148
- const here = path.dirname(fileURLToPath(import.meta.url));
149
- const distEntry = path.join(here, "runtime-entry.mjs");
170
+ const distEntry = path2.join(pluginDir, "runtime-entry.mjs");
150
171
  if (existsSync(distEntry)) return distEntry;
151
- return path.join(here, "runtime", "virtual-entry.ts");
172
+ return path2.join(pluginDir, "runtime", "virtual-entry.ts");
152
173
  }
153
174
  function themeCss(options = {}) {
154
175
  const resolvedOptions = { ...defaultOptions, ...options };
155
- const { config: configPath, scssNamespace, syncHtmlDark, exclude } = resolvedOptions;
156
- let viteConfig;
157
- let themeConfig;
176
+ const { config: configPath, scssNamespace, syncHtmlDark, exclude, autoImportCss } = resolvedOptions;
158
177
  let cssContent = "";
159
- let scssHelperContent = "";
160
178
  let runtimeDataContent = "";
161
179
  const runtimeEntryPath = resolveRuntimeEntryPath();
162
180
  async function loadConfigAndGenerate() {
163
- const jiti = createJiti(import.meta.url, {
181
+ const jiti = createJiti(pluginFilename, {
164
182
  interopDefault: true,
165
183
  transform: (opts) => {
166
184
  let { source } = opts;
@@ -173,16 +191,14 @@ ${source}`;
173
191
  return babelTransform({ ...opts, source });
174
192
  }
175
193
  });
176
- const mod = await jiti.import(path.resolve(configPath));
177
- themeConfig = mod.default;
194
+ const mod = await jiti.import(path2.resolve(configPath));
195
+ const themeConfig = mod.default;
178
196
  cssContent = generateThemeCss(themeConfig);
179
- scssHelperContent = generateScssHelper();
180
197
  runtimeDataContent = generateJs(themeConfig, { syncHtmlDark });
181
198
  }
182
199
  return {
183
200
  name: "vite-plugin-theme-css",
184
- async configResolved(config) {
185
- viteConfig = config;
201
+ async configResolved() {
186
202
  await loadConfigAndGenerate();
187
203
  },
188
204
  resolveId(id) {
@@ -204,52 +220,73 @@ ${source}`;
204
220
  case VIRTUAL_CSS_RESOLVED:
205
221
  return cssContent;
206
222
  case VIRTUAL_SCSS_RESOLVED:
207
- return scssHelperContent;
223
+ return generateScssHelper();
208
224
  case VIRTUAL_RUNTIME_DATA_RESOLVED:
209
225
  return runtimeDataContent;
210
226
  default:
211
227
  return null;
212
228
  }
213
229
  },
230
+ async transformIndexHtml(html) {
231
+ if (!autoImportCss || html.includes("data-theme-css-vars")) return;
232
+ if (!cssContent) await loadConfigAndGenerate();
233
+ return [
234
+ {
235
+ tag: "style",
236
+ attrs: { "data-theme-css-vars": "" },
237
+ children: cssContent,
238
+ injectTo: "head-prepend"
239
+ }
240
+ ];
241
+ },
214
242
  config(userConfig) {
215
243
  const scssOptions = userConfig.css?.preprocessorOptions?.scss ?? {};
216
244
  const userAdditionalData = scssOptions.additionalData;
217
245
  const ourPrefix = `@use "${VIRTUAL_SCSS_ID}" as ${scssNamespace};
218
246
  `;
219
- const wrappedAdditionalData = async (source, filename) => {
220
- if (filename.includes("virtual:theme-css")) {
221
- return typeof userAdditionalData === "function" ? await userAdditionalData(source, filename) : userAdditionalData ?? "";
247
+ const applyUserAdditionalData = async (source, filename) => {
248
+ if (typeof userAdditionalData === "function") {
249
+ return userAdditionalData(source, filename);
250
+ }
251
+ if (userAdditionalData) {
252
+ return userAdditionalData + source;
222
253
  }
223
- const shouldExclude = Array.isArray(exclude) ? exclude.some((rule) => {
254
+ return source;
255
+ };
256
+ const wrappedAdditionalData = async (source, filename) => {
257
+ const skipInject = filename.includes("virtual:theme-css") || (Array.isArray(exclude) ? exclude.some((rule) => {
224
258
  if (typeof rule === "string") return filename.includes(rule);
225
259
  if (rule instanceof RegExp) return rule.test(filename);
226
260
  return false;
227
- }) : typeof exclude === "function" ? exclude(filename) : false;
228
- if (shouldExclude) {
229
- return typeof userAdditionalData === "function" ? await userAdditionalData(source, filename) : userAdditionalData ?? "";
261
+ }) : typeof exclude === "function" ? exclude(filename) : false);
262
+ if (skipInject) {
263
+ return applyUserAdditionalData(source, filename);
230
264
  }
231
- const userContent = typeof userAdditionalData === "function" ? await userAdditionalData(source, filename) : userAdditionalData ?? "";
232
- return ourPrefix + userContent;
265
+ return ourPrefix + await applyUserAdditionalData(source, filename);
233
266
  };
267
+ const userImporters = Array.isArray(scssOptions.importers) ? scssOptions.importers : [];
234
268
  return {
235
269
  css: {
236
270
  preprocessorOptions: {
237
271
  scss: {
238
272
  ...scssOptions,
239
- additionalData: wrappedAdditionalData
273
+ additionalData: wrappedAdditionalData,
274
+ importers: [
275
+ createVirtualScssImporter(generateScssHelper),
276
+ ...userImporters
277
+ ]
240
278
  }
241
279
  }
242
280
  }
243
281
  };
244
282
  },
245
283
  async handleHotUpdate(ctx) {
246
- const configAbsPath = path.resolve(configPath);
284
+ const configAbsPath = path2.resolve(configPath);
247
285
  if (ctx.file === configAbsPath) {
248
286
  await loadConfigAndGenerate();
249
287
  const moduleGraph = ctx.server.moduleGraph;
250
288
  for (const id of [
251
289
  VIRTUAL_CSS_RESOLVED,
252
- VIRTUAL_SCSS_RESOLVED,
253
290
  VIRTUAL_RUNTIME_DATA_RESOLVED,
254
291
  runtimeEntryPath
255
292
  ]) {
@@ -0,0 +1,3 @@
1
+ /** 插件包根目录(须与 index.ts 同级,dev 与 dist 均能正确定位 runtime-entry) */
2
+ export declare const pluginFilename: string;
3
+ export declare const pluginDir: string;
package/dist/types.d.ts CHANGED
@@ -11,5 +11,7 @@ export interface ThemeCssOptions {
11
11
  syncHtmlDark?: boolean;
12
12
  /** 排除注入 SCSS helper 的文件规则 */
13
13
  exclude?: (string | RegExp)[] | ((filename: string) => boolean);
14
+ /** 是否自动在 HTML 注入 CSS 变量,默认 true */
15
+ autoImportCss?: boolean;
14
16
  }
15
17
  export declare const defaultOptions: Required<ThemeCssOptions>;
@@ -0,0 +1,3 @@
1
+ import type { Importer } from 'sass';
2
+ /** 让 Sass 能解析 additionalData 里的 virtual:theme-css/scss */
3
+ export declare function createVirtualScssImporter(getContent: () => string): Importer<'sync'>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-theme-css",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Vite 插件:用一份主题配置生成 CSS 变量、SCSS helper 与 JS 运行时,支持多主题切换与热更新",
5
5
  "author": "yuzinan <1589937631@qq.com>",
6
6
  "license": "MIT",
@@ -53,6 +53,7 @@
53
53
  },
54
54
  "devDependencies": {
55
55
  "@types/node": "^26.2.0",
56
+ "esbuild": "^0.28.2",
56
57
  "prettier": "3.9.6",
57
58
  "sass": "^1.103.0",
58
59
  "tsup": "^8.5.1",
@@ -63,6 +64,7 @@
63
64
  "scripts": {
64
65
  "build": "tsup && tsc -p tsconfig.build.json",
65
66
  "dev": "tsup --watch",
67
+ "play": "vite --config playground/vite.config.ts",
66
68
  "test": "vitest",
67
69
  "format": "prettier --write .",
68
70
  "format:check": "prettier --check .",