Support re-exporting astro components containing client components
This commit is contained in:
parent
5d11c6d56f
commit
00a23092b3
20 changed files with 269 additions and 177 deletions
|
@ -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",
|
||||
|
|
36
packages/astro/src/core/build/graph.ts
Normal file
36
packages/astro/src/core/build/graph.ts
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -71,12 +71,8 @@ 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');
|
||||
|
@ -87,14 +83,6 @@ export async function collectPagesData(
|
|||
} 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;
|
||||
}),
|
||||
};
|
||||
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()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>;
|
||||
|
|
104
packages/astro/src/core/build/vite-plugin-analyzer.ts
Normal file
104
packages/astro/src/core/build/vite-plugin-analyzer.ts
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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}`;
|
||||
|
|
|
@ -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.
|
||||
|
|
9
packages/astro/src/vite-plugin-astro/types.ts
Normal file
9
packages/astro/src/vite-plugin-astro/types.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import type { TransformResult } from '@astrojs/compiler';
|
||||
|
||||
export interface PluginMetadata {
|
||||
astro: {
|
||||
hydratedComponents: TransformResult['hydratedComponents'],
|
||||
clientOnlyComponents: TransformResult['clientOnlyComponents'],
|
||||
scripts: TransformResult['scripts']
|
||||
}
|
||||
}
|
|
@ -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');
|
||||
|
|
5
packages/astro/test/fixtures/reexport-astro-containing-client-component/astro.config.mjs
vendored
Normal file
5
packages/astro/test/fixtures/reexport-astro-containing-client-component/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import preact from '@astrojs/preact';
|
||||
|
||||
export default {
|
||||
integrations: [preact()]
|
||||
};
|
7
packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json
vendored
Normal file
7
packages/astro/test/fixtures/reexport-astro-containing-client-component/package.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "@test/reexport-astro-containing-client-component",
|
||||
"dependencies": {
|
||||
"astro": "workspace:",
|
||||
"@astrojs/preact": "workspace:"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
import {One} from './One.jsx';
|
||||
---
|
||||
<One client:load />
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
export function One() {
|
||||
return (
|
||||
<div>testing</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export { default as One } from './One.astro';
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
import { One as OneWrapper } from '../components/One';
|
||||
---
|
||||
<html>
|
||||
<head><title>Testing</title></head>
|
||||
<body>
|
||||
<OneWrapper client:load />
|
||||
</body>
|
||||
</html>
|
|
@ -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');
|
||||
});
|
||||
});
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue