@unocss/vite 0.11.3 → 0.12.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/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { Plugin } from 'vite';
3
3
  import { UserConfig, UnoGenerator, BetterMap, UserConfigDefaults } from '@unocss/core';
4
4
 
5
5
  declare type FilterPattern = ReadonlyArray<string | RegExp> | string | RegExp | null;
6
- interface PluginOptions<Theme extends {} = {}> extends UserConfig<Theme> {
6
+ interface PluginConfig<Theme extends {} = {}> extends UserConfig<Theme> {
7
7
  /**
8
8
  * Patterns that filter the files being extracted.
9
9
  */
@@ -14,7 +14,7 @@ interface PluginOptions<Theme extends {} = {}> extends UserConfig<Theme> {
14
14
  exclude?: FilterPattern;
15
15
  }
16
16
 
17
- interface VitePluginOptions<Theme extends {} = {}> extends PluginOptions<Theme> {
17
+ interface VitePluginConfig<Theme extends {} = {}> extends PluginConfig<Theme> {
18
18
  /**
19
19
  * Enable UnoCSS inspector
20
20
  *
@@ -34,31 +34,32 @@ interface VitePluginOptions<Theme extends {} = {}> extends PluginOptions<Theme>
34
34
  mode?: 'global' | 'per-module' | 'vue-scoped' | 'dist-chunk';
35
35
  }
36
36
 
37
- declare function createContext(uno: UnoGenerator, config: VitePluginOptions, configFilepath?: string): {
37
+ interface UnocssPluginContext<Config extends PluginConfig = PluginConfig> {
38
+ uno: UnoGenerator;
39
+ config: Config;
38
40
  tokens: Set<string>;
39
41
  modules: BetterMap<string, string>;
42
+ filter: (code: string, id: string) => boolean;
43
+ reloadConfig: () => Promise<void>;
44
+ extract: (code: string, id?: string) => Promise<void>;
45
+ configFilepath?: string;
40
46
  invalidate: () => void;
41
- onInvalidate(fn: () => void): void;
42
- uno: UnoGenerator;
43
- scan: (code: string, id?: string | undefined) => Promise<void>;
44
- config: VitePluginOptions<{}>;
45
- configFilepath: string | undefined;
46
- };
47
- declare type UnocssPluginContext = ReturnType<typeof createContext>;
47
+ onInvalidate: (fn: () => void) => void;
48
+ }
48
49
 
49
- declare function ChunkModeBuildPlugin({ uno, config }: UnocssPluginContext): Plugin;
50
+ declare function ChunkModeBuildPlugin({ uno, filter }: UnocssPluginContext): Plugin;
50
51
 
51
- declare function GlobalModeDevPlugin({ config, uno, tokens, onInvalidate, scan }: UnocssPluginContext): Plugin[];
52
+ declare function GlobalModeDevPlugin({ uno, tokens, onInvalidate, extract, filter }: UnocssPluginContext): Plugin[];
52
53
 
53
- declare function GlobalModeBuildPlugin({ uno, config, scan, tokens }: UnocssPluginContext): Plugin[];
54
+ declare function GlobalModeBuildPlugin({ uno, extract, tokens, modules, filter }: UnocssPluginContext): Plugin[];
54
55
 
55
56
  declare function GlobalModePlugin(ctx: UnocssPluginContext): vite.Plugin[];
56
57
 
57
- declare function PerModuleModePlugin({ uno, config }: UnocssPluginContext): Plugin;
58
+ declare function PerModuleModePlugin({ uno, filter }: UnocssPluginContext): Plugin;
58
59
 
59
60
  declare function VueScopedPlugin({ uno, config }: UnocssPluginContext): Plugin;
60
61
 
61
- declare function defineConfig<Theme extends {}>(config: VitePluginOptions<Theme>): VitePluginOptions<Theme>;
62
- declare function UnocssPlugin(configOrPath?: VitePluginOptions | string, defaults?: UserConfigDefaults): Plugin[];
62
+ declare function defineConfig<Theme extends {}>(config: VitePluginConfig<Theme>): VitePluginConfig<Theme>;
63
+ declare function UnocssPlugin(configOrPath?: VitePluginConfig | string, defaults?: UserConfigDefaults): Plugin[];
63
64
 
64
- export { ChunkModeBuildPlugin, GlobalModeBuildPlugin, GlobalModeDevPlugin, GlobalModePlugin, PerModuleModePlugin, UnocssPluginContext, VitePluginOptions, VueScopedPlugin, UnocssPlugin as default, defineConfig };
65
+ export { ChunkModeBuildPlugin, GlobalModeBuildPlugin, GlobalModeDevPlugin, GlobalModePlugin, PerModuleModePlugin, UnocssPluginContext, VitePluginConfig, VueScopedPlugin, UnocssPlugin as default, defineConfig };
package/dist/index.js CHANGED
@@ -33,16 +33,54 @@ __export(exports, {
33
33
  default: () => UnocssPlugin,
34
34
  defineConfig: () => defineConfig
35
35
  });
36
- var import_core2 = __toModule(require("@unocss/core"));
37
- var import_config2 = __toModule(require("@unocss/config"));
38
36
  var import_inspector = __toModule(require("@unocss/inspector"));
39
37
 
40
- // src/context.ts
38
+ // ../plugins-common/defaults.ts
39
+ var defaultExclude = [/\.(css|postcss|sass|scss|less|stylus|styl)$/];
40
+ var defaultInclude = [/\.vue$/, /\.vue\?vue/, /\.svelte$/, /\.[jt]sx$/, /\.mdx?$/, /\.astro$/];
41
+
42
+ // ../plugins-common/layers.ts
43
+ var VIRTUAL_ENTRY_ALIAS = [
44
+ /^(?:virtual:)?uno(?::(.+))?\.css(\?.*)?$/
45
+ ];
46
+ var LAYER_MARK_ALL = "__ALL__";
47
+ function resolveId(id) {
48
+ for (const alias of VIRTUAL_ENTRY_ALIAS) {
49
+ const match = id.match(alias);
50
+ if (match) {
51
+ return match[1] ? {
52
+ id: `/__uno_${match[1]}.css`,
53
+ layer: match[1]
54
+ } : {
55
+ id: "/__uno.css",
56
+ layer: LAYER_MARK_ALL
57
+ };
58
+ }
59
+ }
60
+ }
61
+ var LAYER_PLACEHOLDER_RE = /(\\?")?#--unocss--\s*{\s*layer\s*:\s*(.+?);?\s*}/g;
62
+ function getLayerPlaceholder(layer) {
63
+ return `#--unocss--{layer:${layer}}`;
64
+ }
65
+ var HASH_PLACEHOLDER_RE = /#--unocss-hash--\s*{\s*content\s*:\s*"(.+?)";?\s*}/g;
66
+ function getHashPlaceholder(hash) {
67
+ return `#--unocss-hash--{content:"${hash}"}`;
68
+ }
69
+
70
+ // ../plugins-common/constants.ts
71
+ var INCLUDE_COMMENT = "@unocss-include";
72
+
73
+ // ../plugins-common/context.ts
74
+ var import_pluginutils = __toModule(require("@rollup/pluginutils"));
75
+ var import_config = __toModule(require("@unocss/config"));
41
76
  var import_core = __toModule(require("@unocss/core"));
42
- function createContext(uno, config, configFilepath) {
77
+ function createContext(configOrPath, defaults = {}) {
78
+ const { config = {}, filepath } = (0, import_config.loadConfig)(configOrPath);
79
+ const uno = (0, import_core.createGenerator)(config, defaults);
43
80
  const invalidations = [];
44
81
  const modules = new import_core.BetterMap();
45
82
  const tokens = new Set();
83
+ let rollupFilter = (0, import_pluginutils.createFilter)(config.include || defaultInclude, config.exclude || defaultExclude);
46
84
  function invalidate() {
47
85
  invalidations.forEach((cb) => cb());
48
86
  }
@@ -52,6 +90,19 @@ function createContext(uno, config, configFilepath) {
52
90
  await uno.applyExtractors(code, id, tokens);
53
91
  invalidate();
54
92
  }
93
+ async function reloadConfig() {
94
+ if (!filepath)
95
+ return;
96
+ uno.setConfig((0, import_config.loadConfig)(filepath).config);
97
+ uno.config.envMode = "dev";
98
+ rollupFilter = (0, import_pluginutils.createFilter)(config.include || defaultInclude, config.exclude || defaultExclude);
99
+ tokens.clear();
100
+ await Promise.all(modules.map((code, id) => uno.applyExtractors(code, id, tokens)));
101
+ invalidate();
102
+ }
103
+ const filter = (code, id) => {
104
+ return code.includes(INCLUDE_COMMENT) || rollupFilter(id);
105
+ };
55
106
  return {
56
107
  tokens,
57
108
  modules,
@@ -59,34 +110,37 @@ function createContext(uno, config, configFilepath) {
59
110
  onInvalidate(fn) {
60
111
  invalidations.push(fn);
61
112
  },
113
+ filter,
114
+ reloadConfig,
62
115
  uno,
63
- scan,
116
+ extract: scan,
64
117
  config,
65
- configFilepath
118
+ configFilepath: filepath
66
119
  };
67
120
  }
68
121
 
69
- // src/modes/chunk-build.ts
70
- var import_pluginutils = __toModule(require("@rollup/pluginutils"));
71
-
72
- // ../plugins-common/defaults.ts
73
- var defaultExclude = [/\.(css|postcss|sass|scss|less|stylus|styl)$/];
74
- var defaultInclude = [/\.vue$/, /\.vue\?vue/, /\.svelte$/, /\.[jt]sx$/, /\.mdx?$/, /\.astro$/];
122
+ // ../plugins-common/utils.ts
123
+ var import_crypto = __toModule(require("crypto"));
124
+ function getHash(input, length = 8) {
125
+ return (0, import_crypto.createHash)("sha256").update(input).digest("hex").substr(0, length);
126
+ }
127
+ function getPath(id) {
128
+ return id.replace(/\?.*$/, "");
129
+ }
75
130
 
76
131
  // src/modes/chunk-build.ts
77
- function ChunkModeBuildPlugin({ uno, config }) {
132
+ function ChunkModeBuildPlugin({ uno, filter }) {
78
133
  let cssPlugin;
79
- const filter = (0, import_pluginutils.createFilter)(config.include || defaultInclude, config.exclude || defaultExclude);
80
134
  const files = {};
81
135
  return {
82
136
  name: "unocss:chunk",
83
137
  apply: "build",
84
138
  enforce: "pre",
85
- configResolved(config2) {
86
- cssPlugin = config2.plugins.find((i) => i.name === "vite:css-post");
139
+ configResolved(config) {
140
+ cssPlugin = config.plugins.find((i) => i.name === "vite:css-post");
87
141
  },
88
142
  transform(code, id) {
89
- if (!filter(id))
143
+ if (!filter(code, id))
90
144
  return;
91
145
  files[id] = code;
92
146
  return null;
@@ -118,73 +172,62 @@ function ChunkModeBuildPlugin({ uno, config }) {
118
172
  }
119
173
 
120
174
  // src/modes/global/build.ts
121
- var import_pluginutils2 = __toModule(require("@rollup/pluginutils"));
122
-
123
- // src/utils.ts
124
- var import_crypto = __toModule(require("crypto"));
125
- function getHash(input, length = 8) {
126
- return (0, import_crypto.createHash)("sha256").update(input).digest("hex").substr(0, length);
127
- }
128
- function getPath(id) {
129
- return id.replace(/\?.*$/, "");
130
- }
131
-
132
- // ../plugins-common/layers.ts
133
- var VIRTUAL_ENTRY_ALIAS = [
134
- /^(?:virtual:)?uno(?::(.+))?\.css(\?.*)?$/
135
- ];
136
- var LAYER_PLACEHOLDER_RE = /(\\?")?#--unocss--\s*{\s*layer\s*:\s*(.+?);?\s*}/g;
137
- var LAYER_MARK_ALL = "__ALL__";
138
- function resolveId(id) {
139
- for (const alias of VIRTUAL_ENTRY_ALIAS) {
140
- const match = id.match(alias);
141
- if (match) {
142
- return match[1] ? {
143
- id: `/__uno_${match[1]}.css`,
144
- layer: match[1]
145
- } : {
146
- id: "/__uno.css",
147
- layer: LAYER_MARK_ALL
148
- };
149
- }
150
- }
151
- }
152
- function getLayerPlaceholder(layer) {
153
- return `#--unocss--{layer:${layer}}`;
154
- }
155
-
156
- // src/modes/global/build.ts
157
- function GlobalModeBuildPlugin({ uno, config, scan, tokens }) {
158
- const filter = (0, import_pluginutils2.createFilter)(config.include || defaultInclude, config.exclude || defaultExclude);
159
- const tasks = [];
160
- const entries = new Map();
175
+ function GlobalModeBuildPlugin({ uno, extract, tokens, modules, filter }) {
176
+ const vfsLayerMap = new Map();
177
+ let tasks = [];
178
+ let cssPlugin;
161
179
  return [
162
180
  {
163
181
  name: "unocss:global:build:scan",
164
182
  apply: "build",
165
183
  enforce: "pre",
184
+ buildStart() {
185
+ tasks = [];
186
+ vfsLayerMap.clear();
187
+ },
166
188
  transform(code, id) {
167
- if (filter(id))
168
- tasks.push(scan(code, id));
189
+ if (filter(code, id))
190
+ tasks.push(extract(code, id));
169
191
  return null;
170
192
  },
171
193
  transformIndexHtml: {
172
194
  enforce: "pre",
173
195
  transform(code, { filename }) {
174
- tasks.push(scan(code, filename));
196
+ tasks.push(extract(code, filename));
175
197
  }
176
198
  },
177
199
  resolveId(id) {
178
200
  const entry = resolveId(id);
179
201
  if (entry) {
180
- entries.set(entry.id, entry.layer);
202
+ vfsLayerMap.set(entry.id, entry.layer);
181
203
  return entry.id;
182
204
  }
183
205
  },
184
206
  load(id) {
185
- const layer = entries.get(getPath(id));
207
+ const layer = vfsLayerMap.get(getPath(id));
186
208
  if (layer)
187
209
  return getLayerPlaceholder(layer);
210
+ },
211
+ async renderChunk(_, chunk) {
212
+ const chunks = Object.keys(chunk.modules).filter((i) => modules.has(i));
213
+ if (!chunks.length)
214
+ return null;
215
+ const tokens2 = new Set();
216
+ await Promise.all(chunks.map((c) => uno.applyExtractors(modules.get(c) || "", c, tokens2)));
217
+ const { css } = await uno.generate(tokens2, { minify: true });
218
+ if (!css)
219
+ return null;
220
+ const hash = getHash(css);
221
+ const fakeCssId = `${chunk.fileName}-unocss-hash.css`;
222
+ await cssPlugin.transform(getHashPlaceholder(hash), fakeCssId);
223
+ chunk.modules[fakeCssId] = {
224
+ code: null,
225
+ originalLength: 0,
226
+ removedExports: [],
227
+ renderedExports: [],
228
+ renderedLength: 0
229
+ };
230
+ return null;
188
231
  }
189
232
  },
190
233
  {
@@ -193,8 +236,11 @@ function GlobalModeBuildPlugin({ uno, config, scan, tokens }) {
193
236
  var _a;
194
237
  return command === "build" && !((_a = options.build) == null ? void 0 : _a.ssr);
195
238
  },
239
+ configResolved(config) {
240
+ cssPlugin = config.plugins.find((i) => i.name === "vite:css-post");
241
+ },
196
242
  enforce: "post",
197
- async generateBundle(options, bundle) {
243
+ async generateBundle(_, bundle) {
198
244
  const files = Object.keys(bundle);
199
245
  const cssFiles = files.filter((i) => i.endsWith(".css"));
200
246
  if (!cssFiles.length)
@@ -202,54 +248,29 @@ function GlobalModeBuildPlugin({ uno, config, scan, tokens }) {
202
248
  await Promise.all(tasks);
203
249
  const result = await uno.generate(tokens, { minify: true });
204
250
  let replaced = false;
205
- const cssReplacedMap = {};
206
251
  for (const file of cssFiles) {
207
252
  const chunk = bundle[file];
208
253
  if (chunk.type === "asset" && typeof chunk.source === "string") {
209
- let currentReplaced = false;
210
- chunk.source = chunk.source.replace(LAYER_PLACEHOLDER_RE, (_, __, layer) => {
211
- currentReplaced = true;
254
+ chunk.source = chunk.source.replace(HASH_PLACEHOLDER_RE, "").replace(LAYER_PLACEHOLDER_RE, (_2, __, layer) => {
212
255
  replaced = true;
213
- return layer === LAYER_MARK_ALL ? result.getLayers(void 0, Array.from(entries.values())) : result.getLayer(layer) || "";
256
+ return layer === LAYER_MARK_ALL ? result.getLayers(void 0, Array.from(vfsLayerMap.values())) : result.getLayer(layer) || "";
214
257
  });
215
- if (currentReplaced) {
216
- const newName = chunk.fileName.replace(/\.(\w+)\.css$/, `.${getHash(chunk.source)}.css`);
217
- cssReplacedMap[chunk.fileName] = newName;
218
- chunk.fileName = newName;
219
- }
220
258
  }
221
259
  }
222
260
  if (!replaced)
223
261
  this.error(new Error("[unocss] does not found CSS placeholder in the generated chunks,\nthis is likely an internal bug of unocss vite plugin"));
224
- const entires = Object.entries(cssReplacedMap);
225
- if (!entires.length)
226
- return;
227
- for (const file of files) {
228
- const chunk = bundle[file];
229
- if (chunk.type === "chunk" && typeof chunk.code === "string") {
230
- for (const [k, v] of entires)
231
- chunk.code = chunk.code.replace(k, v);
232
- } else if (chunk.type === "asset" && typeof chunk.source === "string") {
233
- for (const [k, v] of entires)
234
- chunk.source = chunk.source.replace(k, v);
235
- }
236
- }
237
262
  }
238
263
  }
239
264
  ];
240
265
  }
241
266
 
242
- // src/modes/global/dev.ts
243
- var import_pluginutils3 = __toModule(require("@rollup/pluginutils"));
244
-
245
267
  // src/modes/global/shared.ts
246
268
  var READY_CALLBACK_DEFAULT = "/__unocss_ready";
247
269
 
248
270
  // src/modes/global/dev.ts
249
271
  var WARN_TIMEOUT = 2e3;
250
- function GlobalModeDevPlugin({ config, uno, tokens, onInvalidate, scan }) {
272
+ function GlobalModeDevPlugin({ uno, tokens, onInvalidate, extract, filter }) {
251
273
  const servers = [];
252
- const filter = (0, import_pluginutils3.createFilter)(config.include || defaultInclude, config.exclude || defaultExclude);
253
274
  const tasks = [];
254
275
  const entries = new Map();
255
276
  let invalidateTimer;
@@ -320,14 +341,14 @@ function GlobalModeDevPlugin({ config, uno, tokens, onInvalidate, scan }) {
320
341
  });
321
342
  },
322
343
  transform(code, id) {
323
- if (filter(id))
324
- scan(code, id);
344
+ if (filter(code, id))
345
+ extract(code, id);
325
346
  return null;
326
347
  },
327
348
  transformIndexHtml: {
328
349
  enforce: "pre",
329
350
  transform(code, { filename }) {
330
- scan(code, filename);
351
+ extract(code, filename);
331
352
  }
332
353
  },
333
354
  resolveId(id) {
@@ -350,9 +371,9 @@ function GlobalModeDevPlugin({ config, uno, tokens, onInvalidate, scan }) {
350
371
  },
351
372
  {
352
373
  name: "unocss:global:post",
353
- apply(config2, env) {
374
+ apply(config, env) {
354
375
  var _a;
355
- return env.command === "serve" && !((_a = config2.build) == null ? void 0 : _a.ssr);
376
+ return env.command === "serve" && !((_a = config.build) == null ? void 0 : _a.ssr);
356
377
  },
357
378
  enforce: "post",
358
379
  transform(code, id) {
@@ -373,13 +394,11 @@ function GlobalModePlugin(ctx) {
373
394
  }
374
395
 
375
396
  // src/modes/per-module.ts
376
- var import_pluginutils4 = __toModule(require("@rollup/pluginutils"));
377
397
  var VIRTUAL_PREFIX = "/@unocss/";
378
398
  var SCOPE_IMPORT_RE = / from (['"])(@unocss\/scope)\1/;
379
- function PerModuleModePlugin({ uno, config }) {
399
+ function PerModuleModePlugin({ uno, filter }) {
380
400
  const moduleMap = new Map();
381
401
  let server;
382
- const filter = (0, import_pluginutils4.createFilter)(config.include || defaultInclude, config.exclude || defaultExclude);
383
402
  const invalidate = (hash) => {
384
403
  if (!server)
385
404
  return;
@@ -405,7 +424,7 @@ function PerModuleModePlugin({ uno, config }) {
405
424
  server = _server;
406
425
  },
407
426
  async transform(code, id) {
408
- if (!filter(id))
427
+ if (!filter(code, id))
409
428
  return;
410
429
  const hash = getHash(id);
411
430
  const hasScope = code.match(SCOPE_IMPORT_RE);
@@ -439,9 +458,9 @@ ${css}`;
439
458
  }
440
459
 
441
460
  // src/modes/vue-scoped.ts
442
- var import_pluginutils5 = __toModule(require("@rollup/pluginutils"));
461
+ var import_pluginutils2 = __toModule(require("@rollup/pluginutils"));
443
462
  function VueScopedPlugin({ uno, config }) {
444
- const filter = (0, import_pluginutils5.createFilter)(config.include || [/\.vue$/], config.exclude || defaultExclude);
463
+ const filter = (0, import_pluginutils2.createFilter)(config.include || [/\.vue$/], config.exclude || defaultExclude);
445
464
  async function transformSFC(code) {
446
465
  const { css } = await uno.generate(code);
447
466
  if (!css)
@@ -470,23 +489,18 @@ function VueScopedPlugin({ uno, config }) {
470
489
  }
471
490
 
472
491
  // src/config-hmr.ts
473
- var import_config = __toModule(require("@unocss/config"));
474
- function ConfigHMRPlugin({ uno, configFilepath: filepath, invalidate, tokens, modules }) {
492
+ function ConfigHMRPlugin({ uno, configFilepath, reloadConfig }) {
475
493
  return {
476
494
  name: "unocss:config",
477
495
  configureServer(server) {
478
496
  uno.config.envMode = "dev";
479
- if (!filepath)
497
+ if (!configFilepath)
480
498
  return;
481
- server.watcher.add(filepath);
499
+ server.watcher.add(configFilepath);
482
500
  server.watcher.on("change", async (p) => {
483
- if (p !== filepath)
501
+ if (p !== configFilepath)
484
502
  return;
485
- uno.setConfig((0, import_config.loadConfig)(filepath).config);
486
- uno.config.envMode = "dev";
487
- tokens.clear();
488
- await Promise.all(modules.map((code, id) => uno.applyExtractors(code, id, tokens)));
489
- invalidate();
503
+ reloadConfig();
490
504
  server.ws.send({
491
505
  type: "custom",
492
506
  event: "unocss:config-changed"
@@ -502,10 +516,9 @@ function defineConfig(config) {
502
516
  }
503
517
  function UnocssPlugin(configOrPath, defaults = {}) {
504
518
  var _a;
505
- const { config = {}, filepath } = (0, import_config2.loadConfig)(configOrPath);
519
+ const ctx = createContext(configOrPath, defaults);
520
+ const { config } = ctx;
506
521
  const mode = (_a = config.mode) != null ? _a : "global";
507
- const uno = (0, import_core2.createGenerator)(config, defaults);
508
- const ctx = createContext(uno, config, filepath);
509
522
  const plugins = [
510
523
  ConfigHMRPlugin(ctx)
511
524
  ];
package/dist/index.mjs CHANGED
@@ -1,14 +1,52 @@
1
1
  // src/index.ts
2
- import { createGenerator } from "@unocss/core";
3
- import { loadConfig as loadConfig2 } from "@unocss/config";
4
2
  import UnocssInspector from "@unocss/inspector";
5
3
 
6
- // src/context.ts
7
- import { BetterMap } from "@unocss/core";
8
- function createContext(uno, config, configFilepath) {
4
+ // ../plugins-common/defaults.ts
5
+ var defaultExclude = [/\.(css|postcss|sass|scss|less|stylus|styl)$/];
6
+ var defaultInclude = [/\.vue$/, /\.vue\?vue/, /\.svelte$/, /\.[jt]sx$/, /\.mdx?$/, /\.astro$/];
7
+
8
+ // ../plugins-common/layers.ts
9
+ var VIRTUAL_ENTRY_ALIAS = [
10
+ /^(?:virtual:)?uno(?::(.+))?\.css(\?.*)?$/
11
+ ];
12
+ var LAYER_MARK_ALL = "__ALL__";
13
+ function resolveId(id) {
14
+ for (const alias of VIRTUAL_ENTRY_ALIAS) {
15
+ const match = id.match(alias);
16
+ if (match) {
17
+ return match[1] ? {
18
+ id: `/__uno_${match[1]}.css`,
19
+ layer: match[1]
20
+ } : {
21
+ id: "/__uno.css",
22
+ layer: LAYER_MARK_ALL
23
+ };
24
+ }
25
+ }
26
+ }
27
+ var LAYER_PLACEHOLDER_RE = /(\\?")?#--unocss--\s*{\s*layer\s*:\s*(.+?);?\s*}/g;
28
+ function getLayerPlaceholder(layer) {
29
+ return `#--unocss--{layer:${layer}}`;
30
+ }
31
+ var HASH_PLACEHOLDER_RE = /#--unocss-hash--\s*{\s*content\s*:\s*"(.+?)";?\s*}/g;
32
+ function getHashPlaceholder(hash) {
33
+ return `#--unocss-hash--{content:"${hash}"}`;
34
+ }
35
+
36
+ // ../plugins-common/constants.ts
37
+ var INCLUDE_COMMENT = "@unocss-include";
38
+
39
+ // ../plugins-common/context.ts
40
+ import { createFilter } from "@rollup/pluginutils";
41
+ import { loadConfig } from "@unocss/config";
42
+ import { BetterMap, createGenerator } from "@unocss/core";
43
+ function createContext(configOrPath, defaults = {}) {
44
+ const { config = {}, filepath } = loadConfig(configOrPath);
45
+ const uno = createGenerator(config, defaults);
9
46
  const invalidations = [];
10
47
  const modules = new BetterMap();
11
48
  const tokens = new Set();
49
+ let rollupFilter = createFilter(config.include || defaultInclude, config.exclude || defaultExclude);
12
50
  function invalidate() {
13
51
  invalidations.forEach((cb) => cb());
14
52
  }
@@ -18,6 +56,19 @@ function createContext(uno, config, configFilepath) {
18
56
  await uno.applyExtractors(code, id, tokens);
19
57
  invalidate();
20
58
  }
59
+ async function reloadConfig() {
60
+ if (!filepath)
61
+ return;
62
+ uno.setConfig(loadConfig(filepath).config);
63
+ uno.config.envMode = "dev";
64
+ rollupFilter = createFilter(config.include || defaultInclude, config.exclude || defaultExclude);
65
+ tokens.clear();
66
+ await Promise.all(modules.map((code, id) => uno.applyExtractors(code, id, tokens)));
67
+ invalidate();
68
+ }
69
+ const filter = (code, id) => {
70
+ return code.includes(INCLUDE_COMMENT) || rollupFilter(id);
71
+ };
21
72
  return {
22
73
  tokens,
23
74
  modules,
@@ -25,34 +76,37 @@ function createContext(uno, config, configFilepath) {
25
76
  onInvalidate(fn) {
26
77
  invalidations.push(fn);
27
78
  },
79
+ filter,
80
+ reloadConfig,
28
81
  uno,
29
- scan,
82
+ extract: scan,
30
83
  config,
31
- configFilepath
84
+ configFilepath: filepath
32
85
  };
33
86
  }
34
87
 
35
- // src/modes/chunk-build.ts
36
- import { createFilter } from "@rollup/pluginutils";
37
-
38
- // ../plugins-common/defaults.ts
39
- var defaultExclude = [/\.(css|postcss|sass|scss|less|stylus|styl)$/];
40
- var defaultInclude = [/\.vue$/, /\.vue\?vue/, /\.svelte$/, /\.[jt]sx$/, /\.mdx?$/, /\.astro$/];
88
+ // ../plugins-common/utils.ts
89
+ import { createHash } from "crypto";
90
+ function getHash(input, length = 8) {
91
+ return createHash("sha256").update(input).digest("hex").substr(0, length);
92
+ }
93
+ function getPath(id) {
94
+ return id.replace(/\?.*$/, "");
95
+ }
41
96
 
42
97
  // src/modes/chunk-build.ts
43
- function ChunkModeBuildPlugin({ uno, config }) {
98
+ function ChunkModeBuildPlugin({ uno, filter }) {
44
99
  let cssPlugin;
45
- const filter = createFilter(config.include || defaultInclude, config.exclude || defaultExclude);
46
100
  const files = {};
47
101
  return {
48
102
  name: "unocss:chunk",
49
103
  apply: "build",
50
104
  enforce: "pre",
51
- configResolved(config2) {
52
- cssPlugin = config2.plugins.find((i) => i.name === "vite:css-post");
105
+ configResolved(config) {
106
+ cssPlugin = config.plugins.find((i) => i.name === "vite:css-post");
53
107
  },
54
108
  transform(code, id) {
55
- if (!filter(id))
109
+ if (!filter(code, id))
56
110
  return;
57
111
  files[id] = code;
58
112
  return null;
@@ -84,73 +138,62 @@ function ChunkModeBuildPlugin({ uno, config }) {
84
138
  }
85
139
 
86
140
  // src/modes/global/build.ts
87
- import { createFilter as createFilter2 } from "@rollup/pluginutils";
88
-
89
- // src/utils.ts
90
- import { createHash } from "crypto";
91
- function getHash(input, length = 8) {
92
- return createHash("sha256").update(input).digest("hex").substr(0, length);
93
- }
94
- function getPath(id) {
95
- return id.replace(/\?.*$/, "");
96
- }
97
-
98
- // ../plugins-common/layers.ts
99
- var VIRTUAL_ENTRY_ALIAS = [
100
- /^(?:virtual:)?uno(?::(.+))?\.css(\?.*)?$/
101
- ];
102
- var LAYER_PLACEHOLDER_RE = /(\\?")?#--unocss--\s*{\s*layer\s*:\s*(.+?);?\s*}/g;
103
- var LAYER_MARK_ALL = "__ALL__";
104
- function resolveId(id) {
105
- for (const alias of VIRTUAL_ENTRY_ALIAS) {
106
- const match = id.match(alias);
107
- if (match) {
108
- return match[1] ? {
109
- id: `/__uno_${match[1]}.css`,
110
- layer: match[1]
111
- } : {
112
- id: "/__uno.css",
113
- layer: LAYER_MARK_ALL
114
- };
115
- }
116
- }
117
- }
118
- function getLayerPlaceholder(layer) {
119
- return `#--unocss--{layer:${layer}}`;
120
- }
121
-
122
- // src/modes/global/build.ts
123
- function GlobalModeBuildPlugin({ uno, config, scan, tokens }) {
124
- const filter = createFilter2(config.include || defaultInclude, config.exclude || defaultExclude);
125
- const tasks = [];
126
- const entries = new Map();
141
+ function GlobalModeBuildPlugin({ uno, extract, tokens, modules, filter }) {
142
+ const vfsLayerMap = new Map();
143
+ let tasks = [];
144
+ let cssPlugin;
127
145
  return [
128
146
  {
129
147
  name: "unocss:global:build:scan",
130
148
  apply: "build",
131
149
  enforce: "pre",
150
+ buildStart() {
151
+ tasks = [];
152
+ vfsLayerMap.clear();
153
+ },
132
154
  transform(code, id) {
133
- if (filter(id))
134
- tasks.push(scan(code, id));
155
+ if (filter(code, id))
156
+ tasks.push(extract(code, id));
135
157
  return null;
136
158
  },
137
159
  transformIndexHtml: {
138
160
  enforce: "pre",
139
161
  transform(code, { filename }) {
140
- tasks.push(scan(code, filename));
162
+ tasks.push(extract(code, filename));
141
163
  }
142
164
  },
143
165
  resolveId(id) {
144
166
  const entry = resolveId(id);
145
167
  if (entry) {
146
- entries.set(entry.id, entry.layer);
168
+ vfsLayerMap.set(entry.id, entry.layer);
147
169
  return entry.id;
148
170
  }
149
171
  },
150
172
  load(id) {
151
- const layer = entries.get(getPath(id));
173
+ const layer = vfsLayerMap.get(getPath(id));
152
174
  if (layer)
153
175
  return getLayerPlaceholder(layer);
176
+ },
177
+ async renderChunk(_, chunk) {
178
+ const chunks = Object.keys(chunk.modules).filter((i) => modules.has(i));
179
+ if (!chunks.length)
180
+ return null;
181
+ const tokens2 = new Set();
182
+ await Promise.all(chunks.map((c) => uno.applyExtractors(modules.get(c) || "", c, tokens2)));
183
+ const { css } = await uno.generate(tokens2, { minify: true });
184
+ if (!css)
185
+ return null;
186
+ const hash = getHash(css);
187
+ const fakeCssId = `${chunk.fileName}-unocss-hash.css`;
188
+ await cssPlugin.transform(getHashPlaceholder(hash), fakeCssId);
189
+ chunk.modules[fakeCssId] = {
190
+ code: null,
191
+ originalLength: 0,
192
+ removedExports: [],
193
+ renderedExports: [],
194
+ renderedLength: 0
195
+ };
196
+ return null;
154
197
  }
155
198
  },
156
199
  {
@@ -159,8 +202,11 @@ function GlobalModeBuildPlugin({ uno, config, scan, tokens }) {
159
202
  var _a;
160
203
  return command === "build" && !((_a = options.build) == null ? void 0 : _a.ssr);
161
204
  },
205
+ configResolved(config) {
206
+ cssPlugin = config.plugins.find((i) => i.name === "vite:css-post");
207
+ },
162
208
  enforce: "post",
163
- async generateBundle(options, bundle) {
209
+ async generateBundle(_, bundle) {
164
210
  const files = Object.keys(bundle);
165
211
  const cssFiles = files.filter((i) => i.endsWith(".css"));
166
212
  if (!cssFiles.length)
@@ -168,54 +214,29 @@ function GlobalModeBuildPlugin({ uno, config, scan, tokens }) {
168
214
  await Promise.all(tasks);
169
215
  const result = await uno.generate(tokens, { minify: true });
170
216
  let replaced = false;
171
- const cssReplacedMap = {};
172
217
  for (const file of cssFiles) {
173
218
  const chunk = bundle[file];
174
219
  if (chunk.type === "asset" && typeof chunk.source === "string") {
175
- let currentReplaced = false;
176
- chunk.source = chunk.source.replace(LAYER_PLACEHOLDER_RE, (_, __, layer) => {
177
- currentReplaced = true;
220
+ chunk.source = chunk.source.replace(HASH_PLACEHOLDER_RE, "").replace(LAYER_PLACEHOLDER_RE, (_2, __, layer) => {
178
221
  replaced = true;
179
- return layer === LAYER_MARK_ALL ? result.getLayers(void 0, Array.from(entries.values())) : result.getLayer(layer) || "";
222
+ return layer === LAYER_MARK_ALL ? result.getLayers(void 0, Array.from(vfsLayerMap.values())) : result.getLayer(layer) || "";
180
223
  });
181
- if (currentReplaced) {
182
- const newName = chunk.fileName.replace(/\.(\w+)\.css$/, `.${getHash(chunk.source)}.css`);
183
- cssReplacedMap[chunk.fileName] = newName;
184
- chunk.fileName = newName;
185
- }
186
224
  }
187
225
  }
188
226
  if (!replaced)
189
227
  this.error(new Error("[unocss] does not found CSS placeholder in the generated chunks,\nthis is likely an internal bug of unocss vite plugin"));
190
- const entires = Object.entries(cssReplacedMap);
191
- if (!entires.length)
192
- return;
193
- for (const file of files) {
194
- const chunk = bundle[file];
195
- if (chunk.type === "chunk" && typeof chunk.code === "string") {
196
- for (const [k, v] of entires)
197
- chunk.code = chunk.code.replace(k, v);
198
- } else if (chunk.type === "asset" && typeof chunk.source === "string") {
199
- for (const [k, v] of entires)
200
- chunk.source = chunk.source.replace(k, v);
201
- }
202
- }
203
228
  }
204
229
  }
205
230
  ];
206
231
  }
207
232
 
208
- // src/modes/global/dev.ts
209
- import { createFilter as createFilter3 } from "@rollup/pluginutils";
210
-
211
233
  // src/modes/global/shared.ts
212
234
  var READY_CALLBACK_DEFAULT = "/__unocss_ready";
213
235
 
214
236
  // src/modes/global/dev.ts
215
237
  var WARN_TIMEOUT = 2e3;
216
- function GlobalModeDevPlugin({ config, uno, tokens, onInvalidate, scan }) {
238
+ function GlobalModeDevPlugin({ uno, tokens, onInvalidate, extract, filter }) {
217
239
  const servers = [];
218
- const filter = createFilter3(config.include || defaultInclude, config.exclude || defaultExclude);
219
240
  const tasks = [];
220
241
  const entries = new Map();
221
242
  let invalidateTimer;
@@ -286,14 +307,14 @@ function GlobalModeDevPlugin({ config, uno, tokens, onInvalidate, scan }) {
286
307
  });
287
308
  },
288
309
  transform(code, id) {
289
- if (filter(id))
290
- scan(code, id);
310
+ if (filter(code, id))
311
+ extract(code, id);
291
312
  return null;
292
313
  },
293
314
  transformIndexHtml: {
294
315
  enforce: "pre",
295
316
  transform(code, { filename }) {
296
- scan(code, filename);
317
+ extract(code, filename);
297
318
  }
298
319
  },
299
320
  resolveId(id) {
@@ -316,9 +337,9 @@ function GlobalModeDevPlugin({ config, uno, tokens, onInvalidate, scan }) {
316
337
  },
317
338
  {
318
339
  name: "unocss:global:post",
319
- apply(config2, env) {
340
+ apply(config, env) {
320
341
  var _a;
321
- return env.command === "serve" && !((_a = config2.build) == null ? void 0 : _a.ssr);
342
+ return env.command === "serve" && !((_a = config.build) == null ? void 0 : _a.ssr);
322
343
  },
323
344
  enforce: "post",
324
345
  transform(code, id) {
@@ -339,13 +360,11 @@ function GlobalModePlugin(ctx) {
339
360
  }
340
361
 
341
362
  // src/modes/per-module.ts
342
- import { createFilter as createFilter4 } from "@rollup/pluginutils";
343
363
  var VIRTUAL_PREFIX = "/@unocss/";
344
364
  var SCOPE_IMPORT_RE = / from (['"])(@unocss\/scope)\1/;
345
- function PerModuleModePlugin({ uno, config }) {
365
+ function PerModuleModePlugin({ uno, filter }) {
346
366
  const moduleMap = new Map();
347
367
  let server;
348
- const filter = createFilter4(config.include || defaultInclude, config.exclude || defaultExclude);
349
368
  const invalidate = (hash) => {
350
369
  if (!server)
351
370
  return;
@@ -371,7 +390,7 @@ function PerModuleModePlugin({ uno, config }) {
371
390
  server = _server;
372
391
  },
373
392
  async transform(code, id) {
374
- if (!filter(id))
393
+ if (!filter(code, id))
375
394
  return;
376
395
  const hash = getHash(id);
377
396
  const hasScope = code.match(SCOPE_IMPORT_RE);
@@ -405,9 +424,9 @@ ${css}`;
405
424
  }
406
425
 
407
426
  // src/modes/vue-scoped.ts
408
- import { createFilter as createFilter5 } from "@rollup/pluginutils";
427
+ import { createFilter as createFilter2 } from "@rollup/pluginutils";
409
428
  function VueScopedPlugin({ uno, config }) {
410
- const filter = createFilter5(config.include || [/\.vue$/], config.exclude || defaultExclude);
429
+ const filter = createFilter2(config.include || [/\.vue$/], config.exclude || defaultExclude);
411
430
  async function transformSFC(code) {
412
431
  const { css } = await uno.generate(code);
413
432
  if (!css)
@@ -436,23 +455,18 @@ function VueScopedPlugin({ uno, config }) {
436
455
  }
437
456
 
438
457
  // src/config-hmr.ts
439
- import { loadConfig } from "@unocss/config";
440
- function ConfigHMRPlugin({ uno, configFilepath: filepath, invalidate, tokens, modules }) {
458
+ function ConfigHMRPlugin({ uno, configFilepath, reloadConfig }) {
441
459
  return {
442
460
  name: "unocss:config",
443
461
  configureServer(server) {
444
462
  uno.config.envMode = "dev";
445
- if (!filepath)
463
+ if (!configFilepath)
446
464
  return;
447
- server.watcher.add(filepath);
465
+ server.watcher.add(configFilepath);
448
466
  server.watcher.on("change", async (p) => {
449
- if (p !== filepath)
467
+ if (p !== configFilepath)
450
468
  return;
451
- uno.setConfig(loadConfig(filepath).config);
452
- uno.config.envMode = "dev";
453
- tokens.clear();
454
- await Promise.all(modules.map((code, id) => uno.applyExtractors(code, id, tokens)));
455
- invalidate();
469
+ reloadConfig();
456
470
  server.ws.send({
457
471
  type: "custom",
458
472
  event: "unocss:config-changed"
@@ -468,10 +482,9 @@ function defineConfig(config) {
468
482
  }
469
483
  function UnocssPlugin(configOrPath, defaults = {}) {
470
484
  var _a;
471
- const { config = {}, filepath } = loadConfig2(configOrPath);
485
+ const ctx = createContext(configOrPath, defaults);
486
+ const { config } = ctx;
472
487
  const mode = (_a = config.mode) != null ? _a : "global";
473
- const uno = createGenerator(config, defaults);
474
- const ctx = createContext(uno, config, filepath);
475
488
  const plugins = [
476
489
  ConfigHMRPlugin(ctx)
477
490
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/vite",
3
- "version": "0.11.3",
3
+ "version": "0.12.0",
4
4
  "description": "The Vite plugin for UnoCSS",
5
5
  "keywords": [
6
6
  "unocss",
@@ -34,10 +34,10 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@rollup/pluginutils": "^4.1.1",
37
- "@unocss/config": "0.11.3",
38
- "@unocss/core": "0.11.3",
39
- "@unocss/scope": "0.11.3",
40
- "@unocss/inspector": "0.11.3"
37
+ "@unocss/config": "0.12.0",
38
+ "@unocss/core": "0.12.0",
39
+ "@unocss/scope": "0.12.0",
40
+ "@unocss/inspector": "0.12.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "vite": "^2.6.13"