Fix a regression in vite.build() base option (#2502)
* Fixes subpath bugs * Remove trailing slash appending Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
parent
4e43ae5d76
commit
f3dafd33e7
3 changed files with 46 additions and 20 deletions
|
@ -14,7 +14,7 @@ import { fileURLToPath } from 'url';
|
||||||
import glob from 'fast-glob';
|
import glob from 'fast-glob';
|
||||||
import vite from '../vite.js';
|
import vite from '../vite.js';
|
||||||
import { debug, error } from '../../core/logger.js';
|
import { debug, error } from '../../core/logger.js';
|
||||||
import { prependForwardSlash } from '../../core/path.js';
|
import { prependForwardSlash, appendForwardSlash } from '../../core/path.js';
|
||||||
import { createBuildInternals } from '../../core/build/internal.js';
|
import { createBuildInternals } from '../../core/build/internal.js';
|
||||||
import { rollupPluginAstroBuildCSS } from '../../vite-plugin-build-css/index.js';
|
import { rollupPluginAstroBuildCSS } from '../../vite-plugin-build-css/index.js';
|
||||||
import { getParamsAndProps } from '../ssr/index.js';
|
import { getParamsAndProps } from '../ssr/index.js';
|
||||||
|
@ -162,7 +162,7 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
|
||||||
build: {
|
build: {
|
||||||
emptyOutDir: false,
|
emptyOutDir: false,
|
||||||
minify: false,
|
minify: false,
|
||||||
outDir: fileURLToPath(astroConfig.dist),
|
outDir: fileURLToPath(getOutRoot(astroConfig)),
|
||||||
ssr: true,
|
ssr: true,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input: Array.from(input),
|
input: Array.from(input),
|
||||||
|
@ -202,7 +202,7 @@ async function clientBuild(opts: StaticBuildOptions, internals: BuildInternals,
|
||||||
build: {
|
build: {
|
||||||
emptyOutDir: false,
|
emptyOutDir: false,
|
||||||
minify: 'esbuild',
|
minify: 'esbuild',
|
||||||
outDir: fileURLToPath(astroConfig.dist),
|
outDir: fileURLToPath(getOutRoot(astroConfig)),
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input: Array.from(input),
|
input: Array.from(input),
|
||||||
output: {
|
output: {
|
||||||
|
@ -224,7 +224,7 @@ async function clientBuild(opts: StaticBuildOptions, internals: BuildInternals,
|
||||||
root: viteConfig.root,
|
root: viteConfig.root,
|
||||||
envPrefix: 'PUBLIC_',
|
envPrefix: 'PUBLIC_',
|
||||||
server: viteConfig.server,
|
server: viteConfig.server,
|
||||||
base: astroConfig.buildOptions.site ? new URL(astroConfig.buildOptions.site).pathname : '/',
|
base: appendForwardSlash(astroConfig.buildOptions.site ? (new URL(astroConfig.buildOptions.site)).pathname : '/'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ async function generatePages(result: RollupOutput, opts: StaticBuildOptions, int
|
||||||
async function generatePage(output: OutputChunk, opts: StaticBuildOptions, internals: BuildInternals, facadeIdToPageDataMap: Map<string, PageBuildData>, renderers: Renderer[]) {
|
async function generatePage(output: OutputChunk, opts: StaticBuildOptions, internals: BuildInternals, facadeIdToPageDataMap: Map<string, PageBuildData>, renderers: Renderer[]) {
|
||||||
const { astroConfig } = opts;
|
const { astroConfig } = opts;
|
||||||
|
|
||||||
let url = new URL('./' + output.fileName, astroConfig.dist);
|
let url = new URL('./' + output.fileName, getOutRoot(astroConfig));
|
||||||
const facadeId: string = output.facadeModuleId as string;
|
const facadeId: string = output.facadeModuleId as string;
|
||||||
let pageData = getByFacadeId<PageBuildData>(facadeId, facadeIdToPageDataMap);
|
let pageData = getByFacadeId<PageBuildData>(facadeId, facadeIdToPageDataMap);
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: G
|
||||||
|
|
||||||
debug('build', `Generating: ${pathname}`);
|
debug('build', `Generating: ${pathname}`);
|
||||||
|
|
||||||
const rootpath = new URL(astroConfig.buildOptions.site || 'http://localhost/').pathname;
|
const rootpath = appendForwardSlash(new URL(astroConfig.buildOptions.site || 'http://localhost/').pathname);
|
||||||
const links = new Set<SSRElement>(
|
const links = new Set<SSRElement>(
|
||||||
linkIds.map((href) => ({
|
linkIds.map((href) => ({
|
||||||
props: {
|
props: {
|
||||||
|
@ -372,8 +372,9 @@ async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: G
|
||||||
};
|
};
|
||||||
|
|
||||||
let html = await renderPage(result, Component, pageProps, null);
|
let html = await renderPage(result, Component, pageProps, null);
|
||||||
const outFolder = new URL('.' + pathname + '/', astroConfig.dist);
|
|
||||||
const outFile = new URL('./index.html', outFolder);
|
const outFolder = getOutFolder(astroConfig, pathname);
|
||||||
|
const outFile = getOutFile(astroConfig, outFolder, pathname);
|
||||||
await fs.promises.mkdir(outFolder, { recursive: true });
|
await fs.promises.mkdir(outFolder, { recursive: true });
|
||||||
await fs.promises.writeFile(outFile, html, 'utf-8');
|
await fs.promises.writeFile(outFile, html, 'utf-8');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -381,6 +382,29 @@ async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: G
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOutRoot(astroConfig: AstroConfig): URL {
|
||||||
|
const rootPathname = appendForwardSlash(astroConfig.buildOptions.site ?
|
||||||
|
new URL(astroConfig.buildOptions.site).pathname : '/');
|
||||||
|
return new URL('.' + rootPathname, astroConfig.dist);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOutFolder(astroConfig: AstroConfig, pathname: string): URL {
|
||||||
|
const outRoot = getOutRoot(astroConfig);
|
||||||
|
|
||||||
|
// This is the root folder to write to.
|
||||||
|
switch(astroConfig.buildOptions.pageUrlFormat) {
|
||||||
|
case 'directory': return new URL('.' + appendForwardSlash(pathname), outRoot);
|
||||||
|
case 'file': return outRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOutFile(astroConfig: AstroConfig, outFolder: URL, pathname: string): URL {
|
||||||
|
switch(astroConfig.buildOptions.pageUrlFormat) {
|
||||||
|
case 'directory': return new URL('./index.html', outFolder);
|
||||||
|
case 'file': return new URL('.' + pathname + '.html', outFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function cleanSsrOutput(opts: StaticBuildOptions) {
|
async function cleanSsrOutput(opts: StaticBuildOptions) {
|
||||||
// The SSR output is all .mjs files, the client output is not.
|
// The SSR output is all .mjs files, the client output is not.
|
||||||
const files = await glob('**/*.mjs', {
|
const files = await glob('**/*.mjs', {
|
||||||
|
|
|
@ -263,6 +263,7 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
|
||||||
|
|
||||||
/** Create the Astro.fetchContent() runtime function. */
|
/** Create the Astro.fetchContent() runtime function. */
|
||||||
function createFetchContentFn(url: URL, site: URL) {
|
function createFetchContentFn(url: URL, site: URL) {
|
||||||
|
let sitePathname = site.pathname;
|
||||||
const fetchContent = (importMetaGlobResult: Record<string, any>) => {
|
const fetchContent = (importMetaGlobResult: Record<string, any>) => {
|
||||||
let allEntries = [...Object.entries(importMetaGlobResult)];
|
let allEntries = [...Object.entries(importMetaGlobResult)];
|
||||||
if (allEntries.length === 0) {
|
if (allEntries.length === 0) {
|
||||||
|
@ -280,7 +281,7 @@ function createFetchContentFn(url: URL, site: URL) {
|
||||||
Content: mod.default,
|
Content: mod.default,
|
||||||
content: mod.metadata,
|
content: mod.metadata,
|
||||||
file: new URL(spec, url),
|
file: new URL(spec, url),
|
||||||
url: urlSpec.includes('/pages/') ? urlSpec.replace(/^.*\/pages\//, site.pathname).replace(/(\/index)?\.md$/, '') : undefined,
|
url: urlSpec.includes('/pages/') ? urlSpec.replace(/^.*\/pages\//, sitePathname).replace(/(\/index)?\.md$/, '') : undefined,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
|
|
@ -15,6 +15,7 @@ describe('Static build', () => {
|
||||||
renderers: ['@astrojs/renderer-preact'],
|
renderers: ['@astrojs/renderer-preact'],
|
||||||
buildOptions: {
|
buildOptions: {
|
||||||
experimentalStaticBuild: true,
|
experimentalStaticBuild: true,
|
||||||
|
site: 'http://example.com/subpath/',
|
||||||
},
|
},
|
||||||
ssr: {
|
ssr: {
|
||||||
noExternal: ['@astrojs/test-static-build-pkg'],
|
noExternal: ['@astrojs/test-static-build-pkg'],
|
||||||
|
@ -24,20 +25,20 @@ describe('Static build', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Builds out .astro pages', async () => {
|
it('Builds out .astro pages', async () => {
|
||||||
const html = await fixture.readFile('/index.html');
|
const html = await fixture.readFile('/subpath/index.html');
|
||||||
expect(html).to.be.a('string');
|
expect(html).to.be.a('string');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can build pages using fetchContent', async () => {
|
it('can build pages using fetchContent', async () => {
|
||||||
const html = await fixture.readFile('/index.html');
|
const html = await fixture.readFile('/subpath/index.html');
|
||||||
const $ = cheerio.load(html);
|
const $ = cheerio.load(html);
|
||||||
const link = $('.posts a');
|
const link = $('.posts a');
|
||||||
const href = link.attr('href');
|
const href = link.attr('href');
|
||||||
expect(href).to.be.equal('/posts/thoughts');
|
expect(href).to.be.equal('/subpath/posts/thoughts');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Builds out .md pages', async () => {
|
it('Builds out .md pages', async () => {
|
||||||
const html = await fixture.readFile('/posts/thoughts/index.html');
|
const html = await fixture.readFile('/subpath/posts/thoughts/index.html');
|
||||||
expect(html).to.be.a('string');
|
expect(html).to.be.a('string');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -62,12 +63,12 @@ describe('Static build', () => {
|
||||||
const findEvidence = createFindEvidence(/var\(--c\)/);
|
const findEvidence = createFindEvidence(/var\(--c\)/);
|
||||||
|
|
||||||
it('Included on the index page', async () => {
|
it('Included on the index page', async () => {
|
||||||
const found = await findEvidence('/index.html');
|
const found = await findEvidence('/subpath/index.html');
|
||||||
expect(found).to.equal(true, 'Did not find shared CSS on this page');
|
expect(found).to.equal(true, 'Did not find shared CSS on this page');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Included on a md page', async () => {
|
it('Included on a md page', async () => {
|
||||||
const found = await findEvidence('/posts/thoughts/index.html');
|
const found = await findEvidence('/subpath/posts/thoughts/index.html');
|
||||||
expect(found).to.equal(true, 'Did not find shared CSS on this page');
|
expect(found).to.equal(true, 'Did not find shared CSS on this page');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -76,30 +77,30 @@ describe('Static build', () => {
|
||||||
const findEvidence = createFindEvidence(/var\(--c-black\)/);
|
const findEvidence = createFindEvidence(/var\(--c-black\)/);
|
||||||
|
|
||||||
it('Is included in the index CSS', async () => {
|
it('Is included in the index CSS', async () => {
|
||||||
const found = await findEvidence('/index.html');
|
const found = await findEvidence('/subpath/index.html');
|
||||||
expect(found).to.equal(true, 'Did not find shared CSS module code');
|
expect(found).to.equal(true, 'Did not find shared CSS module code');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Hoisted scripts', () => {
|
describe('Hoisted scripts', () => {
|
||||||
it('Get bundled together on the page', async () => {
|
it('Get bundled together on the page', async () => {
|
||||||
const html = await fixture.readFile('/hoisted/index.html');
|
const html = await fixture.readFile('/subpath/hoisted/index.html');
|
||||||
const $ = cheerio.load(html);
|
const $ = cheerio.load(html);
|
||||||
expect($('script[type="module"]').length).to.equal(1, 'hoisted script added');
|
expect($('script[type="module"]').length).to.equal(1, 'hoisted script added');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Do not get added to the wrong page', async () => {
|
it('Do not get added to the wrong page', async () => {
|
||||||
const hoistedHTML = await fixture.readFile('/hoisted/index.html');
|
const hoistedHTML = await fixture.readFile('/subpath/hoisted/index.html');
|
||||||
const $ = cheerio.load(hoistedHTML);
|
const $ = cheerio.load(hoistedHTML);
|
||||||
const href = $('script[type="module"]').attr('src');
|
const href = $('script[type="module"]').attr('src');
|
||||||
const indexHTML = await fixture.readFile('/index.html');
|
const indexHTML = await fixture.readFile('/subpath/index.html');
|
||||||
const $$ = cheerio.load(indexHTML);
|
const $$ = cheerio.load(indexHTML);
|
||||||
expect($$(`script[src="${href}"]`).length).to.equal(0, 'no script added to different page');
|
expect($$(`script[src="${href}"]`).length).to.equal(0, 'no script added to different page');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('honors ssr config', async () => {
|
it('honors ssr config', async () => {
|
||||||
const html = await fixture.readFile('/index.html');
|
const html = await fixture.readFile('/subpath/index.html');
|
||||||
const $ = cheerio.load(html);
|
const $ = cheerio.load(html);
|
||||||
expect($('#ssr-config').text()).to.equal('testing');
|
expect($('#ssr-config').text()).to.equal('testing');
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue