aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar unknown <matthew@skypack.dev> 2022-06-17 10:38:27 -0400
committerGravatar unknown <matthew@skypack.dev> 2022-06-17 10:38:27 -0400
commit00a23092b3be413affb28ab798392db18a3ac167 (patch)
tree7233b1104e0b4a56f8b42da30e0f8d08a2a4db1b
parent5d11c6d56f3ffcf5bcdaff22f116a4241bbdff4c (diff)
downloadastro-00a23092b3be413affb28ab798392db18a3ac167.tar.gz
astro-00a23092b3be413affb28ab798392db18a3ac167.tar.zst
astro-00a23092b3be413affb28ab798392db18a3ac167.zip
Support re-exporting astro components containing client components
Diffstat (limited to '')
-rw-r--r--packages/astro/package.json2
-rw-r--r--packages/astro/src/core/build/graph.ts36
-rw-r--r--packages/astro/src/core/build/index.ts12
-rw-r--r--packages/astro/src/core/build/internal.ts20
-rw-r--r--packages/astro/src/core/build/page-data.ts41
-rw-r--r--packages/astro/src/core/build/static-build.ts73
-rw-r--r--packages/astro/src/core/build/types.ts2
-rw-r--r--packages/astro/src/core/build/vite-plugin-analyzer.ts104
-rw-r--r--packages/astro/src/runtime/server/metadata.ts34
-rw-r--r--packages/astro/src/vite-plugin-astro/index.ts8
-rw-r--r--packages/astro/src/vite-plugin-astro/types.ts9
-rw-r--r--packages/astro/src/vite-plugin-build-css/index.ts35
-rw-r--r--packages/astro/test/fixtures/reexport-astro-containing-client-component/astro.config.mjs5
-rw-r--r--packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json7
-rw-r--r--packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/One.astro4
-rw-r--r--packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/One.jsx6
-rw-r--r--packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/index.js1
-rw-r--r--packages/astro/test/fixtures/reexport-astro-containing-client-component/src/pages/index.astro9
-rw-r--r--packages/astro/test/reexport-astro-containing-client-component.test.js19
-rw-r--r--pnpm-lock.yaml19
20 files changed, 269 insertions, 177 deletions
diff --git a/packages/astro/package.json b/packages/astro/package.json
index 1c1e48c3f..9ca01afeb 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -78,7 +78,7 @@
"test:e2e:match": "playwright test -g"
},
"dependencies": {
- "@astrojs/compiler": "^0.15.2",
+ "@astrojs/compiler": "metadata-preview",
"@astrojs/language-server": "^0.13.4",
"@astrojs/markdown-remark": "^0.11.2",
"@astrojs/prism": "0.4.1",
diff --git a/packages/astro/src/core/build/graph.ts b/packages/astro/src/core/build/graph.ts
new file mode 100644
index 000000000..e1b0b62b7
--- /dev/null
+++ b/packages/astro/src/core/build/graph.ts
@@ -0,0 +1,36 @@
+import type { GetModuleInfo, ModuleInfo, OutputChunk } from 'rollup';
+import { resolvedPagesVirtualModuleId } from '../app/index.js';
+
+// This walks up the dependency graph and yields out each ModuleInfo object.
+export function* walkParentInfos(
+ id: string,
+ ctx: { getModuleInfo: GetModuleInfo },
+ seen = new Set<string>()
+): Generator<ModuleInfo, void, unknown> {
+ seen.add(id);
+ const info = ctx.getModuleInfo(id);
+ if (info) {
+ yield info;
+ }
+ const importers = (info?.importers || []).concat(info?.dynamicImporters || []);
+ for (const imp of importers) {
+ if (seen.has(imp)) {
+ continue;
+ }
+ yield* walkParentInfos(imp, ctx, seen);
+ }
+}
+
+// This function walks the dependency graph, going up until it finds a page component.
+// This could be a .astro page or a .md page.
+export function* getTopLevelPages(
+ id: string,
+ ctx: { getModuleInfo: GetModuleInfo }
+): Generator<string, void, unknown> {
+ for (const info of walkParentInfos(id, ctx)) {
+ const importers = (info?.importers || []).concat(info?.dynamicImporters || []);
+ if (importers.length <= 2 && importers[0] === resolvedPagesVirtualModuleId) {
+ yield info.id;
+ }
+ }
+}
diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts
index 70ca80160..137c1e7a9 100644
--- a/packages/astro/src/core/build/index.ts
+++ b/packages/astro/src/core/build/index.ts
@@ -114,18 +114,6 @@ class AstroBuilder {
ssr: isBuildingToSSR(this.config),
});
- // Filter pages by using conditions based on their frontmatter.
- Object.entries(allPages).forEach(([page, data]) => {
- if ('frontmatter' in data.preload[1]) {
- // TODO: add better type inference to data.preload[1]
- const frontmatter = (data.preload[1] as any).frontmatter;
- if (Boolean(frontmatter.draft) && !this.config.markdown.drafts) {
- debug('build', timerMessage(`Skipping draft page ${page}`, this.timer.loadStart));
- delete allPages[page];
- }
- }
- });
-
debug('build', timerMessage('All pages loaded', this.timer.loadStart));
// The names of each pages
diff --git a/packages/astro/src/core/build/internal.ts b/packages/astro/src/core/build/internal.ts
index ad838fac8..3be0c6d8f 100644
--- a/packages/astro/src/core/build/internal.ts
+++ b/packages/astro/src/core/build/internal.ts
@@ -31,6 +31,22 @@ export interface BuildInternals {
* A map for page-specific information by a client:only component
*/
pagesByClientOnly: Map<string, Set<PageBuildData>>;
+
+ /**
+ * A list of hydrated components that are discovered during the SSR build
+ * These will be used as the top-level entrypoints for the client build.
+ */
+ discoveredHydratedComponents: Set<string>;
+ /**
+ * A list of client:only components that are discovered during the SSR build
+ * These will be used as the top-level entrypoints for the client build.
+ */
+ discoveredClientOnlyComponents: Set<string>;
+ /**
+ * A list of hoisted scripts that are discovered during the SSR build
+ * These will be used as the top-level entrypoints for the client build.
+ */
+ discoveredScripts: Set<string>;
}
/**
@@ -64,6 +80,10 @@ export function createBuildInternals(): BuildInternals {
pagesByComponent: new Map(),
pagesByViteID: new Map(),
pagesByClientOnly: new Map(),
+
+ discoveredHydratedComponents: new Set(),
+ discoveredClientOnlyComponents: new Set(),
+ discoveredScripts: new Set(),
};
}
diff --git a/packages/astro/src/core/build/page-data.ts b/packages/astro/src/core/build/page-data.ts
index ebbe50a51..371b7bd26 100644
--- a/packages/astro/src/core/build/page-data.ts
+++ b/packages/astro/src/core/build/page-data.ts
@@ -71,30 +71,18 @@ export async function collectPagesData(
css: new Set(),
hoistedScript: undefined,
scripts: new Set(),
- preload: await ssrPreload({
- astroConfig,
- filePath: new URL(`./${route.component}`, astroConfig.root),
- viteServer,
- })
- .then((routes) => {
- clearInterval(routeCollectionLogTimeout);
- if (buildMode === 'static') {
- const html = `${route.pathname}`.replace(/\/?$/, '/index.html');
- debug(
- 'build',
- `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.yellow(html)}`
- );
- } else {
- debug('build', `├── ${colors.bold(colors.green('✔'))} ${route.component}`);
- }
- return routes;
- })
- .catch((err) => {
- clearInterval(routeCollectionLogTimeout);
- debug('build', `├── ${colors.bold(colors.red('✘'))} ${route.component}`);
- throw err;
- }),
};
+
+ clearInterval(routeCollectionLogTimeout);
+ if (buildMode === 'static') {
+ const html = `${route.pathname}`.replace(/\/?$/, '/index.html');
+ debug(
+ 'build',
+ `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.yellow(html)}`
+ );
+ } else {
+ debug('build', `├── ${colors.bold(colors.green('✔'))} ${route.component}`);
+ }
continue;
}
// dynamic route:
@@ -144,12 +132,7 @@ export async function collectPagesData(
moduleSpecifier: '',
css: new Set(),
hoistedScript: undefined,
- scripts: new Set(),
- preload: await ssrPreload({
- astroConfig,
- filePath: new URL(`./${route.component}`, astroConfig.root),
- viteServer,
- }),
+ scripts: new Set()
};
}
diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts
index c242c98b3..3bcc5f0f9 100644
--- a/packages/astro/src/core/build/static-build.ts
+++ b/packages/astro/src/core/build/static-build.ts
@@ -24,6 +24,7 @@ import { vitePluginHoistedScripts } from './vite-plugin-hoisted-scripts.js';
import { vitePluginInternals } from './vite-plugin-internals.js';
import { vitePluginPages } from './vite-plugin-pages.js';
import { vitePluginSSR } from './vite-plugin-ssr.js';
+import { vitePluginAnalyzer } from './vite-plugin-analyzer.js';
export async function staticBuild(opts: StaticBuildOptions) {
const { allPages, astroConfig } = opts;
@@ -31,16 +32,12 @@ export async function staticBuild(opts: StaticBuildOptions) {
// The pages to be built for rendering purposes.
const pageInput = new Set<string>();
- // The JavaScript entrypoints.
- const jsInput = new Set<string>();
-
// A map of each page .astro file, to the PageBuildData which contains information
// about that page, such as its paths.
const facadeIdToPageDataMap = new Map<string, PageBuildData>();
// Build internals needed by the CSS plugin
const internals = createBuildInternals();
- const uniqueHoistedIds = new Map<string, string>();
const timer: Record<string, number> = {};
@@ -53,58 +50,6 @@ export async function staticBuild(opts: StaticBuildOptions) {
// Track the page data in internals
trackPageData(internals, component, pageData, astroModuleId, astroModuleURL);
- if (pageData.route.type === 'page') {
- const [renderers, mod] = pageData.preload;
- const metadata = mod.$$metadata;
-
- // Track client:only usage so we can map their CSS back to the Page they are used in.
- const clientOnlys = Array.from(metadata.clientOnlyComponentPaths());
- trackClientOnlyPageDatas(internals, pageData, clientOnlys);
-
- const topLevelImports = new Set([
- // Any component that gets hydrated
- // 'components/Counter.jsx'
- // { 'components/Counter.jsx': 'counter.hash.js' }
- ...metadata.hydratedComponentPaths(),
- // Client-only components
- ...clientOnlys,
- // The client path for each renderer
- ...renderers
- .filter((renderer) => !!renderer.clientEntrypoint)
- .map((renderer) => renderer.clientEntrypoint!),
- ]);
-
- // Add hoisted scripts
- const hoistedScripts = new Set(metadata.hoistedScriptPaths());
- if (hoistedScripts.size) {
- const uniqueHoistedId = JSON.stringify(Array.from(hoistedScripts).sort());
- let moduleId: string;
-
- // If we're already tracking this set of hoisted scripts, get the unique id
- if (uniqueHoistedIds.has(uniqueHoistedId)) {
- moduleId = uniqueHoistedIds.get(uniqueHoistedId)!;
- } else {
- // Otherwise, create a unique id for this set of hoisted scripts
- moduleId = `/astro/hoisted.js?q=${uniqueHoistedIds.size}`;
- uniqueHoistedIds.set(uniqueHoistedId, moduleId);
- }
- topLevelImports.add(moduleId);
-
- // Make sure to track that this page uses this set of hoisted scripts
- if (internals.hoistedScriptIdToPagesMap.has(moduleId)) {
- const pages = internals.hoistedScriptIdToPagesMap.get(moduleId);
- pages!.add(astroModuleId);
- } else {
- internals.hoistedScriptIdToPagesMap.set(moduleId, new Set([astroModuleId]));
- internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedScripts);
- }
- }
-
- for (const specifier of topLevelImports) {
- jsInput.add(specifier);
- }
- }
-
pageInput.add(astroModuleId);
facadeIdToPageDataMap.set(fileURLToPath(astroModuleURL), pageData);
}
@@ -114,10 +59,6 @@ export async function staticBuild(opts: StaticBuildOptions) {
// condition, so we are doing it ourselves
emptyDir(astroConfig.outDir, new Set('.git'));
- timer.clientBuild = performance.now();
- // Run client build first, so the assets can be fed into the SSR rendered version.
- await clientBuild(opts, internals, jsInput);
-
// Build your project (SSR application code, assets, client JS, etc.)
timer.ssr = performance.now();
info(
@@ -130,6 +71,17 @@ export async function staticBuild(opts: StaticBuildOptions) {
const ssrResult = (await ssrBuild(opts, internals, pageInput)) as RollupOutput;
info(opts.logging, 'build', dim(`Completed in ${getTimeStat(timer.ssr, performance.now())}.`));
+ const clientInput = new Set<string>([
+ ...internals.discoveredHydratedComponents,
+ ...internals.discoveredClientOnlyComponents,
+ ...astroConfig._ctx.renderers.map(r => r.clientEntrypoint).filter(a => a) as string[],
+ ...internals.discoveredScripts,
+ ]);
+
+ // Run client build first, so the assets can be fed into the SSR rendered version.
+ timer.clientBuild = performance.now();
+ await clientBuild(opts, internals, clientInput);
+
timer.generate = performance.now();
if (opts.buildConfig.staticMode) {
try {
@@ -190,6 +142,7 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
// SSR needs to be last
isBuildingToSSR(opts.astroConfig) &&
vitePluginSSR(opts, internals, opts.astroConfig._ctx.adapter!),
+ vitePluginAnalyzer(opts.astroConfig, internals)
],
publicDir: ssr ? false : viteConfig.publicDir,
root: viteConfig.root,
diff --git a/packages/astro/src/core/build/types.ts b/packages/astro/src/core/build/types.ts
index 980d3a170..0d018be7d 100644
--- a/packages/astro/src/core/build/types.ts
+++ b/packages/astro/src/core/build/types.ts
@@ -8,7 +8,6 @@ import type {
} from '../../@types/astro';
import type { ViteConfigWithSSR } from '../create-vite';
import type { LogOptions } from '../logger/core';
-import type { ComponentPreload } from '../render/dev/index';
import type { RouteCache } from '../render/route-cache';
export type ComponentPath = string;
@@ -17,7 +16,6 @@ export type ViteID = string;
export interface PageBuildData {
component: ComponentPath;
paths: string[];
- preload: ComponentPreload;
route: RouteData;
moduleSpecifier: string;
css: Set<string>;
diff --git a/packages/astro/src/core/build/vite-plugin-analyzer.ts b/packages/astro/src/core/build/vite-plugin-analyzer.ts
new file mode 100644
index 000000000..cc0fbae1d
--- /dev/null
+++ b/packages/astro/src/core/build/vite-plugin-analyzer.ts
@@ -0,0 +1,104 @@
+
+
+import type { Plugin as VitePlugin } from 'vite';
+import type { PluginContext } from 'rollup';
+import type { AstroConfig } from '../../@types/astro';
+import type { BuildInternals } from '../../core/build/internal.js';
+import type { PluginMetadata as AstroPluginMetadata } from '../../vite-plugin-astro/types';
+
+import { prependForwardSlash } from '../../core/path.js';
+import { getPageDataByViteID, trackClientOnlyPageDatas } from './internal.js';
+import { getTopLevelPages } from './graph.js';
+
+
+export function vitePluginAnalyzer(
+ astroConfig: AstroConfig,
+ internals: BuildInternals
+): VitePlugin {
+
+ function hoistedScriptScanner() {
+ const uniqueHoistedIds = new Map<string, string>();
+ return function(
+ this: PluginContext,
+ scripts: AstroPluginMetadata['astro']['scripts'],
+ from: string
+ ) {
+ const hoistedScripts = new Set<string>();
+ for(let i = 0; i < scripts.length; i++) {
+ const hid = `${from.replace('/@fs', '')}?astro&type=script&index=${i}`;
+ hoistedScripts.add(hid);
+ }
+
+ for(const pageId of getTopLevelPages(from, this)) {
+ const pageData = getPageDataByViteID(internals, pageId);
+ if(!pageData) continue;
+
+ const { component } = pageData;
+ const astroModuleId = prependForwardSlash(component);
+
+ if (hoistedScripts.size) {
+ const uniqueHoistedId = JSON.stringify(Array.from(hoistedScripts).sort());
+ let moduleId: string;
+
+ // If we're already tracking this set of hoisted scripts, get the unique id
+ if (uniqueHoistedIds.has(uniqueHoistedId)) {
+ moduleId = uniqueHoistedIds.get(uniqueHoistedId)!;
+ } else {
+ // Otherwise, create a unique id for this set of hoisted scripts
+ moduleId = `/astro/hoisted.js?q=${uniqueHoistedIds.size}`;
+ uniqueHoistedIds.set(uniqueHoistedId, moduleId);
+ }
+ internals.discoveredScripts.add(moduleId);
+
+ // Make sure to track that this page uses this set of hoisted scripts
+ if (internals.hoistedScriptIdToPagesMap.has(moduleId)) {
+ const pages = internals.hoistedScriptIdToPagesMap.get(moduleId);
+ pages!.add(astroModuleId);
+ } else {
+ internals.hoistedScriptIdToPagesMap.set(moduleId, new Set([astroModuleId]));
+ internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedScripts);
+ }
+ }
+ }
+ }
+ }
+
+ return {
+ name: '@astro/rollup-plugin-astro-analyzer',
+ generateBundle() {
+ const scanHoisted = hoistedScriptScanner();
+
+ const ids = this.getModuleIds();
+ for(const id of ids) {
+ const info = this.getModuleInfo(id);
+ if(!info || !info.meta?.astro) continue;
+
+ const astro = info.meta.astro as AstroPluginMetadata['astro'];
+
+ for(const c of astro.hydratedComponents) {
+ internals.discoveredHydratedComponents.add(c.resolvedPath || c.specifier);
+ }
+
+ // Scan hoisted scripts
+ scanHoisted.call(this, astro.scripts, id);
+
+ if(astro.clientOnlyComponents.length) {
+ const clientOnlys: string[] = [];
+
+ for(const c of astro.clientOnlyComponents) {
+ const cid = c.resolvedPath || c.specifier;
+ internals.discoveredClientOnlyComponents.add(cid);
+ clientOnlys.push(cid);
+ }
+
+ for(const pageId of getTopLevelPages(id, this)) {
+ const pageData = getPageDataByViteID(internals, pageId);
+ if(!pageData) continue;
+
+ trackClientOnlyPageDatas(internals, pageData, clientOnlys);
+ }
+ }
+ }
+ }
+ };
+}
diff --git a/packages/astro/src/runtime/server/metadata.ts b/packages/astro/src/runtime/server/metadata.ts
index 548d2bb7d..11adeb4ea 100644
--- a/packages/astro/src/runtime/server/metadata.ts
+++ b/packages/astro/src/runtime/server/metadata.ts
@@ -50,40 +50,10 @@ export class Metadata {
return metadata?.componentExport || null;
}
- /**
- * Gets the paths of all hydrated components within this component
- * and children components.
- */
- *hydratedComponentPaths() {
- const found = new Set<string>();
- for (const metadata of this.deepMetadata()) {
- for (const component of metadata.hydratedComponents) {
- const path = metadata.getPath(component);
- if (path && !found.has(path)) {
- found.add(path);
- yield path;
- }
- }
- }
- }
-
- *clientOnlyComponentPaths() {
- const found = new Set<string>();
- for (const metadata of this.deepMetadata()) {
- for (const component of metadata.clientOnlyComponents) {
- const path = metadata.resolvePath(component);
- if (path && !found.has(path)) {
- found.add(path);
- yield path;
- }
- }
- }
- }
-
*hoistedScriptPaths() {
for (const metadata of this.deepMetadata()) {
- let i = 0,
- pathname = metadata.mockURL.pathname;
+ let i = 0, pathname = metadata.mockURL.pathname;
+
while (i < metadata.hoisted.length) {
// Strip off the leading "/@fs" added during compilation.
yield `${pathname.replace('/@fs', '')}?astro&type=script&index=${i}`;
diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts
index 4823b6839..3b957d5d5 100644
--- a/packages/astro/src/vite-plugin-astro/index.ts
+++ b/packages/astro/src/vite-plugin-astro/index.ts
@@ -2,6 +2,7 @@ import type { PluginContext } from 'rollup';
import type * as vite from 'vite';
import type { AstroConfig } from '../@types/astro';
import type { LogOptions } from '../core/logger/core.js';
+import type { PluginMetadata as AstroPluginMetadata } from './types';
import ancestor from 'common-ancestor-path';
import esbuild from 'esbuild';
@@ -217,10 +218,17 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
SUFFIX += `\nimport "${PAGE_SSR_SCRIPT_ID}";`;
}
+ const astroMetadata: AstroPluginMetadata['astro'] = {
+ clientOnlyComponents: transformResult.clientOnlyComponents,
+ hydratedComponents: transformResult.hydratedComponents,
+ scripts: transformResult.scripts
+ };
+
return {
code: `${code}${SUFFIX}`,
map,
meta: {
+ astro: astroMetadata,
vite: {
// Setting this vite metadata to `ts` causes Vite to resolve .js
// extensions to .ts files.
diff --git a/packages/astro/src/vite-plugin-astro/types.ts b/packages/astro/src/vite-plugin-astro/types.ts
new file mode 100644
index 000000000..6537b6f38
--- /dev/null
+++ b/packages/astro/src/vite-plugin-astro/types.ts
@@ -0,0 +1,9 @@
+import type { TransformResult } from '@astrojs/compiler';
+
+export interface PluginMetadata {
+ astro: {
+ hydratedComponents: TransformResult['hydratedComponents'],
+ clientOnlyComponents: TransformResult['clientOnlyComponents'],
+ scripts: TransformResult['scripts']
+ }
+}
diff --git a/packages/astro/src/vite-plugin-build-css/index.ts b/packages/astro/src/vite-plugin-build-css/index.ts
index 6d9861d07..46fcdecff 100644
--- a/packages/astro/src/vite-plugin-build-css/index.ts
+++ b/packages/astro/src/vite-plugin-build-css/index.ts
@@ -7,6 +7,7 @@ import esbuild from 'esbuild';
import { Plugin as VitePlugin } from 'vite';
import { resolvedPagesVirtualModuleId } from '../core/app/index.js';
import { getPageDataByViteID, getPageDatasByClientOnlyID } from '../core/build/internal.js';
+import { getTopLevelPages, walkParentInfos } from '../core/build/graph.js';
import { isCSSRequest } from '../core/render/util.js';
interface PluginOptions {
@@ -17,40 +18,6 @@ interface PluginOptions {
export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
const { internals } = options;
- // This walks up the dependency graph and yields out each ModuleInfo object.
- function* walkParentInfos(
- id: string,
- ctx: { getModuleInfo: GetModuleInfo },
- seen = new Set<string>()
- ): Generator<ModuleInfo, void, unknown> {
- seen.add(id);
- const info = ctx.getModuleInfo(id);
- if (info) {
- yield info;
- }
- const importers = (info?.importers || []).concat(info?.dynamicImporters || []);
- for (const imp of importers) {
- if (seen.has(imp)) {
- continue;
- }
- yield* walkParentInfos(imp, ctx, seen);
- }
- }
-
- // This function walks the dependency graph, going up until it finds a page component.
- // This could be a .astro page or a .md page.
- function* getTopLevelPages(
- id: string,
- ctx: { getModuleInfo: GetModuleInfo }
- ): Generator<string, void, unknown> {
- for (const info of walkParentInfos(id, ctx)) {
- const importers = (info?.importers || []).concat(info?.dynamicImporters || []);
- if (importers.length <= 2 && importers[0] === resolvedPagesVirtualModuleId) {
- yield info.id;
- }
- }
- }
-
function createHashOfPageParents(id: string, ctx: { getModuleInfo: GetModuleInfo }): string {
const parents = Array.from(getTopLevelPages(id, ctx)).sort();
const hash = crypto.createHash('sha256');
diff --git a/packages/astro/test/fixtures/reexport-astro-containing-client-component/astro.config.mjs b/packages/astro/test/fixtures/reexport-astro-containing-client-component/astro.config.mjs
new file mode 100644
index 000000000..c9662ed09
--- /dev/null
+++ b/packages/astro/test/fixtures/reexport-astro-containing-client-component/astro.config.mjs
@@ -0,0 +1,5 @@
+import preact from '@astrojs/preact';
+
+export default {
+ integrations: [preact()]
+};
diff --git a/packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json b/packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json
new file mode 100644
index 000000000..13a0cd46c
--- /dev/null
+++ b/packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "@test/reexport-astro-containing-client-component",
+ "dependencies": {
+ "astro": "workspace:",
+ "@astrojs/preact": "workspace:"
+ }
+}
diff --git a/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/One.astro b/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/One.astro
new file mode 100644
index 000000000..3e86bf020
--- /dev/null
+++ b/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/One.astro
@@ -0,0 +1,4 @@
+---
+import {One} from './One.jsx';
+---
+<One client:load />
diff --git a/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/One.jsx b/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/One.jsx
new file mode 100644
index 000000000..cb23a337e
--- /dev/null
+++ b/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/One.jsx
@@ -0,0 +1,6 @@
+
+export function One() {
+ return (
+ <div>testing</div>
+ );
+}
diff --git a/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/index.js b/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/index.js
new file mode 100644
index 000000000..a239385d7
--- /dev/null
+++ b/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/components/One/index.js
@@ -0,0 +1 @@
+export { default as One } from './One.astro';
diff --git a/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/pages/index.astro b/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/pages/index.astro
new file mode 100644
index 000000000..5ed54c3b8
--- /dev/null
+++ b/packages/astro/test/fixtures/reexport-astro-containing-client-component/src/pages/index.astro
@@ -0,0 +1,9 @@
+---
+import { One as OneWrapper } from '../components/One';
+---
+<html>
+<head><title>Testing</title></head>
+<body>
+ <OneWrapper client:load />
+</body>
+</html>
diff --git a/packages/astro/test/reexport-astro-containing-client-component.test.js b/packages/astro/test/reexport-astro-containing-client-component.test.js
new file mode 100644
index 000000000..8b37e8180
--- /dev/null
+++ b/packages/astro/test/reexport-astro-containing-client-component.test.js
@@ -0,0 +1,19 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+
+describe('Re-exported astro components with client components', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({ root: './fixtures/reexport-astro-containing-client-component/' });
+ await fixture.build();
+ });
+
+ it('Is able to build and renders and stuff', async () => {
+ const html = await fixture.readFile('/index.html');
+ const $ = cheerio.load(html);
+ expect($('astro-island').length).to.equal(1);
+ expect($('astro-island').attr('component-export')).to.equal('One');
+ });
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 50e86253c..3c5e64a98 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -461,7 +461,7 @@ importers:
packages/astro:
specifiers:
- '@astrojs/compiler': ^0.15.2
+ '@astrojs/compiler': metadata-preview
'@astrojs/language-server': ^0.13.4
'@astrojs/markdown-remark': ^0.11.2
'@astrojs/prism': 0.4.1
@@ -545,7 +545,7 @@ importers:
yargs-parser: ^21.0.1
zod: ^3.17.3
dependencies:
- '@astrojs/compiler': 0.15.2
+ '@astrojs/compiler': 0.16.0-metadata-preview
'@astrojs/language-server': 0.13.4
'@astrojs/markdown-remark': link:../markdown/remark
'@astrojs/prism': link:../astro-prism
@@ -1454,6 +1454,14 @@ importers:
react-dom: 18.1.0_react@18.1.0
vue: 3.2.37
+ packages/astro/test/fixtures/reexport-astro-containing-client-component:
+ specifiers:
+ '@astrojs/preact': 'workspace:'
+ astro: 'workspace:'
+ dependencies:
+ '@astrojs/preact': link:../../../../integrations/preact
+ astro: link:../../..
+
packages/astro/test/fixtures/remote-css:
specifiers:
astro: workspace:*
@@ -2302,11 +2310,8 @@ packages:
leven: 3.1.0
dev: true
- /@astrojs/compiler/0.15.2:
- resolution: {integrity: sha512-YsxIyx026zPWbxv3wYrudr1jh8u6oSnhP6MW+9OAgiFuICHjSX4Rw+qm8wJj1D5IkJ3HsDtE+kFMMYIozZ5bvQ==}
- dependencies:
- tsm: 2.2.1
- uvu: 0.5.3
+ /@astrojs/compiler/0.16.0-metadata-preview:
+ resolution: {integrity: sha512-fFUcDSqK06DMGR6+C/YkhrKeNtQx2hgymrI7SqhoR9okOAFf4ckqZ0i7tvd5Mb8F9bhBwVN61kOwv2wpsitRcQ==}
dev: false
/@astrojs/language-server/0.13.4: