@unocss/vite 0.30.12 → 0.31.2

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
@@ -40,27 +40,40 @@ This mode enables a set of Vite plugins for `build` and for `dev` with `HMR` sup
40
40
 
41
41
  The generated `css` will be a global stylesheet injected on the `index.html`.
42
42
 
43
- ### vue-scoped (WIP)
43
+ ### vue-scoped
44
44
 
45
45
  This mode will inject generated CSS to Vue SFC's `<style scoped>` for isolation.
46
46
 
47
- ### svelte-scoped (WIP)
47
+ ### svelte-scoped
48
48
 
49
49
  This mode will inject generated CSS to Svelte's `<style>` for isolation.
50
50
 
51
- ### per-module (WIP)
51
+ ### shadow-dom
52
+
53
+ Since `Web Components` uses `Shadow DOM`, there is no way to style content directly from a global stylesheet (unless you use `custom css vars`, those will penetrate the `Shadow DOM`), you need to inline the generated css by the plugin into the `Shadow DOM` style.
54
+
55
+ To inline the generated css, you only need to configure the plugin mode to `shadow-dom` and include `@unocss-placeholder` magic placeholder on each web component style css block.
56
+
57
+ ### per-module (Experimental)
52
58
 
53
59
  This mode will generate a CSS sheet for each module, can be scoped.
54
60
 
55
- ### dist-chunk (WIP)
61
+ ### dist-chunk (Experimental)
56
62
 
57
63
  This mode will generate a CSS sheet for each code chunk on build, great for MPA.
58
64
 
59
- ### shadow-dom
65
+ ## "Design in DevTools"
60
66
 
61
- Since `Web Components` uses `Shadow DOM`, there is no way to style content directly from a global stylesheet (unless you use `custom css vars`, those will penetrate the `Shadow DOM`), you need to inline the generated css by the plugin into the `Shadow DOM` style.
67
+ Because of limitation of "on-demand" where the DevTools don't know those you haven't used in your source code yet. So if you want to try how things work by directly changing the classes in DevTools, just add the following lines to your main entry.
62
68
 
63
- To inline the generated css, you only need to configure the plugin mode to `shadow-dom` and include `@unocss-placeholder` magic placeholder on each web component style css block.
69
+ ```ts
70
+ import 'uno.css'
71
+ import 'virtual:unocss-devtools'
72
+ ```
73
+
74
+ > ⚠️ Please use it with caution, under the hood we use [`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) to detect the class changes. Which means not only your manual changes but also the changes made by your scripts will be detected and included in the stylesheet. This could cause some misalignment between dev and the production build when you add dynamic classes based on some logic in script tags. We recommended adding your dynamic parts to the [safelist](https://github.com/unocss/unocss/issues/511) or setup UI regression tests for your production build if possible.
75
+
76
+ `virtual:unocss-devtools` will be an empty bundle in production.
64
77
 
65
78
  ## Frameworks
66
79
 
@@ -284,7 +297,7 @@ export class MyElement extends LitElement {
284
297
  :host {...}
285
298
  @unocss-placeholder
286
299
  `
287
- ...
300
+ // ...
288
301
  }
289
302
  ```
290
303
 
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ function post(data) {
4
+ return fetch("__POST_PATH__", {
5
+ method: "POST",
6
+ headers: {
7
+ "Content-Type": "application/json"
8
+ },
9
+ body: JSON.stringify(data)
10
+ });
11
+ }
12
+ function include(set, v) {
13
+ for (const i of v)
14
+ set.add(i);
15
+ }
16
+ console.log("%c[unocss] devtools support enabled %c\nread more at https://windicss.org", "background:#0ea5e9; color:white; padding: 1px 4px; border-radius: 3px;", "");
17
+ const visitedClasses = /* @__PURE__ */ new Set();
18
+ const pendingClasses = /* @__PURE__ */ new Set();
19
+ let _timer;
20
+ function schedule() {
21
+ if (_timer != null)
22
+ clearTimeout(_timer);
23
+ _timer = setTimeout(() => {
24
+ if (pendingClasses.size) {
25
+ post({ type: "add-classes", data: Array.from(pendingClasses) });
26
+ include(visitedClasses, pendingClasses);
27
+ pendingClasses.clear();
28
+ }
29
+ }, 10);
30
+ }
31
+ const mutationObserver = new MutationObserver((mutations) => {
32
+ mutations.forEach((mutation) => {
33
+ if (mutation.attributeName === "class" && mutation.target) {
34
+ Array.from(mutation.target.classList || []).forEach((i) => {
35
+ if (!visitedClasses.has(i))
36
+ pendingClasses.add(i);
37
+ });
38
+ schedule();
39
+ }
40
+ });
41
+ });
42
+ mutationObserver.observe(document.documentElement || document.body, {
43
+ childList: true,
44
+ subtree: true,
45
+ attributes: true
46
+ });
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,44 @@
1
+ function post(data) {
2
+ return fetch("__POST_PATH__", {
3
+ method: "POST",
4
+ headers: {
5
+ "Content-Type": "application/json"
6
+ },
7
+ body: JSON.stringify(data)
8
+ });
9
+ }
10
+ function include(set, v) {
11
+ for (const i of v)
12
+ set.add(i);
13
+ }
14
+ console.log("%c[unocss] devtools support enabled %c\nread more at https://windicss.org", "background:#0ea5e9; color:white; padding: 1px 4px; border-radius: 3px;", "");
15
+ const visitedClasses = /* @__PURE__ */ new Set();
16
+ const pendingClasses = /* @__PURE__ */ new Set();
17
+ let _timer;
18
+ function schedule() {
19
+ if (_timer != null)
20
+ clearTimeout(_timer);
21
+ _timer = setTimeout(() => {
22
+ if (pendingClasses.size) {
23
+ post({ type: "add-classes", data: Array.from(pendingClasses) });
24
+ include(visitedClasses, pendingClasses);
25
+ pendingClasses.clear();
26
+ }
27
+ }, 10);
28
+ }
29
+ const mutationObserver = new MutationObserver((mutations) => {
30
+ mutations.forEach((mutation) => {
31
+ if (mutation.attributeName === "class" && mutation.target) {
32
+ Array.from(mutation.target.classList || []).forEach((i) => {
33
+ if (!visitedClasses.has(i))
34
+ pendingClasses.add(i);
35
+ });
36
+ schedule();
37
+ }
38
+ });
39
+ });
40
+ mutationObserver.observe(document.documentElement || document.body, {
41
+ childList: true,
42
+ subtree: true,
43
+ attributes: true
44
+ });
package/dist/index.cjs CHANGED
@@ -8,11 +8,15 @@ const config = require('@unocss/config');
8
8
  const core = require('@unocss/core');
9
9
  const crypto = require('crypto');
10
10
  const MagicString = require('magic-string');
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const url = require('url');
11
14
 
12
15
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
13
16
 
14
17
  const UnocssInspector__default = /*#__PURE__*/_interopDefaultLegacy(UnocssInspector);
15
18
  const MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
19
+ const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
16
20
 
17
21
  const regexCssId = /\.(css|postcss|sass|scss|less|stylus|styl)$/;
18
22
  const defaultExclude = [regexCssId];
@@ -48,7 +52,8 @@ function getHashPlaceholder(hash) {
48
52
  const INCLUDE_COMMENT = "@unocss-include";
49
53
  const CSS_PLACEHOLDER = "@unocss-placeholder";
50
54
 
51
- function createContext(configOrPath, defaults = {}, extraConfigSources = []) {
55
+ function createContext(configOrPath, defaults = {}, extraConfigSources = [], resolveConfigResult = () => {
56
+ }) {
52
57
  const loadConfig = config.createConfigLoader(configOrPath, extraConfigSources);
53
58
  let rawConfig = {};
54
59
  const uno = core.createGenerator(rawConfig, defaults);
@@ -59,6 +64,7 @@ function createContext(configOrPath, defaults = {}, extraConfigSources = []) {
59
64
  const ready = reloadConfig();
60
65
  async function reloadConfig() {
61
66
  const result = await loadConfig();
67
+ resolveConfigResult(result);
62
68
  rawConfig = result.config;
63
69
  uno.setConfig(rawConfig);
64
70
  uno.config.envMode = "dev";
@@ -246,7 +252,7 @@ function GlobalModeBuildPlugin({ uno, ready, extract, tokens, modules, filter })
246
252
  }
247
253
 
248
254
  const WARN_TIMEOUT = 2e4;
249
- const WS_EVENT_PREFIX = "custom:unocss:";
255
+ const WS_EVENT_PREFIX = "unocss:hmr";
250
256
  function GlobalModeDevPlugin({ uno, tokens, onInvalidate, extract, filter }) {
251
257
  const servers = [];
252
258
  let base = "";
@@ -315,18 +321,9 @@ function GlobalModeDevPlugin({ uno, tokens, onInvalidate, extract, filter }) {
315
321
  configResolved,
316
322
  async configureServer(_server) {
317
323
  servers.push(_server);
318
- _server.ws.on("connection", (ws) => {
319
- ws.on("open", () => {
320
- invalidate();
321
- });
322
- ws.on("message", (msg) => {
323
- const message = String(msg);
324
- if (!message.startsWith(WS_EVENT_PREFIX))
325
- return;
326
- const servedTime = +message.slice(WS_EVENT_PREFIX.length);
327
- if (servedTime < lastUpdate)
328
- invalidate(0);
329
- });
324
+ _server.ws.on(WS_EVENT_PREFIX, (servedTime) => {
325
+ if (servedTime < lastUpdate)
326
+ invalidate(0);
330
327
  });
331
328
  },
332
329
  async buildStart() {
@@ -370,18 +367,9 @@ function GlobalModeDevPlugin({ uno, tokens, onInvalidate, extract, filter }) {
370
367
  },
371
368
  enforce: "post",
372
369
  transform(code, id) {
373
- if (id.includes("@vite/client") || id.includes("vite/dist/client/client.mjs")) {
374
- return code.replace("return hot", [
375
- "let __buffer = []",
376
- "function unoSendBuffer() { if(socket.readyState !== 1) return; __buffer.forEach(msg => socket.send(msg)); __buffer = [] }",
377
- 'socket.addEventListener("open", () => unoSendBuffer())',
378
- "hot.unoSend = (data) => {__buffer.push(data);unoSendBuffer()}",
379
- "return hot"
380
- ].join(";"));
381
- }
382
370
  if (entries.has(getPath(id)) && code.includes("import.meta.hot")) {
383
371
  const snippet = `
384
- if (import.meta.hot) { try { import.meta.hot.unoSend('${WS_EVENT_PREFIX}${lastServed}') } catch (e) { console.warn('[unocss-hmr]', e) } }`;
372
+ if (import.meta.hot) { try { import.meta.hot.send('${WS_EVENT_PREFIX}', ${lastServed}) } catch (e) { console.warn('[unocss-hmr]', e) } }`;
385
373
  return code + snippet;
386
374
  }
387
375
  }
@@ -690,6 +678,133 @@ function initTransformerPlugins(ctx) {
690
678
  ];
691
679
  }
692
680
 
681
+ const _dirname = typeof __dirname !== "undefined" ? __dirname : path.dirname(url.fileURLToPath((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href))));
682
+ const DEVTOOLS_MODULE_ID = "virtual:unocss-devtools";
683
+ const MOCK_CLASSES_MODULE_ID = "virtual:unocss-mock-classes";
684
+ const MOCK_CLASSES_PATH = "/@unocss/mock-classes";
685
+ const DEVTOOLS_PATH = "/@unocss/devtools";
686
+ const DEVTOOLS_CSS_PATH = "/@unocss/devtools.css";
687
+ const devtoolCss = /* @__PURE__ */ new Set();
688
+ const MODULES_MAP = {
689
+ [DEVTOOLS_MODULE_ID]: DEVTOOLS_PATH,
690
+ [MOCK_CLASSES_MODULE_ID]: MOCK_CLASSES_PATH
691
+ };
692
+ const POST_PATH = "/@unocss-devtools-update";
693
+ function getBodyJson(req) {
694
+ return new Promise((resolve2, reject) => {
695
+ let body = "";
696
+ req.on("data", (chunk) => body += chunk);
697
+ req.on("error", reject);
698
+ req.on("end", () => {
699
+ try {
700
+ resolve2(JSON.parse(body) || {});
701
+ } catch (e) {
702
+ reject(e);
703
+ }
704
+ });
705
+ });
706
+ }
707
+ function createDevtoolsPlugin(ctx) {
708
+ let config;
709
+ let server;
710
+ let clientCode = "";
711
+ let devtoolTimer;
712
+ let lastUpdate = Date.now();
713
+ function toClass(name) {
714
+ return `${core.toEscapedSelector(name)}{}`;
715
+ }
716
+ function updateDevtoolClass() {
717
+ clearTimeout(devtoolTimer);
718
+ devtoolTimer = setTimeout(() => {
719
+ lastUpdate = Date.now();
720
+ if (!server)
721
+ return;
722
+ const mod = server.moduleGraph.getModuleById(DEVTOOLS_CSS_PATH);
723
+ if (!mod)
724
+ return;
725
+ server.moduleGraph.invalidateModule(mod);
726
+ server.ws.send({
727
+ type: "update",
728
+ updates: [{
729
+ acceptedPath: DEVTOOLS_CSS_PATH,
730
+ path: DEVTOOLS_CSS_PATH,
731
+ timestamp: lastUpdate,
732
+ type: "js-update"
733
+ }]
734
+ });
735
+ }, 100);
736
+ }
737
+ async function getMockClassesInjector() {
738
+ const suggest = Object.keys(ctx.uno.config.rulesStaticMap);
739
+ const comment = "/* unocss CSS mock class names for devtools auto-completion */\n";
740
+ const css = suggest.map(toClass).join("");
741
+ return `
742
+ const style = document.createElement('style')
743
+ style.setAttribute('type', 'text/css')
744
+ style.innerHTML = ${JSON.stringify(comment + css)}
745
+ document.head.prepend(style)
746
+ `;
747
+ }
748
+ return [
749
+ {
750
+ name: "unocss:devtools",
751
+ configResolved(_config) {
752
+ config = _config;
753
+ },
754
+ configureServer(_server) {
755
+ server = _server;
756
+ server.middlewares.use(async (req, res, next) => {
757
+ if (req.url !== POST_PATH)
758
+ return next();
759
+ try {
760
+ const data = await getBodyJson(req);
761
+ const type = data?.type;
762
+ let changed = false;
763
+ switch (type) {
764
+ case "add-classes":
765
+ data.data.forEach((key) => {
766
+ if (!devtoolCss.has(key)) {
767
+ devtoolCss.add(key);
768
+ changed = true;
769
+ }
770
+ });
771
+ if (changed)
772
+ updateDevtoolClass();
773
+ }
774
+ res.statusCode = 200;
775
+ } catch (e) {
776
+ console.error(e);
777
+ res.statusCode = 500;
778
+ }
779
+ res.end();
780
+ });
781
+ },
782
+ resolveId(id) {
783
+ if (id === DEVTOOLS_CSS_PATH)
784
+ return DEVTOOLS_CSS_PATH;
785
+ return MODULES_MAP[id];
786
+ },
787
+ async load(id) {
788
+ if (id === DEVTOOLS_PATH) {
789
+ if (!clientCode) {
790
+ clientCode = [
791
+ await fs__default.promises.readFile(path.resolve(_dirname, "client.mjs"), "utf-8"),
792
+ `import('${MOCK_CLASSES_MODULE_ID}')`,
793
+ `import('${DEVTOOLS_CSS_PATH}')`
794
+ ].join("\n").replace("__POST_PATH__", (config.server?.origin ?? "") + POST_PATH);
795
+ }
796
+ return config.command === "build" ? "" : clientCode;
797
+ } else if (id === MOCK_CLASSES_PATH) {
798
+ return await getMockClassesInjector();
799
+ } else if (id === DEVTOOLS_CSS_PATH) {
800
+ const { css } = await ctx.uno.generate(devtoolCss);
801
+ return css;
802
+ }
803
+ }
804
+ }
805
+ ];
806
+ }
807
+
693
808
  function defineConfig(config) {
694
809
  return config;
695
810
  }
@@ -699,6 +814,7 @@ function UnocssPlugin(configOrPath, defaults = {}) {
699
814
  const mode = inlineConfig.mode ?? "global";
700
815
  const plugins = [
701
816
  ...initTransformerPlugins(ctx),
817
+ ...createDevtoolsPlugin(ctx),
702
818
  ConfigHMRPlugin(ctx)
703
819
  ];
704
820
  if (inlineConfig.inspector !== false)
package/dist/index.mjs CHANGED
@@ -1,9 +1,12 @@
1
1
  import UnocssInspector from '@unocss/inspector';
2
2
  import { createFilter } from '@rollup/pluginutils';
3
3
  import { createConfigLoader } from '@unocss/config';
4
- import { createGenerator, BetterMap } from '@unocss/core';
4
+ import { createGenerator, BetterMap, toEscapedSelector } from '@unocss/core';
5
5
  import { createHash } from 'crypto';
6
6
  import MagicString from 'magic-string';
7
+ import fs from 'fs';
8
+ import { resolve, dirname } from 'path';
9
+ import { fileURLToPath } from 'url';
7
10
 
8
11
  const regexCssId = /\.(css|postcss|sass|scss|less|stylus|styl)$/;
9
12
  const defaultExclude = [regexCssId];
@@ -39,7 +42,8 @@ function getHashPlaceholder(hash) {
39
42
  const INCLUDE_COMMENT = "@unocss-include";
40
43
  const CSS_PLACEHOLDER = "@unocss-placeholder";
41
44
 
42
- function createContext(configOrPath, defaults = {}, extraConfigSources = []) {
45
+ function createContext(configOrPath, defaults = {}, extraConfigSources = [], resolveConfigResult = () => {
46
+ }) {
43
47
  const loadConfig = createConfigLoader(configOrPath, extraConfigSources);
44
48
  let rawConfig = {};
45
49
  const uno = createGenerator(rawConfig, defaults);
@@ -50,6 +54,7 @@ function createContext(configOrPath, defaults = {}, extraConfigSources = []) {
50
54
  const ready = reloadConfig();
51
55
  async function reloadConfig() {
52
56
  const result = await loadConfig();
57
+ resolveConfigResult(result);
53
58
  rawConfig = result.config;
54
59
  uno.setConfig(rawConfig);
55
60
  uno.config.envMode = "dev";
@@ -237,7 +242,7 @@ function GlobalModeBuildPlugin({ uno, ready, extract, tokens, modules, filter })
237
242
  }
238
243
 
239
244
  const WARN_TIMEOUT = 2e4;
240
- const WS_EVENT_PREFIX = "custom:unocss:";
245
+ const WS_EVENT_PREFIX = "unocss:hmr";
241
246
  function GlobalModeDevPlugin({ uno, tokens, onInvalidate, extract, filter }) {
242
247
  const servers = [];
243
248
  let base = "";
@@ -306,18 +311,9 @@ function GlobalModeDevPlugin({ uno, tokens, onInvalidate, extract, filter }) {
306
311
  configResolved,
307
312
  async configureServer(_server) {
308
313
  servers.push(_server);
309
- _server.ws.on("connection", (ws) => {
310
- ws.on("open", () => {
311
- invalidate();
312
- });
313
- ws.on("message", (msg) => {
314
- const message = String(msg);
315
- if (!message.startsWith(WS_EVENT_PREFIX))
316
- return;
317
- const servedTime = +message.slice(WS_EVENT_PREFIX.length);
318
- if (servedTime < lastUpdate)
319
- invalidate(0);
320
- });
314
+ _server.ws.on(WS_EVENT_PREFIX, (servedTime) => {
315
+ if (servedTime < lastUpdate)
316
+ invalidate(0);
321
317
  });
322
318
  },
323
319
  async buildStart() {
@@ -361,18 +357,9 @@ function GlobalModeDevPlugin({ uno, tokens, onInvalidate, extract, filter }) {
361
357
  },
362
358
  enforce: "post",
363
359
  transform(code, id) {
364
- if (id.includes("@vite/client") || id.includes("vite/dist/client/client.mjs")) {
365
- return code.replace("return hot", [
366
- "let __buffer = []",
367
- "function unoSendBuffer() { if(socket.readyState !== 1) return; __buffer.forEach(msg => socket.send(msg)); __buffer = [] }",
368
- 'socket.addEventListener("open", () => unoSendBuffer())',
369
- "hot.unoSend = (data) => {__buffer.push(data);unoSendBuffer()}",
370
- "return hot"
371
- ].join(";"));
372
- }
373
360
  if (entries.has(getPath(id)) && code.includes("import.meta.hot")) {
374
361
  const snippet = `
375
- if (import.meta.hot) { try { import.meta.hot.unoSend('${WS_EVENT_PREFIX}${lastServed}') } catch (e) { console.warn('[unocss-hmr]', e) } }`;
362
+ if (import.meta.hot) { try { import.meta.hot.send('${WS_EVENT_PREFIX}', ${lastServed}) } catch (e) { console.warn('[unocss-hmr]', e) } }`;
376
363
  return code + snippet;
377
364
  }
378
365
  }
@@ -681,6 +668,133 @@ function initTransformerPlugins(ctx) {
681
668
  ];
682
669
  }
683
670
 
671
+ const _dirname = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
672
+ const DEVTOOLS_MODULE_ID = "virtual:unocss-devtools";
673
+ const MOCK_CLASSES_MODULE_ID = "virtual:unocss-mock-classes";
674
+ const MOCK_CLASSES_PATH = "/@unocss/mock-classes";
675
+ const DEVTOOLS_PATH = "/@unocss/devtools";
676
+ const DEVTOOLS_CSS_PATH = "/@unocss/devtools.css";
677
+ const devtoolCss = /* @__PURE__ */ new Set();
678
+ const MODULES_MAP = {
679
+ [DEVTOOLS_MODULE_ID]: DEVTOOLS_PATH,
680
+ [MOCK_CLASSES_MODULE_ID]: MOCK_CLASSES_PATH
681
+ };
682
+ const POST_PATH = "/@unocss-devtools-update";
683
+ function getBodyJson(req) {
684
+ return new Promise((resolve2, reject) => {
685
+ let body = "";
686
+ req.on("data", (chunk) => body += chunk);
687
+ req.on("error", reject);
688
+ req.on("end", () => {
689
+ try {
690
+ resolve2(JSON.parse(body) || {});
691
+ } catch (e) {
692
+ reject(e);
693
+ }
694
+ });
695
+ });
696
+ }
697
+ function createDevtoolsPlugin(ctx) {
698
+ let config;
699
+ let server;
700
+ let clientCode = "";
701
+ let devtoolTimer;
702
+ let lastUpdate = Date.now();
703
+ function toClass(name) {
704
+ return `${toEscapedSelector(name)}{}`;
705
+ }
706
+ function updateDevtoolClass() {
707
+ clearTimeout(devtoolTimer);
708
+ devtoolTimer = setTimeout(() => {
709
+ lastUpdate = Date.now();
710
+ if (!server)
711
+ return;
712
+ const mod = server.moduleGraph.getModuleById(DEVTOOLS_CSS_PATH);
713
+ if (!mod)
714
+ return;
715
+ server.moduleGraph.invalidateModule(mod);
716
+ server.ws.send({
717
+ type: "update",
718
+ updates: [{
719
+ acceptedPath: DEVTOOLS_CSS_PATH,
720
+ path: DEVTOOLS_CSS_PATH,
721
+ timestamp: lastUpdate,
722
+ type: "js-update"
723
+ }]
724
+ });
725
+ }, 100);
726
+ }
727
+ async function getMockClassesInjector() {
728
+ const suggest = Object.keys(ctx.uno.config.rulesStaticMap);
729
+ const comment = "/* unocss CSS mock class names for devtools auto-completion */\n";
730
+ const css = suggest.map(toClass).join("");
731
+ return `
732
+ const style = document.createElement('style')
733
+ style.setAttribute('type', 'text/css')
734
+ style.innerHTML = ${JSON.stringify(comment + css)}
735
+ document.head.prepend(style)
736
+ `;
737
+ }
738
+ return [
739
+ {
740
+ name: "unocss:devtools",
741
+ configResolved(_config) {
742
+ config = _config;
743
+ },
744
+ configureServer(_server) {
745
+ server = _server;
746
+ server.middlewares.use(async (req, res, next) => {
747
+ if (req.url !== POST_PATH)
748
+ return next();
749
+ try {
750
+ const data = await getBodyJson(req);
751
+ const type = data?.type;
752
+ let changed = false;
753
+ switch (type) {
754
+ case "add-classes":
755
+ data.data.forEach((key) => {
756
+ if (!devtoolCss.has(key)) {
757
+ devtoolCss.add(key);
758
+ changed = true;
759
+ }
760
+ });
761
+ if (changed)
762
+ updateDevtoolClass();
763
+ }
764
+ res.statusCode = 200;
765
+ } catch (e) {
766
+ console.error(e);
767
+ res.statusCode = 500;
768
+ }
769
+ res.end();
770
+ });
771
+ },
772
+ resolveId(id) {
773
+ if (id === DEVTOOLS_CSS_PATH)
774
+ return DEVTOOLS_CSS_PATH;
775
+ return MODULES_MAP[id];
776
+ },
777
+ async load(id) {
778
+ if (id === DEVTOOLS_PATH) {
779
+ if (!clientCode) {
780
+ clientCode = [
781
+ await fs.promises.readFile(resolve(_dirname, "client.mjs"), "utf-8"),
782
+ `import('${MOCK_CLASSES_MODULE_ID}')`,
783
+ `import('${DEVTOOLS_CSS_PATH}')`
784
+ ].join("\n").replace("__POST_PATH__", (config.server?.origin ?? "") + POST_PATH);
785
+ }
786
+ return config.command === "build" ? "" : clientCode;
787
+ } else if (id === MOCK_CLASSES_PATH) {
788
+ return await getMockClassesInjector();
789
+ } else if (id === DEVTOOLS_CSS_PATH) {
790
+ const { css } = await ctx.uno.generate(devtoolCss);
791
+ return css;
792
+ }
793
+ }
794
+ }
795
+ ];
796
+ }
797
+
684
798
  function defineConfig(config) {
685
799
  return config;
686
800
  }
@@ -690,6 +804,7 @@ function UnocssPlugin(configOrPath, defaults = {}) {
690
804
  const mode = inlineConfig.mode ?? "global";
691
805
  const plugins = [
692
806
  ...initTransformerPlugins(ctx),
807
+ ...createDevtoolsPlugin(ctx),
693
808
  ConfigHMRPlugin(ctx)
694
809
  ];
695
810
  if (inlineConfig.inspector !== false)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/vite",
3
- "version": "0.30.12",
3
+ "version": "0.31.2",
4
4
  "description": "The Vite plugin for UnoCSS",
5
5
  "keywords": [
6
6
  "unocss",
@@ -27,19 +27,27 @@
27
27
  "require": "./dist/index.cjs",
28
28
  "import": "./dist/index.mjs",
29
29
  "types": "./dist/index.d.ts"
30
+ },
31
+ "./client": {
32
+ "import": "./dist/client.mjs",
33
+ "require": "./dist/client.js",
34
+ "types": "./dist/client.d.ts"
30
35
  }
31
36
  },
32
37
  "files": [
33
38
  "dist"
34
39
  ],
35
40
  "sideEffects": false,
41
+ "peerDependencies": {
42
+ "vite": "^2.9.0"
43
+ },
36
44
  "dependencies": {
37
45
  "@rollup/pluginutils": "^4.2.0",
38
- "@unocss/config": "0.30.12",
39
- "@unocss/core": "0.30.12",
40
- "@unocss/inspector": "0.30.12",
41
- "@unocss/scope": "0.30.12",
42
- "@unocss/transformer-directives": "0.30.12",
46
+ "@unocss/config": "0.31.2",
47
+ "@unocss/core": "0.31.2",
48
+ "@unocss/inspector": "0.31.2",
49
+ "@unocss/scope": "0.31.2",
50
+ "@unocss/transformer-directives": "0.31.2",
43
51
  "magic-string": "^0.26.1"
44
52
  },
45
53
  "devDependencies": {
@@ -49,5 +57,5 @@
49
57
  "build": "unbuild",
50
58
  "stub": "unbuild --stub"
51
59
  },
52
- "readme": "# @unocss/vite\n\nThe Vite plugin for UnoCSS. Ships with the `unocss` package.\n\n> This plugin does not come with any default presets. You are building a meta framework on top of UnoCSS, see [this file](https://github.com/unocss/unocss/blob/main/packages/unocss/src/vite.ts) for an example to bind the default presets.\n\n## Installation\n\n```bash\nnpm i -D unocss\n```\n\n```ts\n// vite.config.ts\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({ /* options */ }),\n ],\n}\n```\n\nAdd `uno.css` to your main entry:\n\n```ts\n// main.ts\nimport 'uno.css'\n```\n\n## Modes\n\nThe Vite plugin comes with a set of modes that enable different behaviors.\n\n### global (default)\n\nThis is the default mode for the plugin: in this mode you need to add the import of `uno.css` on your entry point.\n\nThis mode enables a set of Vite plugins for `build` and for `dev` with `HMR` support.\n\nThe generated `css` will be a global stylesheet injected on the `index.html`.\n\n### vue-scoped (WIP)\n\nThis mode will inject generated CSS to Vue SFC's `<style scoped>` for isolation.\n\n### svelte-scoped (WIP)\n\nThis mode will inject generated CSS to Svelte's `<style>` for isolation.\n\n### per-module (WIP)\n\nThis mode will generate a CSS sheet for each module, can be scoped.\n\n### dist-chunk (WIP)\n\nThis mode will generate a CSS sheet for each code chunk on build, great for MPA.\n\n### shadow-dom\n\nSince `Web Components` uses `Shadow DOM`, there is no way to style content directly from a global stylesheet (unless you use `custom css vars`, those will penetrate the `Shadow DOM`), you need to inline the generated css by the plugin into the `Shadow DOM` style.\n\nTo inline the generated css, you only need to configure the plugin mode to `shadow-dom` and include `@unocss-placeholder` magic placeholder on each web component style css block.\n\n## Frameworks\n\nSome UI/App frameworks have some caveats that must be fixed to make it work, if you're using one of the following frameworks, just apply the suggestions.\n\n### React\n\n**WARNING**: You should import the `uno.css` virtual module using `import 'virtual:uno.css'` instead `import 'uno.css'`. When you start the dev server first time, you'll need to update some style module to get it working (we're trying to fix it).\n\nIf you're using `@vitejs/plugin-react`:\n\n```ts\n// vite.config.js\nimport react from '@vitejs/plugin-react'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n react(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nor if you're using `@vitejs/plugin-react-refresh`:\n\n```ts\n// vite.config.js\nimport reactRefresh from '@vitejs/plugin-react-refresh'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n reactRefresh(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nIf you're using `@unocss/preset-attributify` you should remove `tsc` from the `build` script.\n\nIf you are using `@vitejs/plugin-react` with `@unocss/preset-attributify`, you must add the plugin before `@vitejs/plugin-react`.\n\n```ts\n// vite.config.js\nimport react from '@vitejs/plugin-react'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({\n /* options */\n }),\n react(),\n ],\n}\n```\n\nYou have a `React` example project on [examples/vite-react](https://github.com/unocss/unocss/tree/main/examples/vite-react) directory using both plugins, check the scripts on `package.json` and its Vite configuration file.\n\n### Preact\n\nIf you're using `@preact/preset-vite`:\n\n```ts\n// vite.config.js\nimport preact from '@preact/preset-vite'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n preact(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nor if you're using `@prefresh/vite`:\n\n```ts\n// vite.config.js\nimport prefresh from '@prefresh/vite'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n prefresh(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nIf you're using `@unocss/preset-attributify` you should remove `tsc` from the `build` script.\n\nIf you are using `@preact/preset-vite` with `@unocss/preset-attributify`, you must add the plugin before `@preact/preset-vite`.\n\n```ts\n// vite.config.js\nimport preact from '@preact/preset-vite'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({\n /* options */\n }),\n preact(),\n ],\n}\n```\n\nYou have a `Preact` example project on [examples/vite-preact](https://github.com/unocss/unocss/tree/main/examples/vite-preact) directory using both plugins, check the scripts on `package.json` and its Vite configuration file.\n\n### Svelte\n\nYou must add the plugin before `@sveltejs/vite-plugin-svelte`.\n\nTo support `class:foo` and `class:foo={bar}` add the plugin and configure `extractorSvelte` on `extractors` option.\n\nYou can use simple rules with `class:`, for example `class:bg-red-500={foo}` or using `shorcuts` to include multiples rules, see `src/App.svelte` on linked example project bellow.\n\n```ts\n// vite.config.js\nimport { svelte } from '@sveltejs/vite-plugin-svelte'\nimport Unocss from 'unocss/vite'\nimport { extractorSvelte } from '@unocss/core'\n\nexport default {\n plugins: [\n Unocss({\n extractors: [extractorSvelte],\n /* more options */\n }),\n svelte(),\n ],\n}\n```\n\nYou have a `Vite + Svelte` example project on [examples/vite-svelte](https://github.com/unocss/unocss/tree/main/examples/vite-svelte) directory.\n\n### Sveltekit\n\nTo support `class:foo` and `class:foo={bar}` add the plugin and configure `extractorSvelte` on `extractors` option.\n\nYou can use simple rules with `class:`, for example `class:bg-red-500={foo}` or using `shorcuts` to include multiples rules, see `src/routes/__layout.svelte` on linked example project bellow.\n\n```ts\n// svelte.config.js\nimport preprocess from 'svelte-preprocess'\nimport UnoCss from 'unocss/vite'\nimport { extractorSvelte } from '@unocss/core'\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n // Consult https://github.com/sveltejs/svelte-preprocess\n // for more information about preprocessors\n preprocess: preprocess(),\n kit: {\n vite: {\n plugins: [\n UnoCss({\n extractors: [extractorSvelte],\n /* more options */\n }),\n ],\n },\n },\n}\n```\n\nYou have a `SvelteKit` example project on [examples/sveltekit](https://github.com/unocss/unocss/tree/main/examples/sveltekit) directory.\n\n### Web Components\n\nTo work with web components you need to enable `shadow-dom` mode on the plugin.\n\nDon't forget to remove the import for `uno.css` since the `shadow-dom` mode will not expose it and the application will not work.\n\n```ts\n// vite.config.js\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({\n mode: 'shadow-dom',\n /* more options */\n }),\n ],\n}\n```\n\nOn each `web component` just add `@unocss-placeholder` to its style css block:\n```ts\nconst template = document.createElement('template')\ntemplate.innerHTML = `\n<style>\n:host {...}\n@unocss-placeholder\n</style>\n<div class=\"m-1em\">\n...\n</div>\n`\n```\n\nIf you're using [Lit](https://lit.dev/):\n\n```ts\n@customElement('my-element')\nexport class MyElement extends LitElement {\n static styles = css`\n :host {...}\n @unocss-placeholder\n `\n ...\n}\n```\n\nYou have a `Web Components` example project on [examples/vite-lit](https://github.com/unocss/unocss/tree/main/examples/vite-lit) directory.\n\n#### `::part` built-in support\n\nYou can use `::part` since the plugin supports it via `shortcuts` and using `part-[<part-name>]:<rule|shortcut>` rule from `preset-mini`, for example using it with simple rules like `part-[<part-name>]:bg-green-500` or using some `shortcut`: check `src/my-element.ts` on linked example project bellow.\n\nThe `part-[<part-name>]:<rule|shortcut>` will work only with this plugin using the `shadow-dom` mode.\n\nThe plugin uses `nth-of-type` to avoid collisions with multiple parts in the same web component and for the same parts on distinct web components, you don't need to worry about it, the plugin will take care for you.\n\n```ts\n// vite.config.js\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({\n mode: 'shadow-dom',\n shortcuts: [\n { 'cool-blue': 'bg-blue-500 text-white' },\n { 'cool-green': 'bg-green-500 text-black' },\n ],\n /* more options */\n }),\n ],\n}\n```\n\nthen in your web components:\n\n```ts\n// my-container-wc.ts\nconst template = document.createElement('template')\ntemplate.innerHTML = `\n<style>\n@unocss-placeholder\n</style>\n<my-wc-with-parts class=\"part-[cool-part]:cool-blue part-[another-cool-part]:cool-green\">...</my-wc-with-parts>\n`\n```\n\n```ts\n// my-wc-with-parts.ts\nconst template = document.createElement('template')\ntemplate.innerHTML = `\n<style>\n@unocss-placeholder\n</style>\n<div>\n <div part=\"cool-part\">...</div>\n <div part=\"another-cool-part\">...</div>\n</div>\n`\n```\n\n### Solid\n\n**WARNING**: You should import the `uno.css` virtual module using `import 'virtual:uno.css'` instead `import 'uno.css'`. When you start the dev server first time, you'll need to update some style module to get it working (we're trying to fix it).\n\n```ts\n// vite.config.js\nimport solidPlugin from 'vite-plugin-solid'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n solidPlugin(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nYou have a `Vite + Solid` example project on [examples/vite-solid](https://github.com/unocss/unocss/tree/main/examples/vite-solid) directory.\n\n### Elm\n\nYou need to add the `vite-plugin-elm` plugin before UnoCSS's plugin.\n\n```ts\n// vite.config.js\nimport { defineConfig } from 'vite'\nimport elmPlugin from 'vite-plugin-elm'\nimport Unocss from 'unocss/vite'\n\nexport default defineConfig({\n plugins: [\n elmPlugin(),\n Unocss({\n /* options */\n }),\n ],\n})\n```\n\nYou have a `Vite + Elm` example project on [examples/vite-elm](https://github.com/unocss/unocss/tree/main/examples/vite-elm) directory.\n\n## License\n\nMIT License © 2021-PRESENT [Anthony Fu](https://github.com/antfu)\n"
60
+ "readme": "# @unocss/vite\n\nThe Vite plugin for UnoCSS. Ships with the `unocss` package.\n\n> This plugin does not come with any default presets. You are building a meta framework on top of UnoCSS, see [this file](https://github.com/unocss/unocss/blob/main/packages/unocss/src/vite.ts) for an example to bind the default presets.\n\n## Installation\n\n```bash\nnpm i -D unocss\n```\n\n```ts\n// vite.config.ts\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({ /* options */ }),\n ],\n}\n```\n\nAdd `uno.css` to your main entry:\n\n```ts\n// main.ts\nimport 'uno.css'\n```\n\n## Modes\n\nThe Vite plugin comes with a set of modes that enable different behaviors.\n\n### global (default)\n\nThis is the default mode for the plugin: in this mode you need to add the import of `uno.css` on your entry point.\n\nThis mode enables a set of Vite plugins for `build` and for `dev` with `HMR` support.\n\nThe generated `css` will be a global stylesheet injected on the `index.html`.\n\n### vue-scoped\n\nThis mode will inject generated CSS to Vue SFC's `<style scoped>` for isolation.\n\n### svelte-scoped\n\nThis mode will inject generated CSS to Svelte's `<style>` for isolation.\n\n### shadow-dom\n\nSince `Web Components` uses `Shadow DOM`, there is no way to style content directly from a global stylesheet (unless you use `custom css vars`, those will penetrate the `Shadow DOM`), you need to inline the generated css by the plugin into the `Shadow DOM` style.\n\nTo inline the generated css, you only need to configure the plugin mode to `shadow-dom` and include `@unocss-placeholder` magic placeholder on each web component style css block.\n\n### per-module (Experimental)\n\nThis mode will generate a CSS sheet for each module, can be scoped.\n\n### dist-chunk (Experimental)\n\nThis mode will generate a CSS sheet for each code chunk on build, great for MPA.\n\n## \"Design in DevTools\"\n\nBecause of limitation of \"on-demand\" where the DevTools don't know those you haven't used in your source code yet. So if you want to try how things work by directly changing the classes in DevTools, just add the following lines to your main entry.\n\n```ts\nimport 'uno.css'\nimport 'virtual:unocss-devtools'\n```\n\n> ⚠️ Please use it with caution, under the hood we use [`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) to detect the class changes. Which means not only your manual changes but also the changes made by your scripts will be detected and included in the stylesheet. This could cause some misalignment between dev and the production build when you add dynamic classes based on some logic in script tags. We recommended adding your dynamic parts to the [safelist](https://github.com/unocss/unocss/issues/511) or setup UI regression tests for your production build if possible.\n\n`virtual:unocss-devtools` will be an empty bundle in production.\n\n## Frameworks\n\nSome UI/App frameworks have some caveats that must be fixed to make it work, if you're using one of the following frameworks, just apply the suggestions.\n\n### React\n\n**WARNING**: You should import the `uno.css` virtual module using `import 'virtual:uno.css'` instead `import 'uno.css'`. When you start the dev server first time, you'll need to update some style module to get it working (we're trying to fix it).\n\nIf you're using `@vitejs/plugin-react`:\n\n```ts\n// vite.config.js\nimport react from '@vitejs/plugin-react'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n react(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nor if you're using `@vitejs/plugin-react-refresh`:\n\n```ts\n// vite.config.js\nimport reactRefresh from '@vitejs/plugin-react-refresh'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n reactRefresh(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nIf you're using `@unocss/preset-attributify` you should remove `tsc` from the `build` script.\n\nIf you are using `@vitejs/plugin-react` with `@unocss/preset-attributify`, you must add the plugin before `@vitejs/plugin-react`.\n\n```ts\n// vite.config.js\nimport react from '@vitejs/plugin-react'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({\n /* options */\n }),\n react(),\n ],\n}\n```\n\nYou have a `React` example project on [examples/vite-react](https://github.com/unocss/unocss/tree/main/examples/vite-react) directory using both plugins, check the scripts on `package.json` and its Vite configuration file.\n\n### Preact\n\nIf you're using `@preact/preset-vite`:\n\n```ts\n// vite.config.js\nimport preact from '@preact/preset-vite'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n preact(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nor if you're using `@prefresh/vite`:\n\n```ts\n// vite.config.js\nimport prefresh from '@prefresh/vite'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n prefresh(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nIf you're using `@unocss/preset-attributify` you should remove `tsc` from the `build` script.\n\nIf you are using `@preact/preset-vite` with `@unocss/preset-attributify`, you must add the plugin before `@preact/preset-vite`.\n\n```ts\n// vite.config.js\nimport preact from '@preact/preset-vite'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({\n /* options */\n }),\n preact(),\n ],\n}\n```\n\nYou have a `Preact` example project on [examples/vite-preact](https://github.com/unocss/unocss/tree/main/examples/vite-preact) directory using both plugins, check the scripts on `package.json` and its Vite configuration file.\n\n### Svelte\n\nYou must add the plugin before `@sveltejs/vite-plugin-svelte`.\n\nTo support `class:foo` and `class:foo={bar}` add the plugin and configure `extractorSvelte` on `extractors` option.\n\nYou can use simple rules with `class:`, for example `class:bg-red-500={foo}` or using `shorcuts` to include multiples rules, see `src/App.svelte` on linked example project bellow.\n\n```ts\n// vite.config.js\nimport { svelte } from '@sveltejs/vite-plugin-svelte'\nimport Unocss from 'unocss/vite'\nimport { extractorSvelte } from '@unocss/core'\n\nexport default {\n plugins: [\n Unocss({\n extractors: [extractorSvelte],\n /* more options */\n }),\n svelte(),\n ],\n}\n```\n\nYou have a `Vite + Svelte` example project on [examples/vite-svelte](https://github.com/unocss/unocss/tree/main/examples/vite-svelte) directory.\n\n### Sveltekit\n\nTo support `class:foo` and `class:foo={bar}` add the plugin and configure `extractorSvelte` on `extractors` option.\n\nYou can use simple rules with `class:`, for example `class:bg-red-500={foo}` or using `shorcuts` to include multiples rules, see `src/routes/__layout.svelte` on linked example project bellow.\n\n```ts\n// svelte.config.js\nimport preprocess from 'svelte-preprocess'\nimport UnoCss from 'unocss/vite'\nimport { extractorSvelte } from '@unocss/core'\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n // Consult https://github.com/sveltejs/svelte-preprocess\n // for more information about preprocessors\n preprocess: preprocess(),\n kit: {\n vite: {\n plugins: [\n UnoCss({\n extractors: [extractorSvelte],\n /* more options */\n }),\n ],\n },\n },\n}\n```\n\nYou have a `SvelteKit` example project on [examples/sveltekit](https://github.com/unocss/unocss/tree/main/examples/sveltekit) directory.\n\n### Web Components\n\nTo work with web components you need to enable `shadow-dom` mode on the plugin.\n\nDon't forget to remove the import for `uno.css` since the `shadow-dom` mode will not expose it and the application will not work.\n\n```ts\n// vite.config.js\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({\n mode: 'shadow-dom',\n /* more options */\n }),\n ],\n}\n```\n\nOn each `web component` just add `@unocss-placeholder` to its style css block:\n```ts\nconst template = document.createElement('template')\ntemplate.innerHTML = `\n<style>\n:host {...}\n@unocss-placeholder\n</style>\n<div class=\"m-1em\">\n...\n</div>\n`\n```\n\nIf you're using [Lit](https://lit.dev/):\n\n```ts\n@customElement('my-element')\nexport class MyElement extends LitElement {\n static styles = css`\n :host {...}\n @unocss-placeholder\n `\n // ...\n}\n```\n\nYou have a `Web Components` example project on [examples/vite-lit](https://github.com/unocss/unocss/tree/main/examples/vite-lit) directory.\n\n#### `::part` built-in support\n\nYou can use `::part` since the plugin supports it via `shortcuts` and using `part-[<part-name>]:<rule|shortcut>` rule from `preset-mini`, for example using it with simple rules like `part-[<part-name>]:bg-green-500` or using some `shortcut`: check `src/my-element.ts` on linked example project bellow.\n\nThe `part-[<part-name>]:<rule|shortcut>` will work only with this plugin using the `shadow-dom` mode.\n\nThe plugin uses `nth-of-type` to avoid collisions with multiple parts in the same web component and for the same parts on distinct web components, you don't need to worry about it, the plugin will take care for you.\n\n```ts\n// vite.config.js\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n Unocss({\n mode: 'shadow-dom',\n shortcuts: [\n { 'cool-blue': 'bg-blue-500 text-white' },\n { 'cool-green': 'bg-green-500 text-black' },\n ],\n /* more options */\n }),\n ],\n}\n```\n\nthen in your web components:\n\n```ts\n// my-container-wc.ts\nconst template = document.createElement('template')\ntemplate.innerHTML = `\n<style>\n@unocss-placeholder\n</style>\n<my-wc-with-parts class=\"part-[cool-part]:cool-blue part-[another-cool-part]:cool-green\">...</my-wc-with-parts>\n`\n```\n\n```ts\n// my-wc-with-parts.ts\nconst template = document.createElement('template')\ntemplate.innerHTML = `\n<style>\n@unocss-placeholder\n</style>\n<div>\n <div part=\"cool-part\">...</div>\n <div part=\"another-cool-part\">...</div>\n</div>\n`\n```\n\n### Solid\n\n**WARNING**: You should import the `uno.css` virtual module using `import 'virtual:uno.css'` instead `import 'uno.css'`. When you start the dev server first time, you'll need to update some style module to get it working (we're trying to fix it).\n\n```ts\n// vite.config.js\nimport solidPlugin from 'vite-plugin-solid'\nimport Unocss from 'unocss/vite'\n\nexport default {\n plugins: [\n solidPlugin(),\n Unocss({\n /* options */\n }),\n ],\n}\n```\n\nYou have a `Vite + Solid` example project on [examples/vite-solid](https://github.com/unocss/unocss/tree/main/examples/vite-solid) directory.\n\n### Elm\n\nYou need to add the `vite-plugin-elm` plugin before UnoCSS's plugin.\n\n```ts\n// vite.config.js\nimport { defineConfig } from 'vite'\nimport elmPlugin from 'vite-plugin-elm'\nimport Unocss from 'unocss/vite'\n\nexport default defineConfig({\n plugins: [\n elmPlugin(),\n Unocss({\n /* options */\n }),\n ],\n})\n```\n\nYou have a `Vite + Elm` example project on [examples/vite-elm](https://github.com/unocss/unocss/tree/main/examples/vite-elm) directory.\n\n## License\n\nMIT License © 2021-PRESENT [Anthony Fu](https://github.com/antfu)\n"
53
61
  }