vite-plugin-taro 0.6.3 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.en.md +3 -3
  2. package/README.md +3 -3
  3. package/dist/node/plugins/wx/dev/dev-host.d.ts +5 -4
  4. package/dist/node/plugins/wx/dev/dev-host.js +19 -43
  5. package/dist/node/plugins/wx/dev/plugins.d.ts +4 -3
  6. package/dist/node/plugins/wx/dev/plugins.js +4 -4
  7. package/dist/node/plugins/wx/dev/wx-dev-options.d.ts +2 -3
  8. package/dist/node/plugins/wx/dev/wx-dev-options.js +4 -4
  9. package/dist/node/plugins/wx/plugins.js +5 -11
  10. package/dist/node/plugins/wx/styles/plugins.d.ts +141 -3
  11. package/dist/node/plugins/wx/styles/plugins.js +401 -89
  12. package/dist/node/utils/vite.d.ts +4 -14
  13. package/dist/node/utils/vite.js +7 -40
  14. package/package.json +4 -3
  15. package/src/node/plugins/wx/dev/dev-host.ts +22 -44
  16. package/src/node/plugins/wx/dev/plugins.ts +5 -4
  17. package/src/node/plugins/wx/dev/wx-dev-options.ts +5 -7
  18. package/src/node/plugins/wx/plugins.ts +5 -11
  19. package/src/node/plugins/wx/styles/plugins.ts +518 -93
  20. package/src/node/utils/vite.ts +13 -58
  21. package/dist/node/plugins/wx/dev/create-style-capture.d.ts +0 -54
  22. package/dist/node/plugins/wx/dev/create-style-capture.js +0 -173
  23. package/dist/node/plugins/wx/styles/transform-wx-style.d.ts +0 -8
  24. package/dist/node/plugins/wx/styles/transform-wx-style.js +0 -9
  25. package/dist/node/plugins/wx/styles/utils.d.ts +0 -39
  26. package/dist/node/plugins/wx/styles/utils.js +0 -95
  27. package/src/node/plugins/wx/dev/create-style-capture.ts +0 -248
  28. package/src/node/plugins/wx/styles/transform-wx-style.ts +0 -11
  29. package/src/node/plugins/wx/styles/utils.ts +0 -119
@@ -1,67 +1,22 @@
1
- import type { HookHandler, Plugin, PluginOption } from 'vite'
1
+ import type { HookHandler, Plugin } from 'vite'
2
2
 
3
3
  type TransformHook = HookHandler<NonNullable<Plugin['transform']>>
4
- export type TransformHookResult = Awaited<ReturnType<TransformHook>>
5
- export type AsyncTransformHook = (
4
+
5
+ type AsyncTransformHook = (
6
6
  this: ThisParameterType<TransformHook>,
7
7
  ...args: Parameters<TransformHook>
8
- ) => Promise<TransformHookResult>
9
- export type TransformHookWrapper = (transform: AsyncTransformHook) => AsyncTransformHook
10
-
11
- export type PluginMapper = (plugin: Plugin) => Plugin
12
-
13
- /** Transforms every concrete plugin while preserving nested arrays, falsy options, and promised options. */
14
- export function transformVitePlugin(pluginOptions: PluginOption[], mapPlugin: PluginMapper): PluginOption[] {
15
- return pluginOptions.map((option) => transformPluginOption(option, mapPlugin))
16
- }
17
-
18
- function transformPluginOption(option: PluginOption, mapPlugin: PluginMapper): PluginOption {
19
- if (option instanceof Promise) {
20
- return option.then((resolvedOption) => transformPluginOption(resolvedOption, mapPlugin))
21
- }
8
+ ) => Promise<Awaited<ReturnType<TransformHook>>>
22
9
 
23
- if (Array.isArray(option)) {
24
- return transformVitePlugin(option, mapPlugin)
25
- }
26
-
27
- return isPlugin(option) ? mapPlugin(option) : option
28
- }
29
-
30
- function isPlugin(option: PluginOption): option is Plugin {
31
- return (
32
- option !== null &&
33
- option !== false &&
34
- option !== undefined &&
35
- typeof option === 'object' &&
36
- !Array.isArray(option) &&
37
- 'name' in option
38
- )
39
- }
40
-
41
- /**
42
- * Clones a Vite transform hook with middleware that controls execution of the original handler.
43
- *
44
- * Function and object hook forms retain their original plugin context. Object metadata such as `order` and `filter` is copied
45
- * unchanged, and the input descriptor is never mutated. The wrapper receives the normalized asynchronous transform with its
46
- * complete plugin context, code, ID, and metadata signature, and returns the handler that continues Vite's plugin pipeline.
47
- */
48
- export function wrapPluginTransform(plugin: Plugin, wrapper: TransformHookWrapper): Plugin {
49
- const { transform } = plugin
50
-
51
- if (!transform) {
52
- throw new Error(`${plugin.name} must expose a transform hook`)
53
- }
54
-
55
- const isTransformFunction = typeof transform === 'function'
56
-
57
- const handler = isTransformFunction ? transform : transform.handler
10
+ export type TransformHookWrapper = (transform: AsyncTransformHook) => AsyncTransformHook
58
11
 
59
- const wrappedHandler = wrapper(async function (code, id, meta) {
60
- return handler.call(this, code, id, meta)
12
+ /** Mutates one concrete plugin to interpose on its transform while preserving hook metadata and plugin context. */
13
+ export function wrapPluginTransform(plugin: Plugin, wrapper: TransformHookWrapper): void {
14
+ const transform = plugin.transform!
15
+ const handler = typeof transform === 'function' ? transform : transform.handler
16
+ const wrapped = wrapper(async function (code, id, options) {
17
+ return handler.call(this, code, id, options)
61
18
  })
62
19
 
63
- return {
64
- ...plugin,
65
- transform: isTransformFunction ? wrappedHandler : { ...transform, handler: wrappedHandler }
66
- }
20
+ // Installation-time mutation keeps Vite's existing plugin identity and resolved hook registration.
21
+ plugin.transform = typeof transform === 'function' ? wrapped : { ...transform, handler: wrapped }
67
22
  }
@@ -1,54 +0,0 @@
1
- import type { GetModuleInfo, Plugin } from 'rolldown';
2
- /** Final CSS extracted from Vite's transformed style module, before the shared WX compatibility pass. */
3
- type ProcessedStyle = Readonly<{
4
- css: string;
5
- /** Marks roots whose generated utilities must be refreshed when JavaScript changes Tailwind candidates. */
6
- isTailwindRoot: boolean;
7
- }>;
8
- /** Minimal structural view of DevEngine output; style reconciliation does not own chunks or other asset metadata. */
9
- type CompleteOutputFile = Readonly<{
10
- type: 'asset';
11
- fileName: string;
12
- source: string | Uint8Array;
13
- }> | Readonly<{
14
- type: 'chunk';
15
- fileName: string;
16
- }>;
17
- export type StyleCaptureAction = Readonly<{
18
- kind: 'capture-graph';
19
- getModuleInfo: GetModuleInfo;
20
- }> | Readonly<{
21
- kind: 'capture-style';
22
- id: string;
23
- style: ProcessedStyle;
24
- }>;
25
- /**
26
- * Captures final Vite CSS and composes the graph projection with its durable WXSS publisher.
27
- *
28
- * Rolldown remains authoritative for topology. Plugin hooks emit typed actions so the host serializes capture mutations with
29
- * output and HMR publication; the projection and publisher below each own only one mutable concern.
30
- *
31
- * Complete-build path:
32
- * final transform captures → DevEngine output write → graph reconciliation → App build rotation
33
- *
34
- * Incremental path:
35
- * final transform captures → optional Tailwind root refresh → graph rendering → WXSS write → JavaScript patch publication
36
- *
37
- * Both paths render the same ordered App/Page graph projection. This prevents complete builds and HMR from implementing two
38
- * subtly different CSS ownership policies, while keeping physical byte equality and atomic writes out of graph state.
39
- */
40
- export declare function createStyleCapture({ applicationEntryIds, outDir, emit, transformTailwindRoot }: {
41
- applicationEntryIds: readonly string[];
42
- outDir: string;
43
- emit: (action: StyleCaptureAction) => void;
44
- transformTailwindRoot: (rootId: string, requestId: string) => Promise<Readonly<{
45
- code: string;
46
- }> | null>;
47
- }): Readonly<{
48
- captureGraph: (reader: GetModuleInfo) => void;
49
- captureStyle: (id: string, style: ProcessedStyle) => void;
50
- plugin: Plugin;
51
- publishChanged: (changedIds: readonly string[]) => Promise<void>;
52
- reconcileComplete: (output: readonly CompleteOutputFile[]) => Promise<void>;
53
- }>;
54
- export {};
@@ -1,173 +0,0 @@
1
- import { isCSSRequest } from 'vite';
2
- import { normalizeModuleId } from '../../../utils/modules.js';
3
- import { transformWxStyle } from '../styles/transform-wx-style.js';
4
- import { composeGraphStyleCss, createGraphStylePlan, createTailwindSidecarId, extractViteCss, isGlobalStyleRequest } from '../styles/utils.js';
5
- import { globalWxssFileName, writeHmrFile } from './hmr-files.js';
6
- /**
7
- * Captures final Vite CSS and composes the graph projection with its durable WXSS publisher.
8
- *
9
- * Rolldown remains authoritative for topology. Plugin hooks emit typed actions so the host serializes capture mutations with
10
- * output and HMR publication; the projection and publisher below each own only one mutable concern.
11
- *
12
- * Complete-build path:
13
- * final transform captures → DevEngine output write → graph reconciliation → App build rotation
14
- *
15
- * Incremental path:
16
- * final transform captures → optional Tailwind root refresh → graph rendering → WXSS write → JavaScript patch publication
17
- *
18
- * Both paths render the same ordered App/Page graph projection. This prevents complete builds and HMR from implementing two
19
- * subtly different CSS ownership policies, while keeping physical byte equality and atomic writes out of graph state.
20
- */
21
- export function createStyleCapture({ applicationEntryIds, outDir, emit, transformTailwindRoot }) {
22
- const projection = createStyleProjection({
23
- applicationEntryIds: applicationEntryIds,
24
- transformTailwindRoot: transformTailwindRoot
25
- });
26
- const publication = createStylePublication(outDir);
27
- const plugin = {
28
- name: 'vpt:wx-dev-style-capture',
29
- buildStart() {
30
- // Capture a live reader rather than a graph snapshot. Rolldown updates the capability as imports change, and a later
31
- // complete generation replaces it through the host action queue before that generation can publish output.
32
- emit({ kind: 'capture-graph', getModuleInfo: (moduleId) => this.getModuleInfo(moduleId) });
33
- },
34
- transform(code, id) {
35
- if (!isGlobalStyleRequest(id)) {
36
- return;
37
- }
38
- // This host plugin runs after Vite's CSS transform, so `code` is the JavaScript wrapper containing final PostCSS and
39
- // CSS-Module output. Capturing source CSS instead would lose generated class names and framework transformations.
40
- const css = extractViteCss(code, id);
41
- emit({
42
- kind: 'capture-style',
43
- id: normalizeModuleId(id),
44
- style: {
45
- css: css,
46
- isTailwindRoot: css.includes('weapp-tailwindcss vite-generated-css:')
47
- }
48
- });
49
- }
50
- };
51
- return {
52
- captureGraph: projection.captureGraph,
53
- captureStyle: projection.captureStyle,
54
- plugin: plugin,
55
- async publishChanged(changedIds) {
56
- // A CSS edit already carries updated processed bytes. Any non-CSS edit can alter both imports and Tailwind class
57
- // candidates, so it requires a fresh graph plan and Tailwind-root generation even when no .css ID changed directly.
58
- const styleChanged = changedIds.some(isGlobalStyleRequest);
59
- const candidatesChanged = changedIds.some((id) => !isCSSRequest(id));
60
- if (!styleChanged && !candidatesChanged) {
61
- return;
62
- }
63
- await publication.publish(await projection.render(candidatesChanged));
64
- },
65
- async reconcileComplete(output) {
66
- // Bundled development can omit CSS Modules from the compiler asset even with cssCodeSplit disabled. Observe the
67
- // physical output first, then reconcile the same graph projection used by incremental HMR before App rotation.
68
- publication.observeOutput(output);
69
- await publication.publish(await projection.render(false));
70
- }
71
- };
72
- }
73
- /**
74
- * Owns the live graph capability and final transformed bytes for every observed style module.
75
- *
76
- * Rendering is O(V + E + C): graph planning visits each reachable module and edge once, then composition and WX conversion
77
- * process C CSS bytes once. The only persistent memory is one processed byte string per style identity observed by the server.
78
- */
79
- function createStyleProjection({ applicationEntryIds, transformTailwindRoot }) {
80
- /*
81
- * This mutable capability is rebound by buildStart for each complete generation. Rolldown keeps the function live across
82
- * incremental graph edits, so rendering uses authoritative topology without maintaining a shadow graph.
83
- */
84
- let getModuleInfo;
85
- /*
86
- * This mutable projection stores final CSS bytes that Rolldown does not retain. Successful transforms replace one entry;
87
- * unreachable entries can remain because every render filters them through the current graph plan. Its size is bounded by
88
- * style module identities observed during this server lifecycle.
89
- */
90
- const processedStyles = new Map();
91
- return {
92
- captureGraph(reader) {
93
- getModuleInfo = reader;
94
- },
95
- captureStyle(id, style) {
96
- processedStyles.set(id, style);
97
- },
98
- async render(refreshTailwind) {
99
- if (!getModuleInfo) {
100
- throw new Error('WX style graph is unavailable before publication');
101
- }
102
- // App first and configured Pages afterward define one deterministic global cascade. The plan also removes stale map
103
- // entries implicitly: styles no longer reachable from these roots never enter composition.
104
- const styleIds = createGraphStylePlan(applicationEntryIds, getModuleInfo, (styleId) => processedStyles.has(styleId));
105
- if (refreshTailwind) {
106
- await refreshTailwindStyles(styleIds, processedStyles, transformTailwindRoot);
107
- }
108
- // Compose browser-facing transformed CSS first, then run one whole-file WX pass. Transforming modules independently
109
- // would change cross-module cascade behavior and duplicate compatibility work.
110
- const css = composeGraphStyleCss(styleIds, (styleId) => requireProcessedStyle(processedStyles, styleId).css);
111
- return (await transformWxStyle(css)).css;
112
- }
113
- };
114
- }
115
- /**
116
- * Owns the physical WXSS frontier independently from graph capture and rendering.
117
- *
118
- * DevEngine writes complete output itself; incremental HMR does not. Observing complete output before publishing the projection
119
- * gives both writers one byte frontier, so equality avoids redundant filesystem notifications without pretending the host owns
120
- * the compiler's write transaction.
121
- */
122
- function createStylePublication(outDir) {
123
- /*
124
- * This mutable value mirrors bytes durable on disk. Complete output adopts the compiler's external write before graph
125
- * reconciliation; host publication advances it only after an atomic write succeeds or byte equality proves none is needed.
126
- */
127
- let publishedWxss;
128
- return {
129
- observeOutput(output) {
130
- // Missing WXSS means DevEngine intentionally reused the existing physical asset. Do not reset the frontier: doing so
131
- // would force an identical rewrite and a spurious DevTools style event on every omitted complete generation.
132
- const style = output.find((file) => file.type === 'asset' && file.fileName === globalWxssFileName);
133
- if (style) {
134
- publishedWxss = typeof style.source === 'string' ? style.source : new TextDecoder().decode(style.source);
135
- }
136
- },
137
- async publish(wxss) {
138
- if (wxss !== publishedWxss) {
139
- // writeHmrFile uses atomic replacement; advance the frontier only after durability so a failed write leaves the
140
- // last known physical generation available for the next reconciliation attempt.
141
- await writeHmrFile(outDir, globalWxssFileName, wxss);
142
- }
143
- publishedWxss = wxss;
144
- }
145
- };
146
- }
147
- /**
148
- * Regenerates all reachable Tailwind roots and commits the cache only when every transform succeeds.
149
- *
150
- * Roots run concurrently because they are independent derivations of the same candidate generation. Results remain local until
151
- * Promise.all fulfills; one failed root therefore preserves every prior root together instead of publishing a mixed generation.
152
- */
153
- async function refreshTailwindStyles(styleIds, processedStyles, transformRoot) {
154
- const roots = styleIds.filter((styleId) => requireProcessedStyle(processedStyles, styleId).isTailwindRoot);
155
- const refreshedStyles = await Promise.all(roots.map(async (rootId) => {
156
- const requestId = createTailwindSidecarId(rootId);
157
- const result = await transformRoot(rootId, requestId);
158
- if (!result) {
159
- throw new Error(`Tailwind sidecar transform produced no result: ${requestId}`);
160
- }
161
- return [rootId, { css: extractViteCss(result.code, requestId), isTailwindRoot: true }];
162
- }));
163
- refreshedStyles.forEach(([rootId, style]) => {
164
- processedStyles.set(rootId, style);
165
- });
166
- }
167
- function requireProcessedStyle(processedStyles, styleId) {
168
- const style = processedStyles.get(styleId);
169
- if (!style) {
170
- throw new Error(`WX style plan references uncaptured CSS: ${styleId}`);
171
- }
172
- return style;
173
- }
@@ -1,8 +0,0 @@
1
- export declare const wxStyleOptions: {
2
- readonly cssCalc: false;
3
- readonly autoprefixer: false;
4
- readonly rem2rpx: true;
5
- readonly px2rpx: true;
6
- };
7
- /** Shared finalization policy for complete builds and host-owned style HMR. */
8
- export declare const transformWxStyle: import("@weapp-tailwindcss/postcss").StyleHandler;
@@ -1,9 +0,0 @@
1
- import { createStyleHandler } from '@weapp-tailwindcss/postcss';
2
- export const wxStyleOptions = {
3
- cssCalc: false,
4
- autoprefixer: false,
5
- rem2rpx: true,
6
- px2rpx: true
7
- };
8
- /** Shared finalization policy for complete builds and host-owned style HMR. */
9
- export const transformWxStyle = createStyleHandler(wxStyleOptions);
@@ -1,39 +0,0 @@
1
- /**
2
- * Creates an auxiliary style request without replacing the physical Rolldown graph module.
3
- *
4
- * `weapp-vite-sidecar` is an upstream protocol marker, not a cache-busting nonce. `weapp-tailwindcss` detects the query
5
- * key, strips the complete query when resolving the physical CSS pipeline file, and excludes this synthetic request from
6
- * transformed-source candidate collection. That lets the request use the latest candidate state without feeding generated
7
- * CSS back into Tailwind's source memory. The descriptive `style` value is stable; upstream treats the presence of the key
8
- * as the protocol contract.
9
- */
10
- export declare function createTailwindSidecarId(rootId: string): string;
11
- /** Selects imported style modules whose Vite development output owns a runtime CSS payload. */
12
- export declare function isGlobalStyleRequest(id: string): boolean;
13
- /**
14
- * Creates the ordered style plan for one completed HMR transaction.
15
- *
16
- * `entryIds` carries semantic cascade ownership from the WX resolver: the App capsule first, followed by Page capsules in
17
- * configured route order. Each entry is traversed depth-first. Static imports retain source order and precede dynamic imports;
18
- * dynamic branches are included because WX cannot inject lazy CSS at browser runtime. A style follows its dependencies,
19
- * matching evaluation order.
20
- *
21
- * Graph IDs may contain queries while `hasStyle` reads physical IDs. Normalization lets aliases share one captured style.
22
- * JavaScript and non-runtime CSS requests remain traversal nodes but do not enter the plan. All mutable traversal state is
23
- * transaction-local, so import additions and removals need no invalidation bookkeeping. Complexity is O(modules + edges),
24
- * with O(modules + styles) temporary memory.
25
- */
26
- export declare function createGraphStylePlan(entryIds: readonly string[], getModuleInfo: (moduleId: string) => Readonly<{
27
- importedIds: readonly string[];
28
- dynamicallyImportedIds: readonly string[];
29
- }> | null, hasStyle: (styleId: string) => boolean): readonly string[];
30
- /** Renders one immutable graph plan after any Tailwind roots in that same plan have been refreshed. */
31
- export declare function composeGraphStyleCss(styleIds: readonly string[], getStyleCss: (styleId: string) => string): string;
32
- /**
33
- * Extracts Vite's final CSS payload from the development module without evaluating its browser HMR code.
34
- *
35
- * Remove this parser when either Vite exposes a supported plugin-container API that returns final CSS directly, or
36
- * `weapp-tailwindcss` exposes generated root CSS after candidate updates. Until then the sidecar receives Vite's JavaScript
37
- * style module, so this function isolates the version-specific `__vite__css` serialization contract.
38
- */
39
- export declare function extractViteCss(moduleCode: string, rootId: string): string;
@@ -1,95 +0,0 @@
1
- import { isCSSRequest } from 'vite';
2
- import { normalizeModuleId } from '../../../utils/modules.js';
3
- const nonRuntimeStyleQueries = ['direct', 'inline', 'inline-css', 'raw', 'style-attr', 'transform-only', 'url'];
4
- /**
5
- * Creates an auxiliary style request without replacing the physical Rolldown graph module.
6
- *
7
- * `weapp-vite-sidecar` is an upstream protocol marker, not a cache-busting nonce. `weapp-tailwindcss` detects the query
8
- * key, strips the complete query when resolving the physical CSS pipeline file, and excludes this synthetic request from
9
- * transformed-source candidate collection. That lets the request use the latest candidate state without feeding generated
10
- * CSS back into Tailwind's source memory. The descriptive `style` value is stable; upstream treats the presence of the key
11
- * as the protocol contract.
12
- */
13
- export function createTailwindSidecarId(rootId) {
14
- return `${rootId}?weapp-vite-sidecar=style`;
15
- }
16
- /** Selects imported style modules whose Vite development output owns a runtime CSS payload. */
17
- export function isGlobalStyleRequest(id) {
18
- if (!isCSSRequest(id)) {
19
- return false;
20
- }
21
- const queryStart = id.indexOf('?');
22
- if (queryStart < 0) {
23
- return true;
24
- }
25
- const fragmentStart = id.indexOf('#', queryStart);
26
- const query = id.slice(queryStart + 1, fragmentStart < 0 ? undefined : fragmentStart);
27
- const parameters = new URLSearchParams(query);
28
- return (!parameters.has('weapp-vite-sidecar') && nonRuntimeStyleQueries.every((parameter) => !parameters.has(parameter)));
29
- }
30
- /**
31
- * Creates the ordered style plan for one completed HMR transaction.
32
- *
33
- * `entryIds` carries semantic cascade ownership from the WX resolver: the App capsule first, followed by Page capsules in
34
- * configured route order. Each entry is traversed depth-first. Static imports retain source order and precede dynamic imports;
35
- * dynamic branches are included because WX cannot inject lazy CSS at browser runtime. A style follows its dependencies,
36
- * matching evaluation order.
37
- *
38
- * Graph IDs may contain queries while `hasStyle` reads physical IDs. Normalization lets aliases share one captured style.
39
- * JavaScript and non-runtime CSS requests remain traversal nodes but do not enter the plan. All mutable traversal state is
40
- * transaction-local, so import additions and removals need no invalidation bookkeeping. Complexity is O(modules + edges),
41
- * with O(modules + styles) temporary memory.
42
- */
43
- export function createGraphStylePlan(entryIds, getModuleInfo, hasStyle) {
44
- // These local collections collapse cycles, shared modules, and aliases without retaining derived topology between batches.
45
- const visitedModuleIds = new Set();
46
- const visitedStyleIds = new Set();
47
- const styleIds = [];
48
- const visit = (moduleId) => {
49
- if (visitedModuleIds.has(moduleId)) {
50
- return;
51
- }
52
- visitedModuleIds.add(moduleId);
53
- const moduleInfo = getModuleInfo(moduleId);
54
- if (!moduleInfo) {
55
- return;
56
- }
57
- moduleInfo.importedIds.forEach(visit);
58
- moduleInfo.dynamicallyImportedIds.forEach(visit);
59
- const styleId = normalizeModuleId(moduleId);
60
- if (hasStyle(styleId) && !visitedStyleIds.has(styleId)) {
61
- visitedStyleIds.add(styleId);
62
- styleIds.push(styleId);
63
- }
64
- };
65
- entryIds.forEach(visit);
66
- return styleIds;
67
- }
68
- /** Renders one immutable graph plan after any Tailwind roots in that same plan have been refreshed. */
69
- export function composeGraphStyleCss(styleIds, getStyleCss) {
70
- return styleIds.map(getStyleCss).join('\n');
71
- }
72
- /**
73
- * Extracts Vite's final CSS payload from the development module without evaluating its browser HMR code.
74
- *
75
- * Remove this parser when either Vite exposes a supported plugin-container API that returns final CSS directly, or
76
- * `weapp-tailwindcss` exposes generated root CSS after candidate updates. Until then the sidecar receives Vite's JavaScript
77
- * style module, so this function isolates the version-specific `__vite__css` serialization contract.
78
- */
79
- export function extractViteCss(moduleCode, rootId) {
80
- const assignmentPrefix = 'const __vite__css = ';
81
- const assignmentStart = moduleCode.indexOf(assignmentPrefix);
82
- if (assignmentStart < 0) {
83
- throw new Error(`Vite CSS transform for ${rootId} did not expose __vite__css`);
84
- }
85
- // Vite serializes the payload with JSON.stringify on one assignment line. Parse that literal so quotes, escapes, and
86
- // embedded CSS newlines are decoded by JSON rather than by a second, subtly different unescaping implementation.
87
- const valueStart = assignmentStart + assignmentPrefix.length;
88
- const lineEnd = moduleCode.indexOf('\n', valueStart);
89
- const serializedCss = moduleCode.slice(valueStart, lineEnd < 0 ? moduleCode.length : lineEnd);
90
- const css = JSON.parse(serializedCss);
91
- if (typeof css !== 'string') {
92
- throw new Error(`Vite CSS transform for ${rootId} exposed a non-string __vite__css value`);
93
- }
94
- return css;
95
- }