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,
|
||||
createModuleScriptElementWithSrcSet,
|
||||
} 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 resolvedPagesVirtualModuleId = '\0' + pagesVirtualModuleId;
|
||||
|
@ -108,7 +108,7 @@ export class App {
|
|||
throw new Error(`Unable to resolve [${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,
|
||||
routeCache: this.#routeCache,
|
||||
|
|
|
@ -22,6 +22,7 @@ export type SerializedRouteInfo = Omit<RouteInfo, 'routeData'> & {
|
|||
export interface SSRManifest {
|
||||
routes: RouteInfo[];
|
||||
site?: string;
|
||||
base?: string;
|
||||
markdown: MarkdownRenderingOptions;
|
||||
pageMap: Map<ComponentPath, ComponentInstance>;
|
||||
renderers: SSRLoadedRenderer[];
|
||||
|
|
|
@ -219,9 +219,7 @@ async function generatePath(
|
|||
}
|
||||
throw new Error(`Cannot find the built path for ${specifier}`);
|
||||
}
|
||||
const relPath = npath.posix.relative(pathname, '/' + hashedFilePath);
|
||||
const fullyRelativePath = relPath[0] === '.' ? relPath : './' + relPath;
|
||||
return fullyRelativePath;
|
||||
return prependForwardSlash(npath.posix.join(astroConfig.base, hashedFilePath));
|
||||
},
|
||||
request: createRequest({ url, headers: new Headers(), logging, ssr }),
|
||||
route: pageData.route,
|
||||
|
|
|
@ -136,6 +136,7 @@ function buildManifest(
|
|||
const ssrManifest: SerializedSSRManifest = {
|
||||
routes,
|
||||
site: astroConfig.site,
|
||||
base: astroConfig.base,
|
||||
markdown: astroConfig.markdown,
|
||||
pageMap: null as any,
|
||||
renderers: [],
|
||||
|
|
|
@ -22,7 +22,39 @@ describe('Client only components', () => {
|
|||
const script = $script.html();
|
||||
|
||||
// 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 () => {
|
||||
|
|
|
@ -37,6 +37,47 @@ describe('Dynamic components', () => {
|
|||
// 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 '../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…
Reference in a new issue