Handle project folders containing a space in the static build (#2486)
* Handle project folders containing a space * Adds a changeset * Bump the test package version * Use server relative paths as entries * Fix windows * A hoisted fix * Correctly handle facadeIds on windows
This commit is contained in:
parent
b3e0b80ab6
commit
6bd165f84c
20 changed files with 31 additions and 18 deletions
5
.changeset/afraid-crabs-heal.md
Normal file
5
.changeset/afraid-crabs-heal.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix for the static build when project contains a space
|
|
@ -63,7 +63,7 @@
|
||||||
"packages/astro/test/fixtures/builtins/packages/*",
|
"packages/astro/test/fixtures/builtins/packages/*",
|
||||||
"packages/astro/test/fixtures/builtins-polyfillnode",
|
"packages/astro/test/fixtures/builtins-polyfillnode",
|
||||||
"packages/astro/test/fixtures/custom-elements/my-component-lib",
|
"packages/astro/test/fixtures/custom-elements/my-component-lib",
|
||||||
"packages/astro/test/fixtures/static-build/pkg"
|
"packages/astro/test/fixtures/static build/pkg"
|
||||||
],
|
],
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "14.17.0",
|
"node": "14.17.0",
|
||||||
|
|
|
@ -14,6 +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 { 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';
|
||||||
|
@ -40,12 +41,16 @@ function addPageName(pathname: string, opts: StaticBuildOptions): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines of a Rollup chunk is an entrypoint page.
|
// Determines of a Rollup chunk is an entrypoint page.
|
||||||
function chunkIsPage(output: OutputAsset | OutputChunk, internals: BuildInternals) {
|
function chunkIsPage(astroConfig: AstroConfig, output: OutputAsset | OutputChunk, internals: BuildInternals) {
|
||||||
if (output.type !== 'chunk') {
|
if (output.type !== 'chunk') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const chunk = output as OutputChunk;
|
const chunk = output as OutputChunk;
|
||||||
return chunk.facadeModuleId && (internals.entrySpecifierToBundleMap.has(chunk.facadeModuleId) || internals.entrySpecifierToBundleMap.has('/' + chunk.facadeModuleId));
|
if(chunk.facadeModuleId) {
|
||||||
|
const facadeToEntryId = prependForwardSlash(chunk.facadeModuleId.slice(fileURLToPath(astroConfig.projectRoot).length));
|
||||||
|
return internals.entrySpecifierToBundleMap.has(facadeToEntryId);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Throttle the rendering a paths to prevents creating too many Promises on the microtask queue.
|
// Throttle the rendering a paths to prevents creating too many Promises on the microtask queue.
|
||||||
|
@ -74,8 +79,8 @@ function* throttle(max: number, inPaths: string[]) {
|
||||||
function getByFacadeId<T>(facadeId: string, map: Map<string, T>): T | undefined {
|
function getByFacadeId<T>(facadeId: string, map: Map<string, T>): T | undefined {
|
||||||
return (
|
return (
|
||||||
map.get(facadeId) ||
|
map.get(facadeId) ||
|
||||||
// Check with a leading `/` because on Windows it doesn't have one.
|
// Windows the facadeId has forward slashes, no idea why
|
||||||
map.get('/' + facadeId)
|
map.get(facadeId.replace(/\//g, '\\'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +110,7 @@ export async function staticBuild(opts: StaticBuildOptions) {
|
||||||
|
|
||||||
for (const [component, pageData] of Object.entries(allPages)) {
|
for (const [component, pageData] of Object.entries(allPages)) {
|
||||||
const astroModuleURL = new URL('./' + component, astroConfig.projectRoot);
|
const astroModuleURL = new URL('./' + component, astroConfig.projectRoot);
|
||||||
const astroModuleId = astroModuleURL.pathname;
|
const astroModuleId = prependForwardSlash(component);
|
||||||
const [renderers, mod] = pageData.preload;
|
const [renderers, mod] = pageData.preload;
|
||||||
const metadata = mod.$$metadata;
|
const metadata = mod.$$metadata;
|
||||||
|
|
||||||
|
@ -121,7 +126,7 @@ export async function staticBuild(opts: StaticBuildOptions) {
|
||||||
// Add hoisted scripts
|
// Add hoisted scripts
|
||||||
const hoistedScripts = new Set(metadata.hoistedScriptPaths());
|
const hoistedScripts = new Set(metadata.hoistedScriptPaths());
|
||||||
if (hoistedScripts.size) {
|
if (hoistedScripts.size) {
|
||||||
const moduleId = new URL('./hoisted.js', astroModuleURL + '/').pathname;
|
const moduleId = npath.posix.join(astroModuleId, 'hoisted.js');
|
||||||
internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedScripts);
|
internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedScripts);
|
||||||
topLevelImports.add(moduleId);
|
topLevelImports.add(moduleId);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +136,7 @@ export async function staticBuild(opts: StaticBuildOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pageInput.add(astroModuleId);
|
pageInput.add(astroModuleId);
|
||||||
facadeIdToPageDataMap.set(astroModuleId, pageData);
|
facadeIdToPageDataMap.set(fileURLToPath(astroModuleURL), pageData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty out the dist folder, if needed. Vite has a config for doing this
|
// Empty out the dist folder, if needed. Vite has a config for doing this
|
||||||
|
@ -177,7 +182,7 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
|
||||||
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: astroConfig.buildOptions.site ? fileURLToPath(new URL(astroConfig.buildOptions.site)) : '/',
|
||||||
ssr: viteConfig.ssr,
|
ssr: viteConfig.ssr,
|
||||||
} as ViteConfigWithSSR);
|
} as ViteConfigWithSSR);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +213,7 @@ async function clientBuild(opts: StaticBuildOptions, internals: BuildInternals,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
vitePluginNewBuild(input, internals, 'js'),
|
vitePluginNewBuild(input, internals, 'js'),
|
||||||
vitePluginHoistedScripts(internals),
|
vitePluginHoistedScripts(astroConfig, internals),
|
||||||
rollupPluginAstroBuildCSS({
|
rollupPluginAstroBuildCSS({
|
||||||
internals,
|
internals,
|
||||||
}),
|
}),
|
||||||
|
@ -218,7 +223,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: astroConfig.buildOptions.site ? fileURLToPath(new URL(astroConfig.buildOptions.site)) : '/',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +262,7 @@ async function generatePages(result: RollupOutput, opts: StaticBuildOptions, int
|
||||||
|
|
||||||
const generationPromises = [];
|
const generationPromises = [];
|
||||||
for (let output of result.output) {
|
for (let output of result.output) {
|
||||||
if (chunkIsPage(output, internals)) {
|
if (chunkIsPage(opts.astroConfig, output, internals)) {
|
||||||
generationPromises.push(generatePage(output as OutputChunk, opts, internals, facadeIdToPageDataMap, renderers));
|
generationPromises.push(generatePage(output as OutputChunk, opts, internals, facadeIdToPageDataMap, renderers));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,7 +277,7 @@ async function generatePage(output: OutputChunk, opts: StaticBuildOptions, inter
|
||||||
let pageData = getByFacadeId<PageBuildData>(facadeId, facadeIdToPageDataMap);
|
let pageData = getByFacadeId<PageBuildData>(facadeId, facadeIdToPageDataMap);
|
||||||
|
|
||||||
if (!pageData) {
|
if (!pageData) {
|
||||||
throw new Error(`Unable to find a PageBuildData for the Astro page: ${facadeId}. There are the PageBuilDatas we have ${Array.from(facadeIdToPageDataMap.keys()).join(', ')}`);
|
throw new Error(`Unable to find a PageBuildData for the Astro page: ${facadeId}. There are the PageBuildDatas we have ${Array.from(facadeIdToPageDataMap.keys()).join(', ')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const linkIds = getByFacadeId<string[]>(facadeId, internals.facadeIdToAssetsMap) || [];
|
const linkIds = getByFacadeId<string[]>(facadeId, internals.facadeIdToAssetsMap) || [];
|
||||||
|
@ -383,7 +388,7 @@ async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: G
|
||||||
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', {
|
||||||
cwd: opts.astroConfig.dist.pathname,
|
cwd: fileURLToPath(opts.astroConfig.dist),
|
||||||
});
|
});
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
files.map(async (filename) => {
|
files.map(async (filename) => {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
|
import type { AstroConfig } from '../../@types/astro';
|
||||||
import type { Plugin as VitePlugin } from '../vite';
|
import type { Plugin as VitePlugin } from '../vite';
|
||||||
import type { BuildInternals } from '../../core/build/internal.js';
|
import type { BuildInternals } from '../../core/build/internal.js';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
function virtualHoistedEntry(id: string) {
|
function virtualHoistedEntry(id: string) {
|
||||||
return id.endsWith('.astro/hoisted.js') || id.endsWith('.md/hoisted.js');
|
return id.endsWith('.astro/hoisted.js') || id.endsWith('.md/hoisted.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function vitePluginHoistedScripts(internals: BuildInternals): VitePlugin {
|
export function vitePluginHoistedScripts(astroConfig: AstroConfig, internals: BuildInternals): VitePlugin {
|
||||||
return {
|
return {
|
||||||
name: '@astro/rollup-plugin-astro-hoisted-scripts',
|
name: '@astro/rollup-plugin-astro-hoisted-scripts',
|
||||||
|
|
||||||
|
@ -34,7 +36,8 @@ export function vitePluginHoistedScripts(internals: BuildInternals): VitePlugin
|
||||||
for (const [id, output] of Object.entries(bundle)) {
|
for (const [id, output] of Object.entries(bundle)) {
|
||||||
if (output.type === 'chunk' && output.facadeModuleId && virtualHoistedEntry(output.facadeModuleId)) {
|
if (output.type === 'chunk' && output.facadeModuleId && virtualHoistedEntry(output.facadeModuleId)) {
|
||||||
const facadeId = output.facadeModuleId!;
|
const facadeId = output.facadeModuleId!;
|
||||||
const filename = facadeId.slice(0, facadeId.length - '/hoisted.js'.length);
|
const pathname = facadeId.slice(0, facadeId.length - '/hoisted.js'.length);
|
||||||
|
const filename = fileURLToPath(new URL('.' + pathname, astroConfig.projectRoot));
|
||||||
internals.facadeIdToHoistedEntryMap.set(filename, id);
|
internals.facadeIdToHoistedEntryMap.set(filename, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@astrojs/test-static-build-pkg",
|
"name": "@astrojs/test-static-build-pkg",
|
||||||
"main": "./oops.js",
|
"main": "./oops.js",
|
||||||
"version": "0.0.1",
|
"version": "0.0.2",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": "./pkg.js",
|
"import": "./pkg.js",
|
|
@ -11,7 +11,7 @@ describe('Static build', () => {
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
fixture = await loadFixture({
|
fixture = await loadFixture({
|
||||||
projectRoot: './fixtures/static-build/',
|
projectRoot: './fixtures/static build/',
|
||||||
renderers: ['@astrojs/renderer-preact'],
|
renderers: ['@astrojs/renderer-preact'],
|
||||||
buildOptions: {
|
buildOptions: {
|
||||||
experimentalStaticBuild: true,
|
experimentalStaticBuild: true,
|
||||||
|
|
Loading…
Add table
Reference in a new issue