@teacss/vite 0.10.3 → 0.10.5
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/finalize.d.ts +5 -0
- package/dist/finalize.js +104 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.js +83 -41
- package/dist/virtual.d.ts +8 -11
- package/dist/virtual.js +10 -13
- package/package.json +4 -3
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ResolvedBuildEnvironmentOptions, type ResolvedConfig } from "vite";
|
|
2
|
+
type BuildOptions = Pick<ResolvedBuildEnvironmentOptions, "cssMinify" | "cssTarget">;
|
|
3
|
+
export declare function finalizeBuildCss(css: string, config: ResolvedConfig, build: BuildOptions, viteVersion: string): Promise<string>;
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=finalize.d.ts.map
|
package/dist/finalize.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { preprocessCSS } from "vite";
|
|
4
|
+
import { RESOLVED_ENTRY } from "./virtual.js";
|
|
5
|
+
// esbuild and lightningcss are Vite's (a dependency or an optional peer, by version), not this package's: load them as Vite does.
|
|
6
|
+
const fromVite = createRequire(import.meta.resolve("vite"));
|
|
7
|
+
export async function finalizeBuildCss(css, config, build, viteVersion) {
|
|
8
|
+
const filename = join(config.root, RESOLVED_ENTRY.slice(1));
|
|
9
|
+
const minifier = minifierOf(build.cssMinify, viteVersion);
|
|
10
|
+
const lightningcss = config.css.transformer === "lightningcss";
|
|
11
|
+
// One pass: a second Lightning CSS pass repeats the prefixes the first one added.
|
|
12
|
+
if (lightningcss && minifier === "lightningcss")
|
|
13
|
+
return minifyWithLightningcss(css, filename, config, build.cssTarget);
|
|
14
|
+
const { code } = await preprocessCSS(css, filename, lightningcss ? withoutCssMinify(config) : config);
|
|
15
|
+
if (minifier === "esbuild")
|
|
16
|
+
return minifyWithEsbuild(code, filename, config, build.cssTarget);
|
|
17
|
+
if (minifier === "lightningcss")
|
|
18
|
+
return minifyWithLightningcss(code, filename, config, build.cssTarget);
|
|
19
|
+
return code;
|
|
20
|
+
}
|
|
21
|
+
/** `preprocessCSS` runs Lightning CSS with the client environment's `build`, minifying wherever its `cssMinify` is set. */
|
|
22
|
+
function withoutCssMinify(config) {
|
|
23
|
+
const environments = Object.fromEntries(Object.entries(config.environments).map(([name, options]) => [name, { ...options, build: { ...options.build, cssMinify: false } }]));
|
|
24
|
+
return { ...config, build: { ...config.build, cssMinify: false }, environments };
|
|
25
|
+
}
|
|
26
|
+
function minifierOf(cssMinify, viteVersion) {
|
|
27
|
+
if (cssMinify !== true)
|
|
28
|
+
return cssMinify;
|
|
29
|
+
// Vite 7 minifies with esbuild for `cssMinify: true`, Vite 8 with Lightning CSS.
|
|
30
|
+
return Number.parseInt(viteVersion, 10) >= 8 ? "lightningcss" : "esbuild";
|
|
31
|
+
}
|
|
32
|
+
async function minifyWithEsbuild(css, filename, config, cssTarget) {
|
|
33
|
+
const esbuild = fromVite("esbuild");
|
|
34
|
+
const result = await esbuild.transform(css, { ...resolveMinifyCssEsbuildOptions(config.esbuild || {}), loader: "css", sourcefile: filename, target: cssTarget || undefined });
|
|
35
|
+
for (const warning of result.warnings)
|
|
36
|
+
config.logger.warn(`[esbuild css minify] ${warning.text}`);
|
|
37
|
+
return result.code;
|
|
38
|
+
}
|
|
39
|
+
function resolveMinifyCssEsbuildOptions(options) {
|
|
40
|
+
const { charset, legalComments, logLevel, logLimit, logOverride, minifyIdentifiers, minifySyntax, minifyWhitespace } = options;
|
|
41
|
+
const base = { charset, legalComments, logLevel, logLimit, logOverride };
|
|
42
|
+
if (minifyIdentifiers == null && minifySyntax == null && minifyWhitespace == null)
|
|
43
|
+
return { ...base, minify: true };
|
|
44
|
+
return { ...base, minifyIdentifiers: minifyIdentifiers ?? true, minifySyntax: minifySyntax ?? true, minifyWhitespace: minifyWhitespace ?? true };
|
|
45
|
+
}
|
|
46
|
+
function minifyWithLightningcss(css, filename, config, cssTarget) {
|
|
47
|
+
const lightningcss = fromVite("lightningcss");
|
|
48
|
+
const result = lightningcss.transform({ ...config.css.lightningcss, filename, code: Buffer.from(css), minify: true, targets: convertTargets(cssTarget), cssModules: undefined });
|
|
49
|
+
for (const warning of result.warnings)
|
|
50
|
+
config.logger.warn(`[lightningcss minify] ${warning.message}`);
|
|
51
|
+
return new TextDecoder().decode(result.code);
|
|
52
|
+
}
|
|
53
|
+
const CSS_TARGET_BROWSERS = new Map([
|
|
54
|
+
["chrome", "chrome"],
|
|
55
|
+
["edge", "edge"],
|
|
56
|
+
["firefox", "firefox"],
|
|
57
|
+
["hermes", false],
|
|
58
|
+
["ie", "ie"],
|
|
59
|
+
["ios", "ios_saf"],
|
|
60
|
+
["node", false],
|
|
61
|
+
["opera", "opera"],
|
|
62
|
+
["rhino", false],
|
|
63
|
+
["safari", "safari"],
|
|
64
|
+
]);
|
|
65
|
+
const ES_TARGETS = new Map([
|
|
66
|
+
[2015, ["chrome49", "edge13", "safari10", "ios10", "firefox44", "opera36"]],
|
|
67
|
+
[2016, ["chrome50", "edge13", "safari10", "ios10", "firefox43", "opera37"]],
|
|
68
|
+
[2017, ["chrome58", "edge15", "safari11", "ios11", "firefox52", "opera45"]],
|
|
69
|
+
[2018, ["chrome63", "edge79", "safari12", "ios12", "firefox58", "opera50"]],
|
|
70
|
+
[2019, ["chrome73", "edge79", "safari12.1", "ios12.1", "firefox64", "opera60"]],
|
|
71
|
+
[2020, ["chrome80", "edge80", "safari14.1", "ios14.5", "firefox80", "opera67"]],
|
|
72
|
+
[2021, ["chrome85", "edge85", "safari14.1", "ios14.5", "firefox80", "opera71"]],
|
|
73
|
+
[2022, ["chrome94", "edge94", "safari16.4", "ios16.4", "firefox93", "opera80"]],
|
|
74
|
+
[2023, ["chrome110", "edge110", "safari16.4", "ios16.4", "firefox146", "opera96"]],
|
|
75
|
+
[2024, ["chrome119", "edge119", "safari17.4", "ios17.4", "firefox145", "opera105"]],
|
|
76
|
+
[2025, ["chrome136", "edge136", "safari26.0", "ios26.0", "firefox138", "opera121"]],
|
|
77
|
+
]);
|
|
78
|
+
function convertTargets(cssTarget) {
|
|
79
|
+
const targets = {};
|
|
80
|
+
for (const entry of [cssTarget || []].flat().flatMap(esBrowsers)) {
|
|
81
|
+
if (entry === "esnext")
|
|
82
|
+
continue;
|
|
83
|
+
const [, name = "", major, minor = "0"] = /^([a-z_]+)(\d+)(?:\.(\d+))?$/i.exec(entry) ?? [];
|
|
84
|
+
const browser = CSS_TARGET_BROWSERS.get(name.toLowerCase());
|
|
85
|
+
if (browser === false)
|
|
86
|
+
continue;
|
|
87
|
+
if (browser === undefined)
|
|
88
|
+
throw new Error(`Unsupported target "${entry}"`);
|
|
89
|
+
const version = (Number(major) << 16) | (Number(minor) << 8);
|
|
90
|
+
if (version < (targets[browser] ?? Number.POSITIVE_INFINITY))
|
|
91
|
+
targets[browser] = version;
|
|
92
|
+
}
|
|
93
|
+
return targets;
|
|
94
|
+
}
|
|
95
|
+
function esBrowsers(entry) {
|
|
96
|
+
const year = /^es(6|\d{4})$/.exec(entry)?.[1];
|
|
97
|
+
if (year === undefined)
|
|
98
|
+
return [entry];
|
|
99
|
+
const browsers = ES_TARGETS.get(year === "6" ? 2015 : Number(year));
|
|
100
|
+
if (browsers === undefined)
|
|
101
|
+
throw new Error(`Unsupported target "${entry}"`);
|
|
102
|
+
return browsers;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=finalize.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export type { ShellOptions } from "@teacss/engine";
|
|
2
2
|
export { INSPECTOR_BASE, type TeacssViteOptions, type TeacssVitePluginApi, teacss } from "./plugin.js";
|
|
3
|
-
export { BUILD_PLACEHOLDER, DEFAULT_PIPELINE_INCLUDE, ENTRY_IDS,
|
|
3
|
+
export { BUILD_PLACEHOLDER, BUILD_PLACEHOLDER_PATTERN, DEFAULT_PIPELINE_INCLUDE, ENTRY_IDS, RESOLVED_ENTRY } from "./virtual.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { INSPECTOR_BASE, teacss } from "./plugin.js";
|
|
2
|
-
export { BUILD_PLACEHOLDER, DEFAULT_PIPELINE_INCLUDE, ENTRY_IDS,
|
|
2
|
+
export { BUILD_PLACEHOLDER, BUILD_PLACEHOLDER_PATTERN, DEFAULT_PIPELINE_INCLUDE, ENTRY_IDS, RESOLVED_ENTRY } from "./virtual.js";
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { type Project, type ShellOptions } from "@teacss/engine";
|
|
2
2
|
import type { Plugin } from "vite";
|
|
3
3
|
export interface TeacssViteOptions extends ShellOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The engine's own minify of the generated CSS, which drops the layer comments and line breaks. Default false:
|
|
6
|
+
* a build hands the generated CSS to Vite's minifier, `build.cssMinify`, whatever this option says.
|
|
7
|
+
*/
|
|
8
|
+
minify?: boolean;
|
|
4
9
|
/** v10.2 §3.6: serve `@teacss/inspector` at `INSPECTOR_BASE` on the dev server. Default true; a build never mounts it. */
|
|
5
10
|
inspector?: boolean;
|
|
6
11
|
/**
|
package/dist/plugin.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
1
2
|
import { readFileSync } from "node:fs";
|
|
2
3
|
import { createRequire } from "node:module";
|
|
3
4
|
import { join, posix, resolve } from "node:path";
|
|
4
5
|
import { createProject, extractBundledFonts, isCssId, markers, replaceEntryWithMap } from "@teacss/engine";
|
|
5
6
|
import { createInspectorMiddleware } from "@teacss/inspector";
|
|
6
|
-
import {
|
|
7
|
+
import { finalizeBuildCss } from "./finalize.js";
|
|
8
|
+
import { BUILD_PLACEHOLDER, BUILD_PLACEHOLDER_PATTERN, digestPlaceholder, hmrPath, isResolvedEntry, resolveEntryId, shouldTransform } from "./virtual.js";
|
|
7
9
|
const INCLUDE_COMMENT = markers().includeComment;
|
|
8
10
|
/** architecture §5: the files `loadProjectFromRoot` discovers the entry through. */
|
|
9
11
|
const ENTRY_CANDIDATES = ["package.json", "index.css", "src/index.css"];
|
|
@@ -12,6 +14,27 @@ const INVALIDATION_DELAY_MS = 10;
|
|
|
12
14
|
/** The dev-server path the inspector's UI and `/api` routes live under; the UI's built asset URLs assume it. */
|
|
13
15
|
export const INSPECTOR_BASE = "/__teacss";
|
|
14
16
|
const HTML_ENTRY = /\.html$/;
|
|
17
|
+
/** `vite:css-post`'s transform, and the stylesheets holding the placeholder it cached, by its hook object. */
|
|
18
|
+
const cssPostCaches = new WeakMap();
|
|
19
|
+
/**
|
|
20
|
+
* Vite names a CSS file by the hash of what `vite:css-post` cached for its stylesheets, when it renders a chunk,
|
|
21
|
+
* and the generated CSS replaces the placeholder only in `generateBundle`. So the stylesheets that hold the
|
|
22
|
+
* placeholder are recorded here, and `renderStart` caches them again with the generated CSS's digest in it.
|
|
23
|
+
*/
|
|
24
|
+
function recordPlaceholderStylesheets(plugins) {
|
|
25
|
+
const hook = plugins.find((plugin) => plugin.name === "vite:css-post")?.transform;
|
|
26
|
+
if (typeof hook !== "object" || hook === null || cssPostCaches.has(hook))
|
|
27
|
+
return;
|
|
28
|
+
const transform = hook.handler;
|
|
29
|
+
const cached = new Map();
|
|
30
|
+
cssPostCaches.set(hook, { transform, cached });
|
|
31
|
+
const record = function (css, id, ...rest) {
|
|
32
|
+
if (typeof css === "string" && css.search(BUILD_PLACEHOLDER_PATTERN) !== -1)
|
|
33
|
+
cached.set(id, css);
|
|
34
|
+
return transform.call(this, css, id, ...rest);
|
|
35
|
+
};
|
|
36
|
+
hook.handler = record;
|
|
37
|
+
}
|
|
15
38
|
export function teacss(options = {}) {
|
|
16
39
|
const { inspector = true, lightningcss, ...shell } = options;
|
|
17
40
|
let project;
|
|
@@ -170,7 +193,7 @@ export function teacss(options = {}) {
|
|
|
170
193
|
...shell,
|
|
171
194
|
root: shell.root ?? config.root,
|
|
172
195
|
envMode: shell.envMode ?? (isBuild ? "build" : "dev"),
|
|
173
|
-
minify: shell.minify ??
|
|
196
|
+
minify: shell.minify ?? false,
|
|
174
197
|
});
|
|
175
198
|
disposed = false;
|
|
176
199
|
sources.clear();
|
|
@@ -185,7 +208,7 @@ export function teacss(options = {}) {
|
|
|
185
208
|
*/
|
|
186
209
|
function generated(warn) {
|
|
187
210
|
if (config.command === "build")
|
|
188
|
-
return
|
|
211
|
+
return BUILD_PLACEHOLDER;
|
|
189
212
|
if (failure)
|
|
190
213
|
server?.hot.send({ type: "error", err: failure });
|
|
191
214
|
const result = project.css();
|
|
@@ -202,6 +225,47 @@ export function teacss(options = {}) {
|
|
|
202
225
|
disposed = true;
|
|
203
226
|
project.dispose();
|
|
204
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* Splices the generated CSS into every CSS file that holds the placeholder. Vite writes a chunk's CSS file
|
|
230
|
+
* when it renders the chunk, and with `build.cssCodeSplit: false` its single CSS file only in its own
|
|
231
|
+
* `generateBundle`, so `teacss:api` runs this again after it.
|
|
232
|
+
*/
|
|
233
|
+
const spliceGenerated = async function (_options, bundle) {
|
|
234
|
+
let css;
|
|
235
|
+
const fonts = new Map();
|
|
236
|
+
for (const file of Object.values(bundle)) {
|
|
237
|
+
if (file.type !== "asset" || !file.fileName.endsWith(".css"))
|
|
238
|
+
continue;
|
|
239
|
+
const source = typeof file.source === "string" ? file.source : new TextDecoder().decode(file.source);
|
|
240
|
+
if (source.search(BUILD_PLACEHOLDER_PATTERN) === -1)
|
|
241
|
+
continue;
|
|
242
|
+
if (css === undefined) {
|
|
243
|
+
const result = project.css();
|
|
244
|
+
project.reportUnmatched(result, { warn: (message) => this.warn(message) });
|
|
245
|
+
css = await finalizeBuildCss(result.css, this.environment.getTopLevelConfig(), this.environment.config.build, viteVersion);
|
|
246
|
+
}
|
|
247
|
+
const emitted = new Set();
|
|
248
|
+
const spliced = extractBundledFonts(css, (digest, bytes) => {
|
|
249
|
+
let reference = fonts.get(digest);
|
|
250
|
+
if (reference === undefined) {
|
|
251
|
+
reference = this.emitFile({ type: "asset", name: `teacss-${digest}.woff2`, source: bytes });
|
|
252
|
+
fonts.set(digest, reference);
|
|
253
|
+
}
|
|
254
|
+
const fileName = this.getFileName(reference);
|
|
255
|
+
emitted.add(fileName);
|
|
256
|
+
return assetUrl(config.base, file.fileName, fileName);
|
|
257
|
+
}).css;
|
|
258
|
+
file.source = source.replace(BUILD_PLACEHOLDER_PATTERN, () => spliced);
|
|
259
|
+
// Vite's manifest lists a chunk's assets from `viteMetadata.importedAssets`; Astro moves the
|
|
260
|
+
// fonts of its server build to the client output from that list.
|
|
261
|
+
for (const chunk of Object.values(bundle)) {
|
|
262
|
+
if (chunk.type !== "chunk" || !chunk.viteMetadata?.importedCss.has(file.fileName))
|
|
263
|
+
continue;
|
|
264
|
+
for (const fileName of emitted)
|
|
265
|
+
chunk.viteMetadata.importedAssets.add(fileName);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
};
|
|
205
269
|
const main = {
|
|
206
270
|
name: "teacss",
|
|
207
271
|
enforce: "pre",
|
|
@@ -239,8 +303,21 @@ export function teacss(options = {}) {
|
|
|
239
303
|
dispose();
|
|
240
304
|
config = resolved;
|
|
241
305
|
viteVersion = this.meta.viteVersion;
|
|
306
|
+
if (resolved.command === "build")
|
|
307
|
+
recordPlaceholderStylesheets(resolved.plugins);
|
|
242
308
|
open();
|
|
243
309
|
},
|
|
310
|
+
async renderStart() {
|
|
311
|
+
if (config.command !== "build")
|
|
312
|
+
return;
|
|
313
|
+
const hook = this.environment.config.plugins.find((plugin) => plugin.name === "vite:css-post")?.transform;
|
|
314
|
+
const cache = typeof hook === "object" && hook !== null ? cssPostCaches.get(hook) : undefined;
|
|
315
|
+
if (!cache || cache.cached.size === 0)
|
|
316
|
+
return;
|
|
317
|
+
const digest = createHash("sha256").update(project.css().css).digest("hex").slice(0, 16);
|
|
318
|
+
for (const [id, css] of cache.cached)
|
|
319
|
+
await cache.transform.call(this, css.replace(BUILD_PLACEHOLDER_PATTERN, () => digestPlaceholder(digest)), id);
|
|
320
|
+
},
|
|
244
321
|
buildStart() {
|
|
245
322
|
if (disposed)
|
|
246
323
|
open();
|
|
@@ -281,7 +358,7 @@ export function teacss(options = {}) {
|
|
|
281
358
|
return null;
|
|
282
359
|
const result = project.transform(id, code);
|
|
283
360
|
const stylesheet = isCssId(id);
|
|
284
|
-
const entry = stylesheet ? replaceEntryWithMap(result.code, () => generated((message) => this.warn(message)), { id
|
|
361
|
+
const entry = stylesheet ? replaceEntryWithMap(result.code, () => generated((message) => this.warn(message)), { id, original: code, map: result.map }) : null;
|
|
285
362
|
if (entry !== null) {
|
|
286
363
|
entries.add(id);
|
|
287
364
|
return { code: entry.code, map: { ...entry.map, file: entry.map.file ?? undefined } };
|
|
@@ -303,43 +380,7 @@ export function teacss(options = {}) {
|
|
|
303
380
|
return result.code;
|
|
304
381
|
},
|
|
305
382
|
},
|
|
306
|
-
generateBundle
|
|
307
|
-
const placeholder = buildPlaceholder(config.build.cssMinify, viteVersion);
|
|
308
|
-
let css;
|
|
309
|
-
const fonts = new Map();
|
|
310
|
-
for (const file of Object.values(bundle)) {
|
|
311
|
-
if (file.type !== "asset" || !file.fileName.endsWith(".css"))
|
|
312
|
-
continue;
|
|
313
|
-
const source = typeof file.source === "string" ? file.source : new TextDecoder().decode(file.source);
|
|
314
|
-
if (!source.includes(placeholder))
|
|
315
|
-
continue;
|
|
316
|
-
if (css === undefined) {
|
|
317
|
-
const result = project.css();
|
|
318
|
-
project.reportUnmatched(result, { warn: (message) => this.warn(message) });
|
|
319
|
-
css = result.css;
|
|
320
|
-
}
|
|
321
|
-
const emitted = new Set();
|
|
322
|
-
const spliced = extractBundledFonts(css, (digest, bytes) => {
|
|
323
|
-
let reference = fonts.get(digest);
|
|
324
|
-
if (reference === undefined) {
|
|
325
|
-
reference = this.emitFile({ type: "asset", name: `teacss-${digest}.woff2`, source: bytes });
|
|
326
|
-
fonts.set(digest, reference);
|
|
327
|
-
}
|
|
328
|
-
const fileName = this.getFileName(reference);
|
|
329
|
-
emitted.add(fileName);
|
|
330
|
-
return assetUrl(config.base, file.fileName, fileName);
|
|
331
|
-
}).css;
|
|
332
|
-
file.source = source.replaceAll(placeholder, spliced);
|
|
333
|
-
// Vite's manifest lists a chunk's assets from `viteMetadata.importedAssets`; Astro moves the
|
|
334
|
-
// fonts of its server build to the client output from that list.
|
|
335
|
-
for (const chunk of Object.values(bundle)) {
|
|
336
|
-
if (chunk.type !== "chunk" || !chunk.viteMetadata?.importedCss.has(file.fileName))
|
|
337
|
-
continue;
|
|
338
|
-
for (const fileName of emitted)
|
|
339
|
-
chunk.viteMetadata.importedAssets.add(fileName);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
},
|
|
383
|
+
generateBundle: spliceGenerated,
|
|
343
384
|
closeBundle() {
|
|
344
385
|
if (!config.build.watch)
|
|
345
386
|
dispose();
|
|
@@ -351,6 +392,7 @@ export function teacss(options = {}) {
|
|
|
351
392
|
const api = {
|
|
352
393
|
name: "teacss:api",
|
|
353
394
|
enforce: "post",
|
|
395
|
+
generateBundle: spliceGenerated,
|
|
354
396
|
api: { getProject: () => project },
|
|
355
397
|
};
|
|
356
398
|
return [main, api];
|
package/dist/virtual.d.ts
CHANGED
|
@@ -2,19 +2,16 @@
|
|
|
2
2
|
export declare const ENTRY_IDS: ReadonlySet<string>;
|
|
3
3
|
/** The resolved id of the virtual entry; Vite's CSS pipeline treats it as a `.css` module. */
|
|
4
4
|
export declare const RESOLVED_ENTRY = "\0virtual:teacss.css";
|
|
5
|
-
/** What `load` returns for the entry in a build; `generateBundle` replaces it with the generated CSS. */
|
|
6
|
-
export declare const BUILD_PLACEHOLDER: string;
|
|
7
|
-
/**
|
|
8
|
-
* The placeholder for a build whose `cssMinify` is esbuild: Vite minifies with `legalComments: "none"`,
|
|
9
|
-
* which drops the comment, while an unknown at-rule passes esbuild untouched and without a warning.
|
|
10
|
-
* lightningcss keeps the comment and would warn about the at-rule, so it gets `BUILD_PLACEHOLDER`.
|
|
11
|
-
*/
|
|
12
|
-
export declare const MINIFIED_PLACEHOLDER: string;
|
|
13
5
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
6
|
+
* What `load` returns for the entry in a build; `generateBundle` replaces it with the generated CSS. A rule,
|
|
7
|
+
* because every minifier keeps one: lightningcss keeps a legal comment only at the top of a stylesheet and
|
|
8
|
+
* warns about an unknown at-rule, esbuild drops the comment, and other CSS can precede the entry in a chunk.
|
|
16
9
|
*/
|
|
17
|
-
export declare
|
|
10
|
+
export declare const BUILD_PLACEHOLDER: string;
|
|
11
|
+
/** `BUILD_PLACEHOLDER` with the digest of the CSS that will replace it, which goes into the CSS file's name. */
|
|
12
|
+
export declare function digestPlaceholder(digest: string): string;
|
|
13
|
+
/** `BUILD_PLACEHOLDER` or a `digestPlaceholder` as any minifier prints it. */
|
|
14
|
+
export declare const BUILD_PLACEHOLDER_PATTERN: RegExp;
|
|
18
15
|
/** Resolves `virtual:teacss.css`, `teacss.css`, their `/`-prefixed forms and the resolved id itself, keeping a `?query`. */
|
|
19
16
|
export declare function resolveEntryId(id: string): string | null;
|
|
20
17
|
/**
|
package/dist/virtual.js
CHANGED
|
@@ -3,22 +3,19 @@ import { CSS_PLACEHOLDER, isCssId } from "@teacss/engine";
|
|
|
3
3
|
export const ENTRY_IDS = new Set(["virtual:teacss.css", "teacss.css"]);
|
|
4
4
|
/** The resolved id of the virtual entry; Vite's CSS pipeline treats it as a `.css` module. */
|
|
5
5
|
export const RESOLVED_ENTRY = "\0virtual:teacss.css";
|
|
6
|
-
|
|
7
|
-
export const BUILD_PLACEHOLDER = `/*! ${CSS_PLACEHOLDER} */`;
|
|
6
|
+
const PLACEHOLDER_NAME = CSS_PLACEHOLDER.slice(1);
|
|
8
7
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* What `load` returns for the entry in a build; `generateBundle` replaces it with the generated CSS. A rule,
|
|
9
|
+
* because every minifier keeps one: lightningcss keeps a legal comment only at the top of a stylesheet and
|
|
10
|
+
* warns about an unknown at-rule, esbuild drops the comment, and other CSS can precede the entry in a chunk.
|
|
12
11
|
*/
|
|
13
|
-
export const
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
*/
|
|
18
|
-
export function buildPlaceholder(cssMinify, viteVersion) {
|
|
19
|
-
const esbuild = cssMinify === "esbuild" || (cssMinify === true && Number.parseInt(viteVersion, 10) < 8);
|
|
20
|
-
return esbuild ? MINIFIED_PLACEHOLDER : BUILD_PLACEHOLDER;
|
|
12
|
+
export const BUILD_PLACEHOLDER = `#${PLACEHOLDER_NAME}{--${PLACEHOLDER_NAME}:0}`;
|
|
13
|
+
/** `BUILD_PLACEHOLDER` with the digest of the CSS that will replace it, which goes into the CSS file's name. */
|
|
14
|
+
export function digestPlaceholder(digest) {
|
|
15
|
+
return `#${PLACEHOLDER_NAME}{--${PLACEHOLDER_NAME}:t${digest}}`;
|
|
21
16
|
}
|
|
17
|
+
/** `BUILD_PLACEHOLDER` or a `digestPlaceholder` as any minifier prints it. */
|
|
18
|
+
export const BUILD_PLACEHOLDER_PATTERN = new RegExp(`#${PLACEHOLDER_NAME}\\s*\\{\\s*--${PLACEHOLDER_NAME}\\s*:\\s*[\\w-]+\\s*;?\\s*\\}`, "g");
|
|
22
19
|
/** Resolves `virtual:teacss.css`, `teacss.css`, their `/`-prefixed forms and the resolved id itself, keeping a `?query`. */
|
|
23
20
|
export function resolveEntryId(id) {
|
|
24
21
|
const [bare = "", query] = splitQuery(id);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teacss/vite",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.5",
|
|
4
4
|
"description": "Vite plugin for TeaCSS on the Rust engine (@teacss/engine)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,11 +36,12 @@
|
|
|
36
36
|
"vite": ">=7"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@teacss/engine": "0.10.
|
|
40
|
-
"@teacss/inspector": "0.10.
|
|
39
|
+
"@teacss/engine": "0.10.5",
|
|
40
|
+
"@teacss/inspector": "0.10.5"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^22.20.5",
|
|
44
|
+
"lightningcss": "^1.32.0",
|
|
44
45
|
"typescript": "^5.9.3",
|
|
45
46
|
"vite": "^7.3.7"
|
|
46
47
|
},
|