Skip to content

Commit

Permalink
WIP: added communication between vite plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
shairez committed Jan 9, 2025
1 parent 4af0105 commit 6126e98
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 33 deletions.
2 changes: 1 addition & 1 deletion packages/docs/src/routes/api/qwik-optimizer/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@
}
],
"kind": "Interface",
"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>",
"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>",
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/plugins/vite.ts",
"mdFile": "qwik.qwikvitepluginapi.md"
},
Expand Down
13 changes: 13 additions & 0 deletions packages/docs/src/routes/api/qwik-optimizer/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2220,6 +2220,19 @@ Description

</td><td>

</td></tr>
<tr><td>

[registerBundleGraphModifier](#)

</td><td>

</td><td>

(modifier: BundleGraphModifier) =&gt; void

</td><td>

</td></tr>
</tbody></table>

Expand Down
42 changes: 23 additions & 19 deletions packages/qwik-city/src/buildtime/vite/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import type { QwikVitePlugin } from '@builder.io/qwik/optimizer';
import swRegister from '@qwik-city-sw-register-build';
import { createMdxTransformer, type MdxTransform } from '../markdown/mdx';
import { basename, join, resolve, extname } from 'node:path';
import type { Plugin, PluginOption, UserConfig, Rollup } from 'vite';
import fs from 'node:fs';
import { basename, extname, join, resolve } from 'node:path';
import type { Plugin, PluginOption, Rollup, UserConfig } from 'vite';
import { loadEnv } from 'vite';
import { generateQwikCityPlan } from '../runtime-generation/generate-qwik-city-plan';
import type { BuildContext } from '../types';
import { createBuildContext, resetBuildContext } from '../context';
import {
NOT_FOUND_PATHS_ID,
RESOLVED_NOT_FOUND_PATHS_ID,
RESOLVED_STATIC_PATHS_ID,
STATIC_PATHS_ID,
} from '../../adapters/shared/vite';
import { postBuild } from '../../adapters/shared/vite/post-build';
import { patchGlobalThis } from '../../middleware/node/node-fetch';
import { isMenuFileName, normalizePath, removeExtension } from '../../utils/fs';
import { validatePlugin } from './validate-plugin';
import type { QwikCityPluginApi, QwikCityVitePluginOptions } from './types';
import { build } from '../build';
import { ssrDevMiddleware, staticDistMiddleware } from './dev-server';
import { createBuildContext, resetBuildContext } from '../context';
import { createMdxTransformer, type MdxTransform } from '../markdown/mdx';
import { transformMenu } from '../markdown/menu';
import { generateQwikCityEntries } from '../runtime-generation/generate-entries';
import { patchGlobalThis } from '../../middleware/node/node-fetch';
import type { QwikVitePlugin } from '@builder.io/qwik/optimizer';
import fs from 'node:fs';
import { generateQwikCityPlan } from '../runtime-generation/generate-qwik-city-plan';
import {
generateServiceWorkerRegister,
prependManifestToServiceWorker,
} from '../runtime-generation/generate-service-worker';
import {
NOT_FOUND_PATHS_ID,
RESOLVED_NOT_FOUND_PATHS_ID,
RESOLVED_STATIC_PATHS_ID,
STATIC_PATHS_ID,
} from '../../adapters/shared/vite';
import { postBuild } from '../../adapters/shared/vite/post-build';
import type { BuildContext } from '../types';
import { ssrDevMiddleware, staticDistMiddleware } from './dev-server';
import { imagePlugin } from './image-jsx';
import type { QwikCityPluginApi, QwikCityVitePluginOptions } from './types';
import { validatePlugin } from './validate-plugin';

/** @public */
export function qwikCity(userOpts?: QwikCityVitePluginOptions): PluginOption[] {
Expand Down Expand Up @@ -237,6 +237,10 @@ function qwikCityPlugin(userOpts?: QwikCityVitePluginOptions): any {
generateBundle(_, bundles) {
// client bundles
if (ctx?.target === 'client') {
// qwikPlugin!.api.registerBundleGraphModifier((graph, bundlesIndiciesMap) => {
// graph.push(-2);

// });
const entries = [...ctx.entries, ...ctx.serviceWorkers].map((entry) => {
return {
chunkFileName: entry.chunkFileName,
Expand Down
4 changes: 4 additions & 0 deletions packages/qwik/src/optimizer/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ export interface QwikVitePluginApi {
getOptions: () => NormalizedQwikPluginOptions;
// (undocumented)
getRootDir: () => string | null;
// Warning: (ae-forgotten-export) The symbol "BundleGraphModifier" needs to be exported by the entry point index.d.ts
//
// (undocumented)
registerBundleGraphModifier: (modifier: BundleGraphModifier) => void;
}

// Warning: (ae-forgotten-export) The symbol "QwikVitePluginCSROptions" needs to be exported by the entry point index.d.ts
Expand Down
25 changes: 22 additions & 3 deletions packages/qwik/src/optimizer/src/plugins/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const FONTS = ['.woff', '.woff2', '.ttf'];
*/
type P<T> = VitePlugin<T> & { api: T; config: Extract<VitePlugin<T>['config'], Function> };

export type BundleGraphModifier = (graph: QwikBundleGraph) => QwikBundleGraph;

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

const bundleGraphModifiers = new Set<BundleGraphModifier>();

const api: QwikVitePluginApi = {
getOptimizer: () => qwikPlugin.getOptimizer(),
getOptions: () => qwikPlugin.getOptions(),
Expand All @@ -102,6 +106,8 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
getClientOutDir: () => clientOutDir,
getClientPublicOutDir: () => clientPublicOutDir,
getAssetsDir: () => viteAssetsDir,
registerBundleGraphModifier: (modifier: BundleGraphModifier) =>
bundleGraphModifiers.add(modifier),
};

// We provide two plugins to Vite. The first plugin is the main plugin that handles all the
Expand Down Expand Up @@ -592,14 +598,17 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
const assetsDir = qwikPlugin.getOptions().assetsDir || '';
const useAssetsDir = !!assetsDir && assetsDir !== '_astro';
const sys = qwikPlugin.getSys();

const bundleGraph = convertManifestToBundleGraph(manifest, bundleGraphModifiers);

this.emitFile({
type: 'asset',
fileName: sys.path.join(
useAssetsDir ? assetsDir : '',
'build',
`q-bundle-graph-${manifest.manifestHash}.json`
),
source: JSON.stringify(convertManifestToBundleGraph(manifest)),
source: JSON.stringify(bundleGraph),
});
const fs: typeof import('fs') = await sys.dynamicImport('node:fs');
const workerScriptPath = (await this.resolve('@builder.io/qwik/qwik-prefetch.js'))!.id;
Expand Down Expand Up @@ -1100,6 +1109,7 @@ export interface QwikVitePluginApi {
getClientOutDir: () => string | null;
getClientPublicOutDir: () => string | null;
getAssetsDir: () => string | undefined;
registerBundleGraphModifier: (modifier: BundleGraphModifier) => void;
}

/**
Expand Down Expand Up @@ -1133,8 +1143,11 @@ function absolutePathAwareJoin(path: Path, ...segments: string[]): string {
return path.join(...segments);
}

export function convertManifestToBundleGraph(manifest: QwikManifest): QwikBundleGraph {
const bundleGraph: QwikBundleGraph = [];
export function convertManifestToBundleGraph(
manifest: QwikManifest,
bundleGraphModifiers?: Set<BundleGraphModifier>
): QwikBundleGraph {
let bundleGraph: QwikBundleGraph = [];
const graph = manifest.bundles;
if (!graph) {
return [];
Expand Down Expand Up @@ -1212,5 +1225,11 @@ export function convertManifestToBundleGraph(manifest: QwikManifest): QwikBundle
bundleGraph[index++] = depIndex;
}
}
if (bundleGraphModifiers && bundleGraphModifiers.size > 0) {
for (const modifier of bundleGraphModifiers) {
bundleGraph = modifier(bundleGraph);
}
}

return bundleGraph;
}
55 changes: 45 additions & 10 deletions packages/qwik/src/optimizer/src/plugins/vite.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { OptimizerOptions, QwikBundle, QwikManifest } from '../types';
import {
convertManifestToBundleGraph,
qwikVite,
type BundleGraphModifier,
type QwikVitePlugin,
type QwikVitePluginOptions,
} from './vite';
Expand Down Expand Up @@ -457,11 +458,16 @@ test('command: build, --mode lib with multiple outputs', async () => {
});

suite('convertManifestToBundleGraph', () => {
test('empty', () => {
expect(convertManifestToBundleGraph({} as any)).toEqual([]);
test(`GIVEN an empty manifest
THEN should return an empty array`, () => {
const emptyManifest = {} as QwikManifest;

const actualResult = convertManifestToBundleGraph(emptyManifest);
expect(actualResult).toEqual([]);
});

test('simple file set', () => {
test(`GIVEN a manifest with 2 static bundles and 1 dynamic bundle
THEN should return an efficient array with the correct pointers`, () => {
const manifest = {
bundles: {
'a.js': {
Expand All @@ -478,15 +484,44 @@ suite('convertManifestToBundleGraph', () => {
},
} as Record<string, QwikBundle>,
} as QwikManifest;
expect(convertManifestToBundleGraph(manifest)).toEqual([

const actualResult = convertManifestToBundleGraph(manifest);

expect(actualResult).toEqual(['a.js', 4, -1, 7, 'b.js', -1, 7, 'c.js']);
});

test(`GIVEN a manifest with 2 static bundles and 1 dynamic bundle
AND a modifier that adds routes info to the bundleGraph
THEN the added info should be added to the result`, () => {
const manifest = {
bundles: {
'a.js': {
size: 0,
imports: ['b.js'],
},
'b.js': {
size: 0,
},
} as Record<string, QwikBundle>,
} as QwikManifest;

const fakeBundleGraphModifier: BundleGraphModifier = (bundleGraph) => {
bundleGraph = [...bundleGraph, -2, '/route', 0];
return bundleGraph;
};

const fakeModifiers = new Set([fakeBundleGraphModifier]);

const actualResult = convertManifestToBundleGraph(manifest, fakeModifiers);

expect(actualResult).toEqual([
'a.js',
4,
-1,
7,
2,
'b.js',
-1,
7,
'c.js',
-2,
// THIS IS THE ADDED INFO 👇
'/route',
0,
]);
});
});

0 comments on commit 6126e98

Please sign in to comment.