wip: store propagated scripts separately
This commit is contained in:
parent
a36e8fd912
commit
0577e4e9e4
5 changed files with 98 additions and 20 deletions
|
@ -75,19 +75,37 @@ export function astroContentProdBundlePlugin({ internals }: { internals: BuildIn
|
||||||
name: 'astro:content-prod-bundle',
|
name: 'astro:content-prod-bundle',
|
||||||
async generateBundle(_options, bundle) {
|
async generateBundle(_options, bundle) {
|
||||||
for (const [_, chunk] of Object.entries(bundle)) {
|
for (const [_, chunk] of Object.entries(bundle)) {
|
||||||
if (chunk.type === 'chunk' && chunk.code.includes(LINKS_PLACEHOLDER)) {
|
if (
|
||||||
|
chunk.type === 'chunk' &&
|
||||||
|
(chunk.code.includes(LINKS_PLACEHOLDER) || chunk.code.includes(SCRIPTS_PLACEHOLDER))
|
||||||
|
) {
|
||||||
for (const id of Object.keys(chunk.modules)) {
|
for (const id of Object.keys(chunk.modules)) {
|
||||||
for (const [pageInfo, depth, order] of walkParentInfos(id, this)) {
|
for (const [pageInfo, depth, order] of walkParentInfos(id, this)) {
|
||||||
if (moduleIsTopLevelPage(pageInfo)) {
|
if (moduleIsTopLevelPage(pageInfo)) {
|
||||||
const pageViteID = pageInfo.id;
|
const pageViteID = pageInfo.id;
|
||||||
const pageData = getPageDataByViteID(internals, pageViteID);
|
const pageData = getPageDataByViteID(internals, pageViteID);
|
||||||
if (!pageData) continue;
|
if (!pageData) continue;
|
||||||
|
console.log({ pageData });
|
||||||
const entryCss = pageData.contentCollectionCss?.get(id);
|
const entryCss = pageData.contentCollectionCss?.get(id);
|
||||||
if (!entryCss) continue;
|
const entryScripts = pageData.propagatedScripts?.get(id);
|
||||||
chunk.code = chunk.code.replace(
|
if (entryCss) {
|
||||||
JSON.stringify(LINKS_PLACEHOLDER),
|
chunk.code = chunk.code.replace(
|
||||||
JSON.stringify([...entryCss])
|
JSON.stringify(LINKS_PLACEHOLDER),
|
||||||
);
|
JSON.stringify([...entryCss])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (entryScripts) {
|
||||||
|
console.log({ entryScripts });
|
||||||
|
chunk.code = chunk.code.replace(
|
||||||
|
JSON.stringify(SCRIPTS_PLACEHOLDER),
|
||||||
|
JSON.stringify(
|
||||||
|
[...entryScripts].map((src) => ({
|
||||||
|
props: { src, type: 'module' },
|
||||||
|
children: '',
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,10 @@ export function moduleIsTopLevelPage(info: ModuleInfo): boolean {
|
||||||
// This could be a .astro page, a .markdown or a .md (or really any file extension for markdown files) page.
|
// This could be a .astro page, a .markdown or a .md (or really any file extension for markdown files) page.
|
||||||
export function* getTopLevelPages(
|
export function* getTopLevelPages(
|
||||||
id: string,
|
id: string,
|
||||||
ctx: { getModuleInfo: GetModuleInfo }
|
ctx: { getModuleInfo: GetModuleInfo },
|
||||||
|
walkUntil?: (importer: string) => boolean
|
||||||
): Generator<[ModuleInfo, number, number], void, unknown> {
|
): Generator<[ModuleInfo, number, number], void, unknown> {
|
||||||
for (const res of walkParentInfos(id, ctx)) {
|
for (const res of walkParentInfos(id, ctx, walkUntil)) {
|
||||||
if (moduleIsTopLevelPage(res[0])) {
|
if (moduleIsTopLevelPage(res[0])) {
|
||||||
yield res;
|
yield res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ export async function collectPagesData(
|
||||||
moduleSpecifier: '',
|
moduleSpecifier: '',
|
||||||
css: new Map(),
|
css: new Map(),
|
||||||
contentCollectionCss: new Map(),
|
contentCollectionCss: new Map(),
|
||||||
|
propagatedScripts: new Map(),
|
||||||
hoistedScript: undefined,
|
hoistedScript: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,6 +78,7 @@ export async function collectPagesData(
|
||||||
moduleSpecifier: '',
|
moduleSpecifier: '',
|
||||||
css: new Map(),
|
css: new Map(),
|
||||||
contentCollectionCss: new Map(),
|
contentCollectionCss: new Map(),
|
||||||
|
propagatedScripts: new Map(),
|
||||||
hoistedScript: undefined,
|
hoistedScript: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ export interface PageBuildData {
|
||||||
moduleSpecifier: string;
|
moduleSpecifier: string;
|
||||||
css: Map<string, { depth: number; order: number }>;
|
css: Map<string, { depth: number; order: number }>;
|
||||||
contentCollectionCss: Map<string, Set<string>>;
|
contentCollectionCss: Map<string, Set<string>>;
|
||||||
|
propagatedScripts: Map<string, Set<string>>;
|
||||||
hoistedScript: { type: 'inline' | 'external'; value: string } | undefined;
|
hoistedScript: { type: 'inline' | 'external'; value: string } | undefined;
|
||||||
}
|
}
|
||||||
export type AllPagesData = Record<ComponentPath, PageBuildData>;
|
export type AllPagesData = Record<ComponentPath, PageBuildData>;
|
||||||
|
|
|
@ -4,13 +4,24 @@ import type { BuildInternals } from '../../core/build/internal.js';
|
||||||
import type { PluginMetadata as AstroPluginMetadata } from '../../vite-plugin-astro/types';
|
import type { PluginMetadata as AstroPluginMetadata } from '../../vite-plugin-astro/types';
|
||||||
|
|
||||||
import { prependForwardSlash } from '../../core/path.js';
|
import { prependForwardSlash } from '../../core/path.js';
|
||||||
import { getTopLevelPages } from './graph.js';
|
import { getTopLevelPages, moduleIsTopLevelPage, walkParentInfos } from './graph.js';
|
||||||
import { getPageDataByViteID, trackClientOnlyPageDatas } from './internal.js';
|
import { getPageDataByViteID, trackClientOnlyPageDatas } from './internal.js';
|
||||||
|
import { PROPAGATED_ASSET_FLAG } from '../../content/consts.js';
|
||||||
|
|
||||||
|
function isPropagatedAsset(id: string) {
|
||||||
|
return new URL('file://' + id).searchParams.has(PROPAGATED_ASSET_FLAG);
|
||||||
|
}
|
||||||
|
|
||||||
export function vitePluginAnalyzer(internals: BuildInternals): VitePlugin {
|
export function vitePluginAnalyzer(internals: BuildInternals): VitePlugin {
|
||||||
function hoistedScriptScanner() {
|
function hoistedScriptScanner() {
|
||||||
const uniqueHoistedIds = new Map<string, string>();
|
const uniqueHoistedIds = new Map<string, string>();
|
||||||
const pageScripts = new Map<string, Set<string>>();
|
const pageScripts = new Map<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
hoistedSet: Set<string>;
|
||||||
|
propagatedMapByImporter: Map<string, Set<string>>;
|
||||||
|
}
|
||||||
|
>();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scan(this: PluginContext, scripts: AstroPluginMetadata['astro']['scripts'], from: string) {
|
scan(this: PluginContext, scripts: AstroPluginMetadata['astro']['scripts'], from: string) {
|
||||||
|
@ -21,13 +32,36 @@ export function vitePluginAnalyzer(internals: BuildInternals): VitePlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hoistedScripts.size) {
|
if (hoistedScripts.size) {
|
||||||
for (const [pageInfo] of getTopLevelPages(from, this)) {
|
for (const [parentInfo] of walkParentInfos(from, this, function until(importer) {
|
||||||
const pageId = pageInfo.id;
|
return isPropagatedAsset(importer);
|
||||||
for (const hid of hoistedScripts) {
|
})) {
|
||||||
if (pageScripts.has(pageId)) {
|
if (isPropagatedAsset(parentInfo.id)) {
|
||||||
pageScripts.get(pageId)?.add(hid);
|
for (const [nestedParentInfo] of walkParentInfos(from, this)) {
|
||||||
} else {
|
if (moduleIsTopLevelPage(nestedParentInfo)) {
|
||||||
pageScripts.set(pageId, new Set([hid]));
|
for (const hid of hoistedScripts) {
|
||||||
|
if (!pageScripts.has(nestedParentInfo.id)) {
|
||||||
|
pageScripts.set(nestedParentInfo.id, {
|
||||||
|
hoistedSet: new Set(),
|
||||||
|
propagatedMapByImporter: new Map(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const entry = pageScripts.get(nestedParentInfo.id)!;
|
||||||
|
if (!entry.propagatedMapByImporter.has(parentInfo.id)) {
|
||||||
|
entry.propagatedMapByImporter.set(parentInfo.id, new Set());
|
||||||
|
}
|
||||||
|
entry.propagatedMapByImporter.get(parentInfo.id)!.add(hid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (moduleIsTopLevelPage(parentInfo)) {
|
||||||
|
for (const hid of hoistedScripts) {
|
||||||
|
if (!pageScripts.has(parentInfo.id)) {
|
||||||
|
pageScripts.set(parentInfo.id, {
|
||||||
|
hoistedSet: new Set(),
|
||||||
|
propagatedMapByImporter: new Map(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pageScripts.get(parentInfo.id)?.hoistedSet.add(hid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,14 +69,14 @@ export function vitePluginAnalyzer(internals: BuildInternals): VitePlugin {
|
||||||
},
|
},
|
||||||
|
|
||||||
finalize() {
|
finalize() {
|
||||||
for (const [pageId, hoistedScripts] of pageScripts) {
|
for (const [pageId, { hoistedSet, propagatedMapByImporter }] of pageScripts) {
|
||||||
const pageData = getPageDataByViteID(internals, pageId);
|
const pageData = getPageDataByViteID(internals, pageId);
|
||||||
if (!pageData) continue;
|
if (!pageData) continue;
|
||||||
|
|
||||||
const { component } = pageData;
|
const { component } = pageData;
|
||||||
const astroModuleId = prependForwardSlash(component);
|
const astroModuleId = prependForwardSlash(component);
|
||||||
|
|
||||||
const uniqueHoistedId = JSON.stringify(Array.from(hoistedScripts).sort());
|
const uniqueHoistedId = JSON.stringify(Array.from(hoistedSet).sort());
|
||||||
let moduleId: string;
|
let moduleId: string;
|
||||||
|
|
||||||
// If we're already tracking this set of hoisted scripts, get the unique id
|
// If we're already tracking this set of hoisted scripts, get the unique id
|
||||||
|
@ -55,13 +89,35 @@ export function vitePluginAnalyzer(internals: BuildInternals): VitePlugin {
|
||||||
}
|
}
|
||||||
internals.discoveredScripts.add(moduleId);
|
internals.discoveredScripts.add(moduleId);
|
||||||
|
|
||||||
|
pageData.propagatedScripts = propagatedMapByImporter;
|
||||||
|
|
||||||
|
// Add propagated scripts to client build,
|
||||||
|
// but DON'T add to pages -> hoisted script map.
|
||||||
|
// const flattenedPropagatedScripts = Array.from(propagatedMapByImporter.values())
|
||||||
|
// .map((s) => Array.from(s))
|
||||||
|
// .flat();
|
||||||
|
// const uniquePropagatedId = JSON.stringify(flattenedPropagatedScripts.sort());
|
||||||
|
// if (uniqueHoistedIds.has(uniquePropagatedId)) {
|
||||||
|
// moduleId = uniqueHoistedIds.get(uniquePropagatedId)!;
|
||||||
|
// } else {
|
||||||
|
// // Otherwise, create a unique id for this set of hoisted scripts
|
||||||
|
// moduleId = `/astro/hoisted.js?q=${uniqueHoistedIds.size}`;
|
||||||
|
// console.log('uniquePropagatedId', uniquePropagatedId, moduleId);
|
||||||
|
// uniqueHoistedIds.set(uniquePropagatedId, moduleId);
|
||||||
|
// }
|
||||||
|
for (const propagatedScripts of propagatedMapByImporter.values()) {
|
||||||
|
for (const propagatedScript of propagatedScripts) {
|
||||||
|
internals.discoveredScripts.add(propagatedScript);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure to track that this page uses this set of hoisted scripts
|
// Make sure to track that this page uses this set of hoisted scripts
|
||||||
if (internals.hoistedScriptIdToPagesMap.has(moduleId)) {
|
if (internals.hoistedScriptIdToPagesMap.has(moduleId)) {
|
||||||
const pages = internals.hoistedScriptIdToPagesMap.get(moduleId);
|
const pages = internals.hoistedScriptIdToPagesMap.get(moduleId);
|
||||||
pages!.add(astroModuleId);
|
pages!.add(astroModuleId);
|
||||||
} else {
|
} else {
|
||||||
internals.hoistedScriptIdToPagesMap.set(moduleId, new Set([astroModuleId]));
|
internals.hoistedScriptIdToPagesMap.set(moduleId, new Set([astroModuleId]));
|
||||||
internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedScripts);
|
internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue