@unocss/vite 66.1.0-beta.8 → 66.1.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.
Files changed (2) hide show
  1. package/dist/index.mjs +61 -168
  2. package/package.json +7 -6
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import process$1 from 'node:process';
2
2
  import { createRecoveryConfigLoader } from '@unocss/config';
3
- import { cssIdRE, createGenerator, BetterMap, toEscapedSelector, LAYER_IMPORTS, LAYER_PREFLIGHTS, notNull } from '@unocss/core';
3
+ import { cssIdRE, createGenerator, BetterMap, toEscapedSelector, LAYER_PREFLIGHTS, LAYER_IMPORTS, notNull } from '@unocss/core';
4
4
  import { createFilter } from 'unplugin-utils';
5
5
  import UnocssInspector from '@unocss/inspector';
6
6
  import fs from 'node:fs';
@@ -10,6 +10,7 @@ import fs$1 from 'node:fs/promises';
10
10
  import { glob } from 'tinyglobby';
11
11
  import remapping from '@ampproject/remapping';
12
12
  import MagicString from 'magic-string';
13
+ import { resolve as resolve$1 } from 'pathe';
13
14
  import { createHash } from 'node:crypto';
14
15
  import { Buffer } from 'node:buffer';
15
16
 
@@ -19,6 +20,12 @@ const CSS_PLACEHOLDER = "@unocss-placeholder";
19
20
  const SKIP_START_COMMENT = "@unocss-skip-start";
20
21
  const SKIP_END_COMMENT = "@unocss-skip-end";
21
22
  const SKIP_COMMENT_RE = new RegExp(`(//\\s*?${SKIP_START_COMMENT}\\s*?|\\/\\*\\s*?${SKIP_START_COMMENT}\\s*?\\*\\/|<!--\\s*?${SKIP_START_COMMENT}\\s*?-->)[\\s\\S]*?(//\\s*?${SKIP_END_COMMENT}\\s*?|\\/\\*\\s*?${SKIP_END_COMMENT}\\s*?\\*\\/|<!--\\s*?${SKIP_END_COMMENT}\\s*?-->)`, "g");
23
+ const VIRTUAL_ENTRY_ALIAS = [
24
+ /^(?:virtual:)?uno(?::(.+))?\.css(\?.*)?$/
25
+ ];
26
+ const LAYER_MARK_ALL = "__ALL__";
27
+ const RESOLVED_ID_WITH_QUERY_RE = /[/\\]__uno(_.*?)?\.css(\?.*)?$/;
28
+ const RESOLVED_ID_RE = /[/\\]__uno(?:_(.*?))?\.css$/;
22
29
 
23
30
  const defaultPipelineExclude = [cssIdRE];
24
31
  const defaultPipelineInclude = [/\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/];
@@ -334,8 +341,9 @@ function ChunkModeBuildPlugin(ctx) {
334
341
  const tokens = /* @__PURE__ */ new Set();
335
342
  await Promise.all(chunks.map((c) => ctx.uno.applyExtractors(c, void 0, tokens)));
336
343
  const { css } = await ctx.uno.generate(tokens);
344
+ const cssPostTransformHandler = "handler" in cssPlugin.transform ? cssPlugin.transform.handler : cssPlugin.transform;
337
345
  const fakeCssId = `${chunk.fileName}.css`;
338
- await cssPlugin.transform(css, fakeCssId);
346
+ await cssPostTransformHandler.call(this, css, fakeCssId);
339
347
  chunk.modules[fakeCssId] = {
340
348
  code: null,
341
349
  originalLength: 0,
@@ -383,28 +391,6 @@ function restoreSkipCode(code, map) {
383
391
  code = code.replaceAll(withHashKey, matched);
384
392
  return code;
385
393
  }
386
- function replaceAsync(string, searchValue, replacer) {
387
- try {
388
- if (typeof replacer === "function") {
389
- const values = [];
390
- String.prototype.replace.call(string, searchValue, (...args) => {
391
- values.push(replacer(...args));
392
- return "";
393
- });
394
- return Promise.all(values).then((resolvedValues) => {
395
- return String.prototype.replace.call(string, searchValue, () => {
396
- return resolvedValues.shift() || "";
397
- });
398
- });
399
- } else {
400
- return Promise.resolve(
401
- String.prototype.replace.call(string, searchValue, replacer)
402
- );
403
- }
404
- } catch (error) {
405
- return Promise.reject(error);
406
- }
407
- }
408
394
 
409
395
  async function applyTransformers(ctx, original, id, enforce = "default") {
410
396
  if (original.includes(IGNORE_COMMENT))
@@ -487,23 +473,18 @@ async function setupContentExtractor(ctx, shouldWatch = false) {
487
473
  }
488
474
  }
489
475
 
490
- function getHash(input, length = 8) {
491
- return createHash("sha256").update(input).digest("hex").slice(0, length);
492
- }
493
-
494
- const VIRTUAL_ENTRY_ALIAS = [
495
- /^(?:virtual:)?uno(?::(.+))?\.css(\?.*)?$/
496
- ];
497
- const LAYER_MARK_ALL = "__ALL__";
498
- const RESOLVED_ID_WITH_QUERY_RE = /[/\\]__uno(_.*?)?\.css(\?.*)?$/;
499
- const RESOLVED_ID_RE = /[/\\]__uno(?:_(.*?))?\.css$/;
500
- function resolveId(id) {
476
+ function resolveId(id, importer) {
501
477
  if (id.match(RESOLVED_ID_WITH_QUERY_RE))
502
478
  return id;
503
479
  for (const alias of VIRTUAL_ENTRY_ALIAS) {
504
480
  const match = id.match(alias);
505
481
  if (match) {
506
- return match[1] ? `/__uno_${match[1]}.css` : "/__uno.css";
482
+ let virtual = match[1] ? `__uno_${match[1]}.css` : "__uno.css";
483
+ if (importer)
484
+ virtual = resolve$1(importer, "..", virtual);
485
+ else
486
+ virtual = `/${virtual}`;
487
+ return virtual;
507
488
  }
508
489
  }
509
490
  }
@@ -512,24 +493,16 @@ function resolveLayer(id) {
512
493
  if (match)
513
494
  return match[1] || LAYER_MARK_ALL;
514
495
  }
515
- const LAYER_PLACEHOLDER_RE = /#--unocss--\s*\{\s*layer\s*:\s*(.+?)\s*(?:;\s*escape-view\s*:\s*(.+?)\s*)?;?\s*\}/g;
516
496
  function getLayerPlaceholder(layer) {
517
497
  return `#--unocss--{layer:${layer};escape-view:\\"\\'\\\`\\\\}`;
518
498
  }
519
- const HASH_PLACEHOLDER_RE = /#--unocss-hash--\s*\{\s*content\s*:\s*\\*"([^\\"]+)\\*";?\s*\}/g;
520
- function getHashPlaceholder(hash) {
521
- return `#--unocss-hash--{content:"${hash}"}`;
522
- }
523
499
 
524
500
  const MESSAGE_UNOCSS_ENTRY_NOT_FOUND = "[unocss] Entry module not found. Did you add `import 'uno.css'` in your main entry?";
525
501
 
526
- function isLegacyChunk(chunk, options) {
527
- return options.format === "system" && chunk.fileName.includes("-legacy");
528
- }
529
502
  function GlobalModeBuildPlugin(ctx) {
530
503
  const { ready, extract, tokens, filter, getConfig, tasks, flushTasks } = ctx;
531
- const vfsLayers = /* @__PURE__ */ new Set();
532
- const layerImporterMap = /* @__PURE__ */ new Map();
504
+ const vfsLayers = /* @__PURE__ */ new Map();
505
+ const resolveContexts = /* @__PURE__ */ new Map();
533
506
  let viteConfig;
534
507
  const cssPostPlugins = /* @__PURE__ */ new Map();
535
508
  const cssPlugins = /* @__PURE__ */ new Map();
@@ -539,7 +512,9 @@ function GlobalModeBuildPlugin(ctx) {
539
512
  } = await getConfig();
540
513
  if (!cssPlugins.get(dir) || !postcss)
541
514
  return css;
542
- const result = await cssPlugins.get(dir).transform.call(ctx2, css, id);
515
+ const cssPlugin = cssPlugins.get(dir);
516
+ const cssPluginTransformHandler = "handler" in cssPlugin.transform ? cssPlugin.transform.handler : cssPlugin.transform;
517
+ const result = await cssPluginTransformHandler.call(ctx2, css, id);
543
518
  if (!result)
544
519
  return css;
545
520
  if (typeof result === "string")
@@ -559,7 +534,7 @@ function GlobalModeBuildPlugin(ctx) {
559
534
  lastTokenSize = tokens.size;
560
535
  return lastResult;
561
536
  }
562
- let replaced = false;
537
+ const cssContentCache = /* @__PURE__ */ new Map();
563
538
  return [
564
539
  {
565
540
  name: "unocss:global:build:scan",
@@ -567,6 +542,7 @@ function GlobalModeBuildPlugin(ctx) {
567
542
  enforce: "pre",
568
543
  async buildStart() {
569
544
  vfsLayers.clear();
545
+ cssContentCache.clear();
570
546
  tasks.length = 0;
571
547
  lastTokenSize = 0;
572
548
  lastResult = void 0;
@@ -588,13 +564,16 @@ function GlobalModeBuildPlugin(ctx) {
588
564
  }
589
565
  },
590
566
  resolveId(id, importer) {
591
- const entry = resolveId(id);
567
+ const entry = resolveId(id, importer);
592
568
  if (entry) {
593
569
  const layer = resolveLayer(entry);
594
570
  if (layer) {
595
- vfsLayers.add(layer);
596
- if (importer)
597
- layerImporterMap.set(importer, entry);
571
+ if (vfsLayers.has(layer)) {
572
+ this.warn(`[unocss] ${JSON.stringify(id)} is being imported multiple times in different files, using the first occurrence: ${JSON.stringify(vfsLayers.get(layer))}`);
573
+ return vfsLayers.get(layer);
574
+ }
575
+ vfsLayers.set(layer, entry);
576
+ resolveContexts.set(layer, this);
598
577
  }
599
578
  return entry;
600
579
  }
@@ -602,17 +581,14 @@ function GlobalModeBuildPlugin(ctx) {
602
581
  load(id) {
603
582
  const layer = resolveLayer(getPath(id));
604
583
  if (layer) {
605
- vfsLayers.add(layer);
606
- return getLayerPlaceholder(layer);
607
- }
608
- },
609
- moduleParsed({ id, importedIds }) {
610
- if (!layerImporterMap.has(id))
611
- return;
612
- const layerKey = layerImporterMap.get(id);
613
- if (!importedIds.includes(layerKey)) {
614
- layerImporterMap.delete(id);
615
- vfsLayers.delete(resolveLayer(layerKey));
584
+ if (!vfsLayers.has(layer)) {
585
+ this.error(`[unocss] layer ${JSON.stringify(id)} is imported but not being resolved before, it might be an internal bug of UnoCSS`);
586
+ }
587
+ return {
588
+ code: getLayerPlaceholder(layer),
589
+ map: null,
590
+ moduleSideEffects: true
591
+ };
616
592
  }
617
593
  },
618
594
  async configResolved(config) {
@@ -635,38 +611,6 @@ function GlobalModeBuildPlugin(ctx) {
635
611
  if (cssPlugin)
636
612
  distDirs.forEach((dir) => cssPlugins.set(dir, cssPlugin));
637
613
  await ready;
638
- },
639
- // we inject a hash to chunk before the dist hash calculation to make sure
640
- // the hash is different when unocss changes
641
- async renderChunk(_, chunk, options) {
642
- const isLegacy = isLegacyChunk(chunk, options);
643
- if (isLegacy && (!ctx.uno.config.legacy || ctx.uno.config.legacy.renderModernChunks))
644
- return null;
645
- if (!Object.keys(chunk.modules).some((i) => RESOLVED_ID_RE.test(i)))
646
- return null;
647
- const cssPost = cssPostPlugins.get(options.dir);
648
- if (!cssPost) {
649
- this.warn("[unocss] failed to find vite:css-post plugin. It might be an internal bug of UnoCSS");
650
- return null;
651
- }
652
- let { css } = await generateAll();
653
- const fakeCssId = `${viteConfig.root}/${chunk.fileName}-unocss-hash.css`;
654
- css = await applyCssTransform(css, fakeCssId, options.dir, this);
655
- const transformHandler = "handler" in cssPost.transform ? cssPost.transform.handler : cssPost.transform;
656
- if (isLegacy) {
657
- await transformHandler.call({}, css, "/__uno.css");
658
- } else {
659
- const hash = getHash(css);
660
- await transformHandler.call({}, getHashPlaceholder(hash), fakeCssId);
661
- }
662
- chunk.modules[fakeCssId] = {
663
- code: null,
664
- originalLength: 0,
665
- removedExports: [],
666
- renderedExports: [],
667
- renderedLength: 0
668
- };
669
- return null;
670
614
  }
671
615
  },
672
616
  {
@@ -683,17 +627,16 @@ function GlobalModeBuildPlugin(ctx) {
683
627
  name: "unocss:global:build:generate",
684
628
  apply: "build",
685
629
  async renderChunk(code, chunk, options) {
686
- if (isLegacyChunk(chunk, options))
687
- return null;
688
- if (!Object.keys(chunk.modules).some((i) => RESOLVED_ID_RE.test(i)))
630
+ const entryModules = Object.keys(chunk.modules).filter((id) => RESOLVED_ID_RE.test(id));
631
+ if (!entryModules.length)
689
632
  return null;
690
633
  const cssPost = cssPostPlugins.get(options.dir);
691
634
  if (!cssPost) {
692
635
  this.warn("[unocss] failed to find vite:css-post plugin. It might be an internal bug of UnoCSS");
693
636
  return null;
694
637
  }
638
+ const cssPostTransformHandler = "handler" in cssPost.transform ? cssPost.transform.handler : cssPost.transform;
695
639
  const result = await generateAll();
696
- const importsLayer = result.getLayer(LAYER_IMPORTS) ?? "";
697
640
  const fakeCssId = `${viteConfig.root}/${chunk.fileName}-unocss-hash.css`;
698
641
  const preflightLayers = ctx.uno.config.preflights?.map((i) => i.layer).concat(LAYER_PREFLIGHTS).filter(Boolean);
699
642
  await Promise.all(preflightLayers.map((i) => result.setLayer(i, async (layerContent) => {
@@ -702,85 +645,35 @@ function GlobalModeBuildPlugin(ctx) {
702
645
  const postTransform = await applyTransformers(ctx, defaultTransform?.code || preTransform?.code || layerContent, fakeCssId, "post");
703
646
  return postTransform?.code || defaultTransform?.code || preTransform?.code || layerContent;
704
647
  })));
705
- const cssWithLayers = await Promise.all(Array.from(vfsLayers).map(async (layer) => {
706
- const layerStart = `#--unocss-layer-start--${layer}--{start:${layer}}`;
707
- const layerEnd = `#--unocss-layer-end--${layer}--{end:${layer}}`;
708
- let layerContent;
709
- if (layer === LAYER_MARK_ALL) {
710
- layerContent = result.getLayers(void 0, [...vfsLayers, LAYER_IMPORTS]);
711
- } else {
712
- layerContent = result.getLayer(layer) || "";
713
- }
714
- return `${importsLayer}${layerStart} ${layerContent} ${layerEnd}`;
715
- }));
716
- const css = await applyCssTransform(cssWithLayers.join(""), fakeCssId, options.dir, this);
717
- const transformHandler = "handler" in cssPost.transform ? cssPost.transform.handler : cssPost.transform;
718
- await transformHandler.call({}, css, fakeCssId);
719
- }
720
- },
721
- {
722
- name: "unocss:global:build:bundle",
723
- apply: "build",
724
- enforce: "post",
725
- // rewrite the css placeholders
726
- async generateBundle(options, bundle) {
727
- const checkJs = ["umd", "amd", "iife"].includes(options.format);
728
- const files = Object.keys(bundle).filter((i) => i.endsWith(".css") || checkJs && i.endsWith(".js"));
729
- if (!files.length)
730
- return;
648
+ for (const mod of entryModules) {
649
+ const layer = RESOLVED_ID_RE.exec(mod)?.[1] || LAYER_MARK_ALL;
650
+ const layerContent = layer === LAYER_MARK_ALL ? result.getLayers(void 0, [LAYER_IMPORTS, ...vfsLayers.keys()]) : result.getLayer(layer) || "";
651
+ const css = await applyCssTransform(
652
+ layerContent,
653
+ mod,
654
+ options.dir,
655
+ // .emitFile in Rollup has different FileEmitter instance in load/transform hooks and renderChunk hooks
656
+ // here we need to store the resolveId context to use it in the vite:css transform hook
657
+ resolveContexts.get(layer) || this
658
+ );
659
+ await cssPostTransformHandler.call(this, css, mod);
660
+ }
661
+ },
662
+ async buildEnd() {
731
663
  if (!vfsLayers.size) {
732
- if (replaced)
733
- return;
734
664
  if ((await getConfig()).checkImport) {
735
665
  this.warn(MESSAGE_UNOCSS_ENTRY_NOT_FOUND);
736
666
  }
737
- return;
738
- }
739
- const getLayer = (layer, input, replace = false) => {
740
- const re = new RegExp(`#--unocss-layer-start--${layer}--\\{start:${layer}\\}([\\s\\S]*?)#--unocss-layer-end--${layer}--\\{end:${layer}\\}`, "g");
741
- if (replace)
742
- return input.replace(re, "");
743
- const match = re.exec(input);
744
- if (match)
745
- return match[1];
746
- return "";
747
- };
748
- for (const file of files) {
749
- const chunk = bundle[file];
750
- if (chunk.type === "asset" && typeof chunk.source === "string") {
751
- const css = chunk.source.replace(HASH_PLACEHOLDER_RE, "");
752
- chunk.source = await replaceAsync(css, LAYER_PLACEHOLDER_RE, async (_, layer) => {
753
- replaced = true;
754
- return getLayer(layer.trim(), css);
755
- });
756
- Array.from(vfsLayers).forEach((layer) => {
757
- chunk.source = getLayer(layer, chunk.source, true);
758
- });
759
- } else if (chunk.type === "chunk" && typeof chunk.code === "string") {
760
- const js = chunk.code.replace(HASH_PLACEHOLDER_RE, "");
761
- chunk.code = await replaceAsync(js, LAYER_PLACEHOLDER_RE, async (_, layer) => {
762
- replaced = true;
763
- const css = getLayer(layer.trim(), js);
764
- return css.replace(/\n/g, "").replace(/(?<!\\)(['"])/g, "\\$1");
765
- });
766
- Array.from(vfsLayers).forEach((layer) => {
767
- chunk.code = getLayer(layer, chunk.code, true);
768
- });
769
- }
770
- }
771
- if (!replaced) {
772
- let msg = "[unocss] does not found CSS placeholder in the generated chunks";
773
- if (viteConfig.build.lib && checkJs)
774
- msg += "\nIt seems you are building in library mode, it's recommended to set `build.cssCodeSplit` to true.\nSee https://github.com/vitejs/vite/issues/1579";
775
- else
776
- msg += "\nThis is likely an internal bug of unocss vite plugin";
777
- this.warn(msg);
778
667
  }
779
668
  }
780
669
  }
781
670
  ];
782
671
  }
783
672
 
673
+ function getHash(input, length = 8) {
674
+ return createHash("sha256").update(input).digest("hex").slice(0, length);
675
+ }
676
+
784
677
  const WARN_TIMEOUT = 2e4;
785
678
  const WS_EVENT_PREFIX = "unocss:hmr";
786
679
  const HASH_LENGTH = 6;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unocss/vite",
3
3
  "type": "module",
4
- "version": "66.1.0-beta.8",
4
+ "version": "66.1.0",
5
5
  "description": "The Vite plugin for UnoCSS",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -52,14 +52,15 @@
52
52
  "@ampproject/remapping": "^2.3.0",
53
53
  "chokidar": "^3.6.0",
54
54
  "magic-string": "^0.30.17",
55
- "tinyglobby": "^0.2.12",
55
+ "pathe": "^2.0.3",
56
+ "tinyglobby": "^0.2.13",
56
57
  "unplugin-utils": "^0.2.4",
57
- "@unocss/core": "66.1.0-beta.8",
58
- "@unocss/config": "66.1.0-beta.8",
59
- "@unocss/inspector": "66.1.0-beta.8"
58
+ "@unocss/config": "66.1.0",
59
+ "@unocss/core": "66.1.0",
60
+ "@unocss/inspector": "66.1.0"
60
61
  },
61
62
  "devDependencies": {
62
- "vite": "^6.2.3"
63
+ "vite": "^6.2.7"
63
64
  },
64
65
  "scripts": {
65
66
  "build": "unbuild",