@unocss/postcss 0.58.8 → 0.59.0-beta.1

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/esm.d.mts ADDED
@@ -0,0 +1,21 @@
1
+ import { Root, Result } from 'postcss';
2
+ import { UserConfig } from '@unocss/core';
3
+
4
+ interface UnoPostcssPluginOptions {
5
+ content?: (string | {
6
+ raw: string;
7
+ extension: string;
8
+ })[];
9
+ directiveMap?: {
10
+ apply?: string;
11
+ screen?: string;
12
+ theme?: string;
13
+ unocss?: string;
14
+ };
15
+ cwd?: string;
16
+ configOrPath?: string | UserConfig;
17
+ }
18
+
19
+ declare function createPlugin(options: UnoPostcssPluginOptions): (root: Root, result: Result) => Promise<void>;
20
+
21
+ export { createPlugin };
package/dist/esm.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { Root, Result } from 'postcss';
2
+ import { UserConfig } from '@unocss/core';
3
+
4
+ interface UnoPostcssPluginOptions {
5
+ content?: (string | {
6
+ raw: string;
7
+ extension: string;
8
+ })[];
9
+ directiveMap?: {
10
+ apply?: string;
11
+ screen?: string;
12
+ theme?: string;
13
+ unocss?: string;
14
+ };
15
+ cwd?: string;
16
+ configOrPath?: string | UserConfig;
17
+ }
18
+
19
+ declare function createPlugin(options: UnoPostcssPluginOptions): (root: Root, result: Result) => Promise<void>;
20
+
21
+ export { createPlugin };
package/dist/esm.mjs ADDED
@@ -0,0 +1,270 @@
1
+ import { stat, readFile } from 'node:fs/promises';
2
+ import { normalize } from 'node:path';
3
+ import process from 'node:process';
4
+ import fg from 'fast-glob';
5
+ import postcss from 'postcss';
6
+ import { expandVariantGroup, notNull, regexScopePlaceholder, createGenerator } from '@unocss/core';
7
+ import { loadConfig } from '@unocss/config';
8
+ import { transformThemeFn, hasThemeFn } from '@unocss/rule-utils';
9
+ import { parse, generate, clone } from 'css-tree';
10
+
11
+ const defaultFilesystemGlobs = [
12
+ "**/*.{html,js,ts,jsx,tsx,vue,svelte,astro,elm,php,phtml,mdx,md}"
13
+ ];
14
+
15
+ async function parseApply(root, uno, directiveName) {
16
+ root.walkAtRules(directiveName, async (rule) => {
17
+ if (!rule.parent)
18
+ return;
19
+ const source = rule.source;
20
+ const classNames = expandVariantGroup(rule.params).split(/\s+/g).map((className) => className.trim().replace(/\\/, ""));
21
+ const utils = (await Promise.all(
22
+ classNames.map((i) => uno.parseToken(i, "-"))
23
+ )).filter(notNull).flat().sort((a, b) => a[0] - b[0]).sort((a, b) => (a[3] ? uno.parentOrders.get(a[3]) ?? 0 : 0) - (b[3] ? uno.parentOrders.get(b[3]) ?? 0 : 0)).reduce((acc, item) => {
24
+ const target = acc.find((i) => i[1] === item[1] && i[3] === item[3]);
25
+ if (target)
26
+ target[2] += item[2];
27
+ else
28
+ acc.push([...item]);
29
+ return acc;
30
+ }, []);
31
+ if (!utils.length)
32
+ return;
33
+ const parentAfterNodes = [];
34
+ for (const i of utils) {
35
+ const [, _selector, body, parent] = i;
36
+ const selector = _selector?.replace(regexScopePlaceholder, " ") || _selector;
37
+ if (parent || selector && selector !== ".\\-") {
38
+ const node = parse(rule.parent.toString(), {
39
+ context: "rule"
40
+ });
41
+ let newSelector = generate(node.prelude);
42
+ if (selector && selector !== ".\\-") {
43
+ const selectorAST = parse(selector, {
44
+ context: "selector"
45
+ });
46
+ const prelude = clone(node.prelude);
47
+ prelude.children.forEach((child) => {
48
+ const parentSelectorAst = clone(selectorAST);
49
+ parentSelectorAst.children.forEach((i2) => {
50
+ if (i2.type === "ClassSelector" && i2.name === "\\-")
51
+ Object.assign(i2, clone(child));
52
+ });
53
+ Object.assign(child, parentSelectorAst);
54
+ });
55
+ newSelector = generate(prelude);
56
+ }
57
+ let css = `${newSelector}{${body}}`;
58
+ if (parent)
59
+ css = `${parent}{${css}}`;
60
+ const css_parsed = postcss.parse(css);
61
+ css_parsed.walkDecls((declaration) => {
62
+ declaration.source = source;
63
+ });
64
+ parentAfterNodes.push(css_parsed);
65
+ } else {
66
+ const css = postcss.parse(body);
67
+ css.walkDecls((declaration) => {
68
+ declaration.source = source;
69
+ });
70
+ rule.parent.append(css);
71
+ }
72
+ }
73
+ rule.parent.after(parentAfterNodes);
74
+ rule.remove();
75
+ });
76
+ }
77
+
78
+ async function parseTheme(root, uno) {
79
+ root.walkDecls((decl) => {
80
+ decl.value = transformThemeFn(decl.value, uno.config.theme);
81
+ });
82
+ }
83
+
84
+ async function parseScreen(root, uno, directiveName) {
85
+ root.walkAtRules(directiveName, async (rule) => {
86
+ let breakpointName = "";
87
+ let prefix = "";
88
+ if (rule.params)
89
+ breakpointName = rule.params.trim();
90
+ if (!breakpointName)
91
+ return;
92
+ const match = breakpointName.match(/^(?:(lt|at)-)?(\w+)$/);
93
+ if (match) {
94
+ prefix = match[1];
95
+ breakpointName = match[2];
96
+ }
97
+ const resolveBreakpoints = () => {
98
+ let breakpoints;
99
+ if (uno.userConfig && uno.userConfig.theme)
100
+ breakpoints = uno.userConfig.theme.breakpoints;
101
+ if (!breakpoints)
102
+ breakpoints = uno.config.theme.breakpoints;
103
+ return breakpoints ? Object.entries(breakpoints).sort((a, b) => Number.parseInt(a[1].replace(/[a-z]+/gi, "")) - Number.parseInt(b[1].replace(/[a-z]+/gi, ""))).map(([point, size]) => ({ point, size })) : void 0;
104
+ };
105
+ const variantEntries = (resolveBreakpoints() ?? []).map(({ point, size }, idx) => [point, size, idx]);
106
+ const generateMediaQuery = (breakpointName2, prefix2) => {
107
+ const [, size, idx] = variantEntries.find((i) => i[0] === breakpointName2);
108
+ if (prefix2) {
109
+ if (prefix2 === "lt")
110
+ return `(max-width: ${calcMaxWidthBySize(size)})`;
111
+ else if (prefix2 === "at")
112
+ return `(min-width: ${size})${variantEntries[idx + 1] ? ` and (max-width: ${calcMaxWidthBySize(variantEntries[idx + 1][1])})` : ""}`;
113
+ else
114
+ throw new Error(`breakpoint variant not supported: ${prefix2}`);
115
+ }
116
+ return `(min-width: ${size})`;
117
+ };
118
+ if (!variantEntries.find((i) => i[0] === breakpointName))
119
+ throw new Error(`breakpoint ${breakpointName} not found`);
120
+ rule.name = "media";
121
+ rule.params = `${generateMediaQuery(breakpointName, prefix)}`;
122
+ });
123
+ }
124
+ function calcMaxWidthBySize(size) {
125
+ const value = size.match(/^-?[0-9]+\.?[0-9]*/)?.[0] || "";
126
+ const unit = size.slice(value.length);
127
+ const maxWidth = Number.parseFloat(value) - 0.1;
128
+ return Number.isNaN(maxWidth) ? size : `${maxWidth}${unit}`;
129
+ }
130
+
131
+ function createPlugin(options) {
132
+ const {
133
+ cwd = process.cwd(),
134
+ configOrPath
135
+ } = options;
136
+ const directiveMap = Object.assign({
137
+ apply: "apply",
138
+ theme: "theme",
139
+ screen: "screen",
140
+ unocss: "unocss"
141
+ }, options.directiveMap || {});
142
+ const fileMap = /* @__PURE__ */ new Map();
143
+ const fileClassMap = /* @__PURE__ */ new Map();
144
+ const classes = /* @__PURE__ */ new Set();
145
+ const targetCache = /* @__PURE__ */ new Set();
146
+ const config = loadConfig(cwd, configOrPath);
147
+ let uno;
148
+ let promises = [];
149
+ let last_config_mtime = 0;
150
+ const targetRE = new RegExp(Object.values(directiveMap).join("|"));
151
+ return async function plugin(root, result) {
152
+ const from = result.opts.from?.split("?")[0];
153
+ if (!from)
154
+ return;
155
+ let isTarget = targetCache.has(from);
156
+ const isScanTarget = root.toString().includes(`@${directiveMap.unocss}`);
157
+ if (targetRE.test(root.toString())) {
158
+ if (!isTarget) {
159
+ root.walkAtRules((rule) => {
160
+ if (rule.name === directiveMap.unocss || rule.name === directiveMap.apply || rule.name === directiveMap.screen)
161
+ isTarget = true;
162
+ if (isTarget)
163
+ return false;
164
+ });
165
+ if (!isTarget) {
166
+ root.walkDecls((decl) => {
167
+ if (hasThemeFn(decl.value)) {
168
+ isTarget = true;
169
+ return false;
170
+ }
171
+ });
172
+ } else {
173
+ targetCache.add(from);
174
+ }
175
+ }
176
+ } else if (targetCache.has(from)) {
177
+ targetCache.delete(from);
178
+ }
179
+ if (!isTarget)
180
+ return;
181
+ try {
182
+ const cfg = await config;
183
+ if (!uno) {
184
+ uno = createGenerator(cfg.config);
185
+ } else if (cfg.sources.length) {
186
+ const config_mtime = (await stat(cfg.sources[0])).mtimeMs;
187
+ if (config_mtime > last_config_mtime) {
188
+ uno = createGenerator((await loadConfig(cwd, configOrPath)).config);
189
+ last_config_mtime = config_mtime;
190
+ }
191
+ }
192
+ } catch (error) {
193
+ throw new Error(`UnoCSS config not found: ${error.message}`);
194
+ }
195
+ const globs = uno.config.content?.filesystem ?? defaultFilesystemGlobs;
196
+ const plainContent = uno.config.content?.inline ?? [];
197
+ const entries = await fg(isScanTarget ? globs : from, {
198
+ cwd,
199
+ absolute: true,
200
+ ignore: ["**/node_modules/**"],
201
+ stats: true
202
+ });
203
+ await parseApply(root, uno, directiveMap.apply);
204
+ await parseTheme(root, uno);
205
+ await parseScreen(root, uno, directiveMap.screen);
206
+ promises.push(
207
+ ...plainContent.map(async (c2, idx) => {
208
+ if (typeof c2 === "function")
209
+ c2 = await c2();
210
+ if (typeof c2 === "string")
211
+ c2 = { code: c2 };
212
+ const { matched } = await uno.generate(c2.code, { id: c2.id ?? `__plain_content_${idx}__` });
213
+ for (const candidate of matched)
214
+ classes.add(candidate);
215
+ }),
216
+ ...entries.map(async ({ path: file, mtimeMs }) => {
217
+ result.messages.push({
218
+ type: "dependency",
219
+ plugin: directiveMap.unocss,
220
+ file: normalize(file),
221
+ parent: from
222
+ });
223
+ if (fileMap.has(file) && mtimeMs <= fileMap.get(file))
224
+ return;
225
+ else
226
+ fileMap.set(file, mtimeMs);
227
+ const content = await readFile(file, "utf8");
228
+ const { matched } = await uno.generate(content, {
229
+ id: file
230
+ });
231
+ fileClassMap.set(file, matched);
232
+ })
233
+ );
234
+ await Promise.all(promises);
235
+ promises = [];
236
+ for (const set of fileClassMap.values()) {
237
+ for (const candidate of set)
238
+ classes.add(candidate);
239
+ }
240
+ const c = await uno.generate(classes);
241
+ classes.clear();
242
+ const excludes = [];
243
+ root.walkAtRules(directiveMap.unocss, (rule) => {
244
+ if (rule.params) {
245
+ const source = rule.source;
246
+ const layers = rule.params.split(",").map((v) => v.trim());
247
+ const css = postcss.parse(
248
+ layers.map((i) => (i === "all" ? c.getLayers() : c.getLayer(i)) || "").filter(Boolean).join("\n")
249
+ );
250
+ css.walkDecls((declaration) => {
251
+ declaration.source = source;
252
+ });
253
+ rule.replaceWith(css);
254
+ excludes.push(rule.params);
255
+ }
256
+ });
257
+ root.walkAtRules(directiveMap.unocss, (rule) => {
258
+ if (!rule.params) {
259
+ const source = rule.source;
260
+ const css = postcss.parse(c.getLayers(void 0, excludes) || "");
261
+ css.walkDecls((declaration) => {
262
+ declaration.source = source;
263
+ });
264
+ rule.replaceWith(css);
265
+ }
266
+ });
267
+ };
268
+ }
269
+
270
+ export { createPlugin };
package/dist/index.cjs CHANGED
@@ -1,280 +1,14 @@
1
- 'use strict';
2
-
3
- const promises = require('node:fs/promises');
4
- const node_path = require('node:path');
5
- const process = require('node:process');
6
- const fg = require('fast-glob');
7
- const postcss = require('postcss');
8
- const core = require('@unocss/core');
9
- const config = require('@unocss/config');
10
- const ruleUtils = require('@unocss/rule-utils');
11
- const cssTree = require('css-tree');
12
-
13
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
14
-
15
- const process__default = /*#__PURE__*/_interopDefaultCompat(process);
16
- const fg__default = /*#__PURE__*/_interopDefaultCompat(fg);
17
- const postcss__default = /*#__PURE__*/_interopDefaultCompat(postcss);
18
-
19
- const defaultFilesystemGlobs = [
20
- "**/*.{html,js,ts,jsx,tsx,vue,svelte,astro,elm,php,phtml,mdx,md}"
21
- ];
22
-
23
- async function parseApply(root, uno, directiveName) {
24
- root.walkAtRules(directiveName, async (rule) => {
25
- if (!rule.parent)
26
- return;
27
- const source = rule.source;
28
- const classNames = core.expandVariantGroup(rule.params).split(/\s+/g).map((className) => className.trim().replace(/\\/, ""));
29
- const utils = (await Promise.all(
30
- classNames.map((i) => uno.parseToken(i, "-"))
31
- )).filter(core.notNull).flat().sort((a, b) => a[0] - b[0]).sort((a, b) => (a[3] ? uno.parentOrders.get(a[3]) ?? 0 : 0) - (b[3] ? uno.parentOrders.get(b[3]) ?? 0 : 0)).reduce((acc, item) => {
32
- const target = acc.find((i) => i[1] === item[1] && i[3] === item[3]);
33
- if (target)
34
- target[2] += item[2];
35
- else
36
- acc.push([...item]);
37
- return acc;
38
- }, []);
39
- if (!utils.length)
40
- return;
41
- const parentAfterNodes = [];
42
- for (const i of utils) {
43
- const [, _selector, body, parent] = i;
44
- const selector = _selector?.replace(core.regexScopePlaceholder, " ") || _selector;
45
- if (parent || selector && selector !== ".\\-") {
46
- const node = cssTree.parse(rule.parent.toString(), {
47
- context: "rule"
48
- });
49
- let newSelector = cssTree.generate(node.prelude);
50
- if (selector && selector !== ".\\-") {
51
- const selectorAST = cssTree.parse(selector, {
52
- context: "selector"
53
- });
54
- const prelude = cssTree.clone(node.prelude);
55
- prelude.children.forEach((child) => {
56
- const parentSelectorAst = cssTree.clone(selectorAST);
57
- parentSelectorAst.children.forEach((i2) => {
58
- if (i2.type === "ClassSelector" && i2.name === "\\-")
59
- Object.assign(i2, cssTree.clone(child));
60
- });
61
- Object.assign(child, parentSelectorAst);
62
- });
63
- newSelector = cssTree.generate(prelude);
64
- }
65
- let css = `${newSelector}{${body}}`;
66
- if (parent)
67
- css = `${parent}{${css}}`;
68
- const css_parsed = postcss__default.parse(css);
69
- css_parsed.walkDecls((declaration) => {
70
- declaration.source = source;
71
- });
72
- parentAfterNodes.push(css_parsed);
73
- } else {
74
- const css = postcss__default.parse(body);
75
- css.walkDecls((declaration) => {
76
- declaration.source = source;
77
- });
78
- rule.parent.append(css);
79
- }
80
- }
81
- rule.parent.after(parentAfterNodes);
82
- rule.remove();
83
- });
84
- }
85
-
86
- async function parseTheme(root, uno) {
87
- root.walkDecls((decl) => {
88
- decl.value = ruleUtils.transformThemeFn(decl.value, uno.config.theme);
89
- });
90
- }
91
-
92
- async function parseScreen(root, uno, directiveName) {
93
- root.walkAtRules(directiveName, async (rule) => {
94
- let breakpointName = "";
95
- let prefix = "";
96
- if (rule.params)
97
- breakpointName = rule.params.trim();
98
- if (!breakpointName)
99
- return;
100
- const match = breakpointName.match(/^(?:(lt|at)-)?(\w+)$/);
101
- if (match) {
102
- prefix = match[1];
103
- breakpointName = match[2];
104
- }
105
- const resolveBreakpoints = () => {
106
- let breakpoints;
107
- if (uno.userConfig && uno.userConfig.theme)
108
- breakpoints = uno.userConfig.theme.breakpoints;
109
- if (!breakpoints)
110
- breakpoints = uno.config.theme.breakpoints;
111
- return breakpoints ? Object.entries(breakpoints).sort((a, b) => Number.parseInt(a[1].replace(/[a-z]+/gi, "")) - Number.parseInt(b[1].replace(/[a-z]+/gi, ""))).map(([point, size]) => ({ point, size })) : void 0;
112
- };
113
- const variantEntries = (resolveBreakpoints() ?? []).map(({ point, size }, idx) => [point, size, idx]);
114
- const generateMediaQuery = (breakpointName2, prefix2) => {
115
- const [, size, idx] = variantEntries.find((i) => i[0] === breakpointName2);
116
- if (prefix2) {
117
- if (prefix2 === "lt")
118
- return `(max-width: ${calcMaxWidthBySize(size)})`;
119
- else if (prefix2 === "at")
120
- return `(min-width: ${size})${variantEntries[idx + 1] ? ` and (max-width: ${calcMaxWidthBySize(variantEntries[idx + 1][1])})` : ""}`;
121
- else
122
- throw new Error(`breakpoint variant not supported: ${prefix2}`);
123
- }
124
- return `(min-width: ${size})`;
125
- };
126
- if (!variantEntries.find((i) => i[0] === breakpointName))
127
- throw new Error(`breakpoint ${breakpointName} not found`);
128
- rule.name = "media";
129
- rule.params = `${generateMediaQuery(breakpointName, prefix)}`;
130
- });
131
- }
132
- function calcMaxWidthBySize(size) {
133
- const value = size.match(/^-?[0-9]+\.?[0-9]*/)?.[0] || "";
134
- const unit = size.slice(value.length);
135
- const maxWidth = Number.parseFloat(value) - 0.1;
136
- return Number.isNaN(maxWidth) ? size : `${maxWidth}${unit}`;
137
- }
1
+ 'use strict';Object.defineProperty(exports, '__esModule', {value: true});
138
2
 
139
3
  function unocss(options = {}) {
140
- const {
141
- cwd = process__default.cwd(),
142
- configOrPath
143
- } = options;
144
- const directiveMap = Object.assign({
145
- apply: "apply",
146
- theme: "theme",
147
- screen: "screen",
148
- unocss: "unocss"
149
- }, options.directiveMap || {});
150
- const fileMap = /* @__PURE__ */ new Map();
151
- const fileClassMap = /* @__PURE__ */ new Map();
152
- const classes = /* @__PURE__ */ new Set();
153
- const targetCache = /* @__PURE__ */ new Set();
154
- const config$1 = config.loadConfig(cwd, configOrPath);
155
- let uno;
156
- let promises$1 = [];
157
- let last_config_mtime = 0;
158
- const targetRE = new RegExp(Object.values(directiveMap).join("|"));
4
+ let promise;
159
5
  return {
160
- postcssPlugin: directiveMap.unocss,
6
+ postcssPlugin: options.directiveMap?.unocss || "unocss",
161
7
  plugins: [
162
- async function(root, result) {
163
- const from = result.opts.from?.split("?")[0];
164
- if (!from)
165
- return;
166
- let isTarget = targetCache.has(from);
167
- const isScanTarget = root.toString().includes(`@${directiveMap.unocss}`);
168
- if (targetRE.test(root.toString())) {
169
- if (!isTarget) {
170
- root.walkAtRules((rule) => {
171
- if (rule.name === directiveMap.unocss || rule.name === directiveMap.apply || rule.name === directiveMap.screen)
172
- isTarget = true;
173
- if (isTarget)
174
- return false;
175
- });
176
- if (!isTarget) {
177
- root.walkDecls((decl) => {
178
- if (ruleUtils.hasThemeFn(decl.value)) {
179
- isTarget = true;
180
- return false;
181
- }
182
- });
183
- } else {
184
- targetCache.add(from);
185
- }
186
- }
187
- } else if (targetCache.has(from)) {
188
- targetCache.delete(from);
189
- }
190
- if (!isTarget)
191
- return;
192
- try {
193
- const cfg = await config$1;
194
- if (!uno) {
195
- uno = core.createGenerator(cfg.config);
196
- } else if (cfg.sources.length) {
197
- const config_mtime = (await promises.stat(cfg.sources[0])).mtimeMs;
198
- if (config_mtime > last_config_mtime) {
199
- uno = core.createGenerator((await config.loadConfig(cwd, configOrPath)).config);
200
- last_config_mtime = config_mtime;
201
- }
202
- }
203
- } catch (error) {
204
- throw new Error(`UnoCSS config not found: ${error.message}`);
205
- }
206
- const globs = uno.config.content?.filesystem ?? defaultFilesystemGlobs;
207
- const plainContent = uno.config.content?.inline ?? [];
208
- const entries = await fg__default(isScanTarget ? globs : from, {
209
- cwd,
210
- absolute: true,
211
- ignore: ["**/node_modules/**"],
212
- stats: true
213
- });
214
- await parseApply(root, uno, directiveMap.apply);
215
- await parseTheme(root, uno);
216
- await parseScreen(root, uno, directiveMap.screen);
217
- promises$1.push(
218
- ...plainContent.map(async (c2, idx) => {
219
- if (typeof c2 === "function")
220
- c2 = await c2();
221
- if (typeof c2 === "string")
222
- c2 = { code: c2 };
223
- const { matched } = await uno.generate(c2.code, { id: c2.id ?? `__plain_content_${idx}__` });
224
- for (const candidate of matched)
225
- classes.add(candidate);
226
- }),
227
- ...entries.map(async ({ path: file, mtimeMs }) => {
228
- result.messages.push({
229
- type: "dependency",
230
- plugin: directiveMap.unocss,
231
- file: node_path.normalize(file),
232
- parent: from
233
- });
234
- if (fileMap.has(file) && mtimeMs <= fileMap.get(file))
235
- return;
236
- else
237
- fileMap.set(file, mtimeMs);
238
- const content = await promises.readFile(file, "utf8");
239
- const { matched } = await uno.generate(content, {
240
- id: file
241
- });
242
- fileClassMap.set(file, matched);
243
- })
244
- );
245
- await Promise.all(promises$1);
246
- promises$1 = [];
247
- for (const set of fileClassMap.values()) {
248
- for (const candidate of set)
249
- classes.add(candidate);
250
- }
251
- const c = await uno.generate(classes);
252
- classes.clear();
253
- const excludes = [];
254
- root.walkAtRules(directiveMap.unocss, (rule) => {
255
- if (rule.params) {
256
- const source = rule.source;
257
- const layers = rule.params.split(",").map((v) => v.trim());
258
- const css = postcss__default.parse(
259
- layers.map((i) => (i === "all" ? c.getLayers() : c.getLayer(i)) || "").filter(Boolean).join("\n")
260
- );
261
- css.walkDecls((declaration) => {
262
- declaration.source = source;
263
- });
264
- rule.replaceWith(css);
265
- excludes.push(rule.params);
266
- }
267
- });
268
- root.walkAtRules(directiveMap.unocss, (rule) => {
269
- if (!rule.params) {
270
- const source = rule.source;
271
- const css = postcss__default.parse(c.getLayers(void 0, excludes) || "");
272
- css.walkDecls((declaration) => {
273
- declaration.source = source;
274
- });
275
- rule.replaceWith(css);
276
- }
277
- });
8
+ async (root, result) => {
9
+ if (!promise)
10
+ promise = import('@unocss/postcss/esm').then((r) => r.createPlugin(options));
11
+ return await (await promise)(root, result);
278
12
  }
279
13
  ]
280
14
  };
@@ -282,4 +16,4 @@ function unocss(options = {}) {
282
16
  unocss.postcss = true;
283
17
  unocss.default = unocss;
284
18
 
285
- module.exports = unocss;
19
+ exports.default = unocss;
package/dist/index.mjs CHANGED
@@ -1,272 +1,12 @@
1
- import { stat, readFile } from 'node:fs/promises';
2
- import { normalize } from 'node:path';
3
- import process from 'node:process';
4
- import fg from 'fast-glob';
5
- import postcss from 'postcss';
6
- import { expandVariantGroup, notNull, regexScopePlaceholder, createGenerator } from '@unocss/core';
7
- import { loadConfig } from '@unocss/config';
8
- import { transformThemeFn, hasThemeFn } from '@unocss/rule-utils';
9
- import { parse, generate, clone } from 'css-tree';
10
-
11
- const defaultFilesystemGlobs = [
12
- "**/*.{html,js,ts,jsx,tsx,vue,svelte,astro,elm,php,phtml,mdx,md}"
13
- ];
14
-
15
- async function parseApply(root, uno, directiveName) {
16
- root.walkAtRules(directiveName, async (rule) => {
17
- if (!rule.parent)
18
- return;
19
- const source = rule.source;
20
- const classNames = expandVariantGroup(rule.params).split(/\s+/g).map((className) => className.trim().replace(/\\/, ""));
21
- const utils = (await Promise.all(
22
- classNames.map((i) => uno.parseToken(i, "-"))
23
- )).filter(notNull).flat().sort((a, b) => a[0] - b[0]).sort((a, b) => (a[3] ? uno.parentOrders.get(a[3]) ?? 0 : 0) - (b[3] ? uno.parentOrders.get(b[3]) ?? 0 : 0)).reduce((acc, item) => {
24
- const target = acc.find((i) => i[1] === item[1] && i[3] === item[3]);
25
- if (target)
26
- target[2] += item[2];
27
- else
28
- acc.push([...item]);
29
- return acc;
30
- }, []);
31
- if (!utils.length)
32
- return;
33
- const parentAfterNodes = [];
34
- for (const i of utils) {
35
- const [, _selector, body, parent] = i;
36
- const selector = _selector?.replace(regexScopePlaceholder, " ") || _selector;
37
- if (parent || selector && selector !== ".\\-") {
38
- const node = parse(rule.parent.toString(), {
39
- context: "rule"
40
- });
41
- let newSelector = generate(node.prelude);
42
- if (selector && selector !== ".\\-") {
43
- const selectorAST = parse(selector, {
44
- context: "selector"
45
- });
46
- const prelude = clone(node.prelude);
47
- prelude.children.forEach((child) => {
48
- const parentSelectorAst = clone(selectorAST);
49
- parentSelectorAst.children.forEach((i2) => {
50
- if (i2.type === "ClassSelector" && i2.name === "\\-")
51
- Object.assign(i2, clone(child));
52
- });
53
- Object.assign(child, parentSelectorAst);
54
- });
55
- newSelector = generate(prelude);
56
- }
57
- let css = `${newSelector}{${body}}`;
58
- if (parent)
59
- css = `${parent}{${css}}`;
60
- const css_parsed = postcss.parse(css);
61
- css_parsed.walkDecls((declaration) => {
62
- declaration.source = source;
63
- });
64
- parentAfterNodes.push(css_parsed);
65
- } else {
66
- const css = postcss.parse(body);
67
- css.walkDecls((declaration) => {
68
- declaration.source = source;
69
- });
70
- rule.parent.append(css);
71
- }
72
- }
73
- rule.parent.after(parentAfterNodes);
74
- rule.remove();
75
- });
76
- }
77
-
78
- async function parseTheme(root, uno) {
79
- root.walkDecls((decl) => {
80
- decl.value = transformThemeFn(decl.value, uno.config.theme);
81
- });
82
- }
83
-
84
- async function parseScreen(root, uno, directiveName) {
85
- root.walkAtRules(directiveName, async (rule) => {
86
- let breakpointName = "";
87
- let prefix = "";
88
- if (rule.params)
89
- breakpointName = rule.params.trim();
90
- if (!breakpointName)
91
- return;
92
- const match = breakpointName.match(/^(?:(lt|at)-)?(\w+)$/);
93
- if (match) {
94
- prefix = match[1];
95
- breakpointName = match[2];
96
- }
97
- const resolveBreakpoints = () => {
98
- let breakpoints;
99
- if (uno.userConfig && uno.userConfig.theme)
100
- breakpoints = uno.userConfig.theme.breakpoints;
101
- if (!breakpoints)
102
- breakpoints = uno.config.theme.breakpoints;
103
- return breakpoints ? Object.entries(breakpoints).sort((a, b) => Number.parseInt(a[1].replace(/[a-z]+/gi, "")) - Number.parseInt(b[1].replace(/[a-z]+/gi, ""))).map(([point, size]) => ({ point, size })) : void 0;
104
- };
105
- const variantEntries = (resolveBreakpoints() ?? []).map(({ point, size }, idx) => [point, size, idx]);
106
- const generateMediaQuery = (breakpointName2, prefix2) => {
107
- const [, size, idx] = variantEntries.find((i) => i[0] === breakpointName2);
108
- if (prefix2) {
109
- if (prefix2 === "lt")
110
- return `(max-width: ${calcMaxWidthBySize(size)})`;
111
- else if (prefix2 === "at")
112
- return `(min-width: ${size})${variantEntries[idx + 1] ? ` and (max-width: ${calcMaxWidthBySize(variantEntries[idx + 1][1])})` : ""}`;
113
- else
114
- throw new Error(`breakpoint variant not supported: ${prefix2}`);
115
- }
116
- return `(min-width: ${size})`;
117
- };
118
- if (!variantEntries.find((i) => i[0] === breakpointName))
119
- throw new Error(`breakpoint ${breakpointName} not found`);
120
- rule.name = "media";
121
- rule.params = `${generateMediaQuery(breakpointName, prefix)}`;
122
- });
123
- }
124
- function calcMaxWidthBySize(size) {
125
- const value = size.match(/^-?[0-9]+\.?[0-9]*/)?.[0] || "";
126
- const unit = size.slice(value.length);
127
- const maxWidth = Number.parseFloat(value) - 0.1;
128
- return Number.isNaN(maxWidth) ? size : `${maxWidth}${unit}`;
129
- }
130
-
131
1
  function unocss(options = {}) {
132
- const {
133
- cwd = process.cwd(),
134
- configOrPath
135
- } = options;
136
- const directiveMap = Object.assign({
137
- apply: "apply",
138
- theme: "theme",
139
- screen: "screen",
140
- unocss: "unocss"
141
- }, options.directiveMap || {});
142
- const fileMap = /* @__PURE__ */ new Map();
143
- const fileClassMap = /* @__PURE__ */ new Map();
144
- const classes = /* @__PURE__ */ new Set();
145
- const targetCache = /* @__PURE__ */ new Set();
146
- const config = loadConfig(cwd, configOrPath);
147
- let uno;
148
- let promises = [];
149
- let last_config_mtime = 0;
150
- const targetRE = new RegExp(Object.values(directiveMap).join("|"));
2
+ let promise;
151
3
  return {
152
- postcssPlugin: directiveMap.unocss,
4
+ postcssPlugin: options.directiveMap?.unocss || "unocss",
153
5
  plugins: [
154
- async function(root, result) {
155
- const from = result.opts.from?.split("?")[0];
156
- if (!from)
157
- return;
158
- let isTarget = targetCache.has(from);
159
- const isScanTarget = root.toString().includes(`@${directiveMap.unocss}`);
160
- if (targetRE.test(root.toString())) {
161
- if (!isTarget) {
162
- root.walkAtRules((rule) => {
163
- if (rule.name === directiveMap.unocss || rule.name === directiveMap.apply || rule.name === directiveMap.screen)
164
- isTarget = true;
165
- if (isTarget)
166
- return false;
167
- });
168
- if (!isTarget) {
169
- root.walkDecls((decl) => {
170
- if (hasThemeFn(decl.value)) {
171
- isTarget = true;
172
- return false;
173
- }
174
- });
175
- } else {
176
- targetCache.add(from);
177
- }
178
- }
179
- } else if (targetCache.has(from)) {
180
- targetCache.delete(from);
181
- }
182
- if (!isTarget)
183
- return;
184
- try {
185
- const cfg = await config;
186
- if (!uno) {
187
- uno = createGenerator(cfg.config);
188
- } else if (cfg.sources.length) {
189
- const config_mtime = (await stat(cfg.sources[0])).mtimeMs;
190
- if (config_mtime > last_config_mtime) {
191
- uno = createGenerator((await loadConfig(cwd, configOrPath)).config);
192
- last_config_mtime = config_mtime;
193
- }
194
- }
195
- } catch (error) {
196
- throw new Error(`UnoCSS config not found: ${error.message}`);
197
- }
198
- const globs = uno.config.content?.filesystem ?? defaultFilesystemGlobs;
199
- const plainContent = uno.config.content?.inline ?? [];
200
- const entries = await fg(isScanTarget ? globs : from, {
201
- cwd,
202
- absolute: true,
203
- ignore: ["**/node_modules/**"],
204
- stats: true
205
- });
206
- await parseApply(root, uno, directiveMap.apply);
207
- await parseTheme(root, uno);
208
- await parseScreen(root, uno, directiveMap.screen);
209
- promises.push(
210
- ...plainContent.map(async (c2, idx) => {
211
- if (typeof c2 === "function")
212
- c2 = await c2();
213
- if (typeof c2 === "string")
214
- c2 = { code: c2 };
215
- const { matched } = await uno.generate(c2.code, { id: c2.id ?? `__plain_content_${idx}__` });
216
- for (const candidate of matched)
217
- classes.add(candidate);
218
- }),
219
- ...entries.map(async ({ path: file, mtimeMs }) => {
220
- result.messages.push({
221
- type: "dependency",
222
- plugin: directiveMap.unocss,
223
- file: normalize(file),
224
- parent: from
225
- });
226
- if (fileMap.has(file) && mtimeMs <= fileMap.get(file))
227
- return;
228
- else
229
- fileMap.set(file, mtimeMs);
230
- const content = await readFile(file, "utf8");
231
- const { matched } = await uno.generate(content, {
232
- id: file
233
- });
234
- fileClassMap.set(file, matched);
235
- })
236
- );
237
- await Promise.all(promises);
238
- promises = [];
239
- for (const set of fileClassMap.values()) {
240
- for (const candidate of set)
241
- classes.add(candidate);
242
- }
243
- const c = await uno.generate(classes);
244
- classes.clear();
245
- const excludes = [];
246
- root.walkAtRules(directiveMap.unocss, (rule) => {
247
- if (rule.params) {
248
- const source = rule.source;
249
- const layers = rule.params.split(",").map((v) => v.trim());
250
- const css = postcss.parse(
251
- layers.map((i) => (i === "all" ? c.getLayers() : c.getLayer(i)) || "").filter(Boolean).join("\n")
252
- );
253
- css.walkDecls((declaration) => {
254
- declaration.source = source;
255
- });
256
- rule.replaceWith(css);
257
- excludes.push(rule.params);
258
- }
259
- });
260
- root.walkAtRules(directiveMap.unocss, (rule) => {
261
- if (!rule.params) {
262
- const source = rule.source;
263
- const css = postcss.parse(c.getLayers(void 0, excludes) || "");
264
- css.walkDecls((declaration) => {
265
- declaration.source = source;
266
- });
267
- rule.replaceWith(css);
268
- }
269
- });
6
+ async (root, result) => {
7
+ if (!promise)
8
+ promise = import('@unocss/postcss/esm').then((r) => r.createPlugin(options));
9
+ return await (await promise)(root, result);
270
10
  }
271
11
  ]
272
12
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/postcss",
3
- "version": "0.58.8",
3
+ "version": "0.59.0-beta.1",
4
4
  "description": "PostCSS plugin for UnoCSS",
5
5
  "author": "sibbng <sibbngheid@gmail.com>",
6
6
  "license": "MIT",
@@ -18,7 +18,6 @@
18
18
  "sideEffects": false,
19
19
  "exports": {
20
20
  ".": {
21
- "types": "./dist/index.d.ts",
22
21
  "import": "./dist/index.mjs",
23
22
  "require": "./dist/index.cjs"
24
23
  }
@@ -40,9 +39,9 @@
40
39
  "fast-glob": "^3.3.2",
41
40
  "magic-string": "^0.30.8",
42
41
  "postcss": "^8.4.38",
43
- "@unocss/core": "0.58.8",
44
- "@unocss/rule-utils": "0.58.8",
45
- "@unocss/config": "0.58.8"
42
+ "@unocss/core": "0.59.0-beta.1",
43
+ "@unocss/config": "0.59.0-beta.1",
44
+ "@unocss/rule-utils": "0.59.0-beta.1"
46
45
  },
47
46
  "scripts": {
48
47
  "build": "unbuild",