mirror of
https://github.com/withastro/astro.git
synced 2025-01-27 22:19:04 -05:00
Updates hydration scripts to use absolute paths (#3422)
* WIP: proof of concept fix to use absolute paths * correct fix to handle absolute paths and config.base * adding tests for hydration scripts with config.base * chore: add changeset * fix: ensure posix paths are used for Windows compat
This commit is contained in:
parent
28ede84a88
commit
0209d6276c
7 changed files with 85 additions and 7 deletions
5
.changeset/wet-beds-act.md
Normal file
5
.changeset/wet-beds-act.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Updates component hydration scripts to use absolute paths for script imports
|
|
@ -18,7 +18,7 @@ import {
|
||||||
createLinkStylesheetElementSet,
|
createLinkStylesheetElementSet,
|
||||||
createModuleScriptElementWithSrcSet,
|
createModuleScriptElementWithSrcSet,
|
||||||
} from '../render/ssr-element.js';
|
} from '../render/ssr-element.js';
|
||||||
import { prependForwardSlash } from '../path.js';
|
import { joinPaths, prependForwardSlash } from '../path.js';
|
||||||
|
|
||||||
export const pagesVirtualModuleId = '@astrojs-pages-virtual-entry';
|
export const pagesVirtualModuleId = '@astrojs-pages-virtual-entry';
|
||||||
export const resolvedPagesVirtualModuleId = '\0' + pagesVirtualModuleId;
|
export const resolvedPagesVirtualModuleId = '\0' + pagesVirtualModuleId;
|
||||||
|
@ -108,7 +108,7 @@ export class App {
|
||||||
throw new Error(`Unable to resolve [${specifier}]`);
|
throw new Error(`Unable to resolve [${specifier}]`);
|
||||||
}
|
}
|
||||||
const bundlePath = manifest.entryModules[specifier];
|
const bundlePath = manifest.entryModules[specifier];
|
||||||
return bundlePath.startsWith('data:') ? bundlePath : prependForwardSlash(bundlePath);
|
return bundlePath.startsWith('data:') ? bundlePath : prependForwardSlash(joinPaths(manifest.base, bundlePath));
|
||||||
},
|
},
|
||||||
route: routeData,
|
route: routeData,
|
||||||
routeCache: this.#routeCache,
|
routeCache: this.#routeCache,
|
||||||
|
|
|
@ -22,6 +22,7 @@ export type SerializedRouteInfo = Omit<RouteInfo, 'routeData'> & {
|
||||||
export interface SSRManifest {
|
export interface SSRManifest {
|
||||||
routes: RouteInfo[];
|
routes: RouteInfo[];
|
||||||
site?: string;
|
site?: string;
|
||||||
|
base?: string;
|
||||||
markdown: MarkdownRenderingOptions;
|
markdown: MarkdownRenderingOptions;
|
||||||
pageMap: Map<ComponentPath, ComponentInstance>;
|
pageMap: Map<ComponentPath, ComponentInstance>;
|
||||||
renderers: SSRLoadedRenderer[];
|
renderers: SSRLoadedRenderer[];
|
||||||
|
|
|
@ -219,9 +219,7 @@ async function generatePath(
|
||||||
}
|
}
|
||||||
throw new Error(`Cannot find the built path for ${specifier}`);
|
throw new Error(`Cannot find the built path for ${specifier}`);
|
||||||
}
|
}
|
||||||
const relPath = npath.posix.relative(pathname, '/' + hashedFilePath);
|
return prependForwardSlash(npath.posix.join(astroConfig.base, hashedFilePath));
|
||||||
const fullyRelativePath = relPath[0] === '.' ? relPath : './' + relPath;
|
|
||||||
return fullyRelativePath;
|
|
||||||
},
|
},
|
||||||
request: createRequest({ url, headers: new Headers(), logging, ssr }),
|
request: createRequest({ url, headers: new Headers(), logging, ssr }),
|
||||||
route: pageData.route,
|
route: pageData.route,
|
||||||
|
|
|
@ -136,6 +136,7 @@ function buildManifest(
|
||||||
const ssrManifest: SerializedSSRManifest = {
|
const ssrManifest: SerializedSSRManifest = {
|
||||||
routes,
|
routes,
|
||||||
site: astroConfig.site,
|
site: astroConfig.site,
|
||||||
|
base: astroConfig.base,
|
||||||
markdown: astroConfig.markdown,
|
markdown: astroConfig.markdown,
|
||||||
pageMap: null as any,
|
pageMap: null as any,
|
||||||
renderers: [],
|
renderers: [],
|
||||||
|
|
|
@ -22,7 +22,39 @@ describe('Client only components', () => {
|
||||||
const script = $script.html();
|
const script = $script.html();
|
||||||
|
|
||||||
// test 2: svelte renderer is on the page
|
// test 2: svelte renderer is on the page
|
||||||
expect(/import\(".\/entry.*/g.test(script)).to.be.ok;
|
expect(/import\("\/entry.*/g.test(script)).to.be.ok;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds the CSS to the page', async () => {
|
||||||
|
const html = await fixture.readFile('/index.html');
|
||||||
|
const $ = cheerioLoad(html);
|
||||||
|
expect($('link[rel=stylesheet]')).to.have.lengthOf(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Client only components subpath', () => {
|
||||||
|
let fixture;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
fixture = await loadFixture({
|
||||||
|
site: 'https://site.com',
|
||||||
|
base: '/blog',
|
||||||
|
root: './fixtures/astro-client-only/',
|
||||||
|
});
|
||||||
|
await fixture.build();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Loads pages using client:only hydrator', async () => {
|
||||||
|
const html = await fixture.readFile('/index.html');
|
||||||
|
const $ = cheerioLoad(html);
|
||||||
|
|
||||||
|
// test 1: <astro-root> is empty
|
||||||
|
expect($('astro-root').html()).to.equal('');
|
||||||
|
const $script = $('script');
|
||||||
|
const script = $script.html();
|
||||||
|
|
||||||
|
// test 2: svelte renderer is on the page
|
||||||
|
expect(/import\("\/blog\/entry.*/g.test(script)).to.be.ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Adds the CSS to the page', async () => {
|
it('Adds the CSS to the page', async () => {
|
||||||
|
|
|
@ -37,6 +37,47 @@ describe('Dynamic components', () => {
|
||||||
// test 2: correct script is being loaded.
|
// test 2: correct script is being loaded.
|
||||||
// because of bundling, we don't have access to the source import,
|
// because of bundling, we don't have access to the source import,
|
||||||
// only the bundled import.
|
// only the bundled import.
|
||||||
expect($('script').html()).to.include(`import setup from '../entry`);
|
expect($('script').html()).to.include(`import setup from '/entry`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Dynamic components subpath', () => {
|
||||||
|
let fixture;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
fixture = await loadFixture({
|
||||||
|
site: 'https://site.com',
|
||||||
|
base: '/blog',
|
||||||
|
root: './fixtures/astro-dynamic/',
|
||||||
|
});
|
||||||
|
await fixture.build();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Loads packages that only run code in client', async () => {
|
||||||
|
const html = await fixture.readFile('/index.html');
|
||||||
|
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
expect($('script').length).to.eq(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Loads pages using client:media hydrator', async () => {
|
||||||
|
const root = new URL('http://example.com/media/index.html');
|
||||||
|
const html = await fixture.readFile('/media/index.html');
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
|
||||||
|
// test 1: static value rendered
|
||||||
|
expect($('script').length).to.equal(2); // One for each
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Loads pages using client:only hydrator', async () => {
|
||||||
|
const html = await fixture.readFile('/client-only/index.html');
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
|
||||||
|
// test 1: <astro-root> is empty.
|
||||||
|
expect($('<astro-root>').html()).to.equal('');
|
||||||
|
// test 2: correct script is being loaded.
|
||||||
|
// because of bundling, we don't have access to the source import,
|
||||||
|
// only the bundled import.
|
||||||
|
expect($('script').html()).to.include(`import setup from '/blog/entry`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue