Skip to content

Commit 6126e98

Browse files
committed
WIP: added communication between vite plugins
1 parent 4af0105 commit 6126e98

File tree

6 files changed

+108
-33
lines changed

6 files changed

+108
-33
lines changed

packages/docs/src/routes/api/qwik-optimizer/api.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@
518518
}
519519
],
520520
"kind": "Interface",
521-
"content": "```typescript\nexport interface QwikVitePluginApi \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[getAssetsDir](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; string \\| undefined\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getClientOutDir](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; string \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getClientPublicOutDir](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; string \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getInsightsManifest](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(clientOutDir?: string \\| null) =&gt; Promise&lt;[InsightManifest](#insightmanifest) \\| null&gt;\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getManifest](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; [QwikManifest](#qwikmanifest) \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getOptimizer](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; [Optimizer](#optimizer) \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getOptions](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; NormalizedQwikPluginOptions\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getRootDir](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; string \\| null\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>",
521+
"content": "```typescript\nexport interface QwikVitePluginApi \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[getAssetsDir](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; string \\| undefined\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getClientOutDir](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; string \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getClientPublicOutDir](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; string \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getInsightsManifest](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(clientOutDir?: string \\| null) =&gt; Promise&lt;[InsightManifest](#insightmanifest) \\| null&gt;\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getManifest](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; [QwikManifest](#qwikmanifest) \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getOptimizer](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; [Optimizer](#optimizer) \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getOptions](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; NormalizedQwikPluginOptions\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[getRootDir](#)\n\n\n</td><td>\n\n\n</td><td>\n\n() =&gt; string \\| null\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[registerBundleGraphModifier](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(modifier: BundleGraphModifier) =&gt; void\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>",
522522
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/plugins/vite.ts",
523523
"mdFile": "qwik.qwikvitepluginapi.md"
524524
},

packages/docs/src/routes/api/qwik-optimizer/index.md

+13
Original file line numberDiff line numberDiff line change
@@ -2220,6 +2220,19 @@ Description
22202220

22212221
</td><td>
22222222

2223+
</td></tr>
2224+
<tr><td>
2225+
2226+
[registerBundleGraphModifier](#)
2227+
2228+
</td><td>
2229+
2230+
</td><td>
2231+
2232+
(modifier: BundleGraphModifier) =&gt; void
2233+
2234+
</td><td>
2235+
22232236
</td></tr>
22242237
</tbody></table>
22252238

packages/qwik-city/src/buildtime/vite/plugin.ts

+23-19
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1+
import type { QwikVitePlugin } from '@builder.io/qwik/optimizer';
12
import swRegister from '@qwik-city-sw-register-build';
2-
import { createMdxTransformer, type MdxTransform } from '../markdown/mdx';
3-
import { basename, join, resolve, extname } from 'node:path';
4-
import type { Plugin, PluginOption, UserConfig, Rollup } from 'vite';
3+
import fs from 'node:fs';
4+
import { basename, extname, join, resolve } from 'node:path';
5+
import type { Plugin, PluginOption, Rollup, UserConfig } from 'vite';
56
import { loadEnv } from 'vite';
6-
import { generateQwikCityPlan } from '../runtime-generation/generate-qwik-city-plan';
7-
import type { BuildContext } from '../types';
8-
import { createBuildContext, resetBuildContext } from '../context';
7+
import {
8+
NOT_FOUND_PATHS_ID,
9+
RESOLVED_NOT_FOUND_PATHS_ID,
10+
RESOLVED_STATIC_PATHS_ID,
11+
STATIC_PATHS_ID,
12+
} from '../../adapters/shared/vite';
13+
import { postBuild } from '../../adapters/shared/vite/post-build';
14+
import { patchGlobalThis } from '../../middleware/node/node-fetch';
915
import { isMenuFileName, normalizePath, removeExtension } from '../../utils/fs';
10-
import { validatePlugin } from './validate-plugin';
11-
import type { QwikCityPluginApi, QwikCityVitePluginOptions } from './types';
1216
import { build } from '../build';
13-
import { ssrDevMiddleware, staticDistMiddleware } from './dev-server';
17+
import { createBuildContext, resetBuildContext } from '../context';
18+
import { createMdxTransformer, type MdxTransform } from '../markdown/mdx';
1419
import { transformMenu } from '../markdown/menu';
1520
import { generateQwikCityEntries } from '../runtime-generation/generate-entries';
16-
import { patchGlobalThis } from '../../middleware/node/node-fetch';
17-
import type { QwikVitePlugin } from '@builder.io/qwik/optimizer';
18-
import fs from 'node:fs';
21+
import { generateQwikCityPlan } from '../runtime-generation/generate-qwik-city-plan';
1922
import {
2023
generateServiceWorkerRegister,
2124
prependManifestToServiceWorker,
2225
} from '../runtime-generation/generate-service-worker';
23-
import {
24-
NOT_FOUND_PATHS_ID,
25-
RESOLVED_NOT_FOUND_PATHS_ID,
26-
RESOLVED_STATIC_PATHS_ID,
27-
STATIC_PATHS_ID,
28-
} from '../../adapters/shared/vite';
29-
import { postBuild } from '../../adapters/shared/vite/post-build';
26+
import type { BuildContext } from '../types';
27+
import { ssrDevMiddleware, staticDistMiddleware } from './dev-server';
3028
import { imagePlugin } from './image-jsx';
29+
import type { QwikCityPluginApi, QwikCityVitePluginOptions } from './types';
30+
import { validatePlugin } from './validate-plugin';
3131

3232
/** @public */
3333
export function qwikCity(userOpts?: QwikCityVitePluginOptions): PluginOption[] {
@@ -237,6 +237,10 @@ function qwikCityPlugin(userOpts?: QwikCityVitePluginOptions): any {
237237
generateBundle(_, bundles) {
238238
// client bundles
239239
if (ctx?.target === 'client') {
240+
// qwikPlugin!.api.registerBundleGraphModifier((graph, bundlesIndiciesMap) => {
241+
// graph.push(-2);
242+
243+
// });
240244
const entries = [...ctx.entries, ...ctx.serviceWorkers].map((entry) => {
241245
return {
242246
chunkFileName: entry.chunkFileName,

packages/qwik/src/optimizer/src/api.md

+4
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ export interface QwikVitePluginApi {
300300
getOptions: () => NormalizedQwikPluginOptions;
301301
// (undocumented)
302302
getRootDir: () => string | null;
303+
// Warning: (ae-forgotten-export) The symbol "BundleGraphModifier" needs to be exported by the entry point index.d.ts
304+
//
305+
// (undocumented)
306+
registerBundleGraphModifier: (modifier: BundleGraphModifier) => void;
303307
}
304308

305309
// Warning: (ae-forgotten-export) The symbol "QwikVitePluginCSROptions" needs to be exported by the entry point index.d.ts

packages/qwik/src/optimizer/src/plugins/vite.ts

+22-3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ const FONTS = ['.woff', '.woff2', '.ttf'];
4949
*/
5050
type P<T> = VitePlugin<T> & { api: T; config: Extract<VitePlugin<T>['config'], Function> };
5151

52+
export type BundleGraphModifier = (graph: QwikBundleGraph) => QwikBundleGraph;
53+
5254
/**
5355
* The types for Vite/Rollup don't allow us to be too specific about the return type. The correct
5456
* return type is `[QwikVitePlugin, VitePlugin<never>]`, and if you search the plugin by name you'll
@@ -93,6 +95,8 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
9395
return null;
9496
}
9597

98+
const bundleGraphModifiers = new Set<BundleGraphModifier>();
99+
96100
const api: QwikVitePluginApi = {
97101
getOptimizer: () => qwikPlugin.getOptimizer(),
98102
getOptions: () => qwikPlugin.getOptions(),
@@ -102,6 +106,8 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
102106
getClientOutDir: () => clientOutDir,
103107
getClientPublicOutDir: () => clientPublicOutDir,
104108
getAssetsDir: () => viteAssetsDir,
109+
registerBundleGraphModifier: (modifier: BundleGraphModifier) =>
110+
bundleGraphModifiers.add(modifier),
105111
};
106112

107113
// We provide two plugins to Vite. The first plugin is the main plugin that handles all the
@@ -592,14 +598,17 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
592598
const assetsDir = qwikPlugin.getOptions().assetsDir || '';
593599
const useAssetsDir = !!assetsDir && assetsDir !== '_astro';
594600
const sys = qwikPlugin.getSys();
601+
602+
const bundleGraph = convertManifestToBundleGraph(manifest, bundleGraphModifiers);
603+
595604
this.emitFile({
596605
type: 'asset',
597606
fileName: sys.path.join(
598607
useAssetsDir ? assetsDir : '',
599608
'build',
600609
`q-bundle-graph-${manifest.manifestHash}.json`
601610
),
602-
source: JSON.stringify(convertManifestToBundleGraph(manifest)),
611+
source: JSON.stringify(bundleGraph),
603612
});
604613
const fs: typeof import('fs') = await sys.dynamicImport('node:fs');
605614
const workerScriptPath = (await this.resolve('@builder.io/qwik/qwik-prefetch.js'))!.id;
@@ -1100,6 +1109,7 @@ export interface QwikVitePluginApi {
11001109
getClientOutDir: () => string | null;
11011110
getClientPublicOutDir: () => string | null;
11021111
getAssetsDir: () => string | undefined;
1112+
registerBundleGraphModifier: (modifier: BundleGraphModifier) => void;
11031113
}
11041114

11051115
/**
@@ -1133,8 +1143,11 @@ function absolutePathAwareJoin(path: Path, ...segments: string[]): string {
11331143
return path.join(...segments);
11341144
}
11351145

1136-
export function convertManifestToBundleGraph(manifest: QwikManifest): QwikBundleGraph {
1137-
const bundleGraph: QwikBundleGraph = [];
1146+
export function convertManifestToBundleGraph(
1147+
manifest: QwikManifest,
1148+
bundleGraphModifiers?: Set<BundleGraphModifier>
1149+
): QwikBundleGraph {
1150+
let bundleGraph: QwikBundleGraph = [];
11381151
const graph = manifest.bundles;
11391152
if (!graph) {
11401153
return [];
@@ -1212,5 +1225,11 @@ export function convertManifestToBundleGraph(manifest: QwikManifest): QwikBundle
12121225
bundleGraph[index++] = depIndex;
12131226
}
12141227
}
1228+
if (bundleGraphModifiers && bundleGraphModifiers.size > 0) {
1229+
for (const modifier of bundleGraphModifiers) {
1230+
bundleGraph = modifier(bundleGraph);
1231+
}
1232+
}
1233+
12151234
return bundleGraph;
12161235
}

packages/qwik/src/optimizer/src/plugins/vite.unit.ts

+45-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { OptimizerOptions, QwikBundle, QwikManifest } from '../types';
66
import {
77
convertManifestToBundleGraph,
88
qwikVite,
9+
type BundleGraphModifier,
910
type QwikVitePlugin,
1011
type QwikVitePluginOptions,
1112
} from './vite';
@@ -457,11 +458,16 @@ test('command: build, --mode lib with multiple outputs', async () => {
457458
});
458459

459460
suite('convertManifestToBundleGraph', () => {
460-
test('empty', () => {
461-
expect(convertManifestToBundleGraph({} as any)).toEqual([]);
461+
test(`GIVEN an empty manifest
462+
THEN should return an empty array`, () => {
463+
const emptyManifest = {} as QwikManifest;
464+
465+
const actualResult = convertManifestToBundleGraph(emptyManifest);
466+
expect(actualResult).toEqual([]);
462467
});
463468

464-
test('simple file set', () => {
469+
test(`GIVEN a manifest with 2 static bundles and 1 dynamic bundle
470+
THEN should return an efficient array with the correct pointers`, () => {
465471
const manifest = {
466472
bundles: {
467473
'a.js': {
@@ -478,15 +484,44 @@ suite('convertManifestToBundleGraph', () => {
478484
},
479485
} as Record<string, QwikBundle>,
480486
} as QwikManifest;
481-
expect(convertManifestToBundleGraph(manifest)).toEqual([
487+
488+
const actualResult = convertManifestToBundleGraph(manifest);
489+
490+
expect(actualResult).toEqual(['a.js', 4, -1, 7, 'b.js', -1, 7, 'c.js']);
491+
});
492+
493+
test(`GIVEN a manifest with 2 static bundles and 1 dynamic bundle
494+
AND a modifier that adds routes info to the bundleGraph
495+
THEN the added info should be added to the result`, () => {
496+
const manifest = {
497+
bundles: {
498+
'a.js': {
499+
size: 0,
500+
imports: ['b.js'],
501+
},
502+
'b.js': {
503+
size: 0,
504+
},
505+
} as Record<string, QwikBundle>,
506+
} as QwikManifest;
507+
508+
const fakeBundleGraphModifier: BundleGraphModifier = (bundleGraph) => {
509+
bundleGraph = [...bundleGraph, -2, '/route', 0];
510+
return bundleGraph;
511+
};
512+
513+
const fakeModifiers = new Set([fakeBundleGraphModifier]);
514+
515+
const actualResult = convertManifestToBundleGraph(manifest, fakeModifiers);
516+
517+
expect(actualResult).toEqual([
482518
'a.js',
483-
4,
484-
-1,
485-
7,
519+
2,
486520
'b.js',
487-
-1,
488-
7,
489-
'c.js',
521+
-2,
522+
// THIS IS THE ADDED INFO 👇
523+
'/route',
524+
0,
490525
]);
491526
});
492527
});

0 commit comments

Comments
 (0)