0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-10 23:01:26 -05:00

wip improve base handling

This commit is contained in:
bluwy 2023-12-26 21:16:57 +08:00
parent bb1438d20d
commit b9c751e9cd
10 changed files with 52 additions and 22 deletions

View file

@ -1,4 +1,16 @@
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({});
export default defineConfig({
base: '/src',
vite: {
plugins: [
{
name:'',
configResolved(c) {
console.log(c.base)
}
}
]
}
});

View file

@ -61,6 +61,9 @@ import Card from '../components/Card.astro';
/>
</ul>
</main>
<script>
console.log('asd')
</script>
</Layout>
<style>

View file

@ -73,6 +73,7 @@ export function astroContentAssetPropagationPlugin({
const hoistedScripts = await getScriptsForURL(
pathToFileURL(basePath),
settings.config.root,
settings.config.base,
devModuleLoader
);

View file

@ -107,7 +107,6 @@ export async function createVite(
const commonConfig: vite.InlineConfig = {
// Tell Vite not to combine config from vite.config.js with our provided inline config
configFile: false,
cacheDir: fileURLToPath(new URL('./node_modules/.vite/', settings.config.root)), // using local caches allows Astro to be used in monorepos, etc.
clearScreen: false, // we want to control the output, not Vite
customLogger: createViteLogger(logger, settings.config.vite.logLevel),
appType: 'custom',
@ -147,6 +146,7 @@ export async function createVite(
],
publicDir: fileURLToPath(settings.config.publicDir),
root: fileURLToPath(settings.config.root),
base: new URL(settings.config.base, settings.config.site ?? 'http://localhost').pathname,
envPrefix: settings.config.vite?.envPrefix ?? 'PUBLIC_',
define: {
'import.meta.env.SITE': settings.config.site

View file

@ -6,7 +6,7 @@ import type { AstroConfig, AstroSettings, RouteType } from '../@types/astro.js';
import { isServerLikeOutput } from '../prerender/utils.js';
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './constants.js';
import type { ModuleLoader } from './module-loader/index.js';
import { prependForwardSlash, removeTrailingForwardSlash, slash } from './path.js';
import { joinPaths, prependForwardSlash, removeTrailingForwardSlash, slash } from './path.js';
/** Returns true if argument is an object of any prototype/class (but not null). */
export function isObject(value: unknown): value is Record<string, any> {
@ -189,25 +189,29 @@ export function emoji(char: string, fallback: string) {
* through a script tag or a dynamic import as-is.
*/
// NOTE: `/@id/` should only be used when the id is fully resolved
export async function resolveIdToUrl(loader: ModuleLoader, id: string, root?: URL) {
export async function resolveIdToUrl(loader: ModuleLoader, id: string, root?: URL, base?: string) {
let resultId = await loader.resolveId(id, undefined);
// Try resolve jsx to tsx
if (!resultId && id.endsWith('.jsx')) {
resultId = await loader.resolveId(id.slice(0, -4), undefined);
}
if (!resultId) {
return VALID_ID_PREFIX + id;
}
if (path.isAbsolute(resultId)) {
resultId = VALID_ID_PREFIX + id;
} else if (path.isAbsolute(resultId)) {
const normalizedRoot = root && normalizePath(fileURLToPath(root));
// Convert to root-relative path if path is inside root
if (normalizedRoot && resultId.startsWith(normalizedRoot)) {
return resultId.slice(normalizedRoot.length - 1);
resultId = resultId.slice(normalizedRoot.length - 1);
} else {
return '/@fs' + prependForwardSlash(resultId);
resultId = '/@fs' + prependForwardSlash(resultId);
}
} else {
resultId = VALID_ID_PREFIX + resultId;
}
return VALID_ID_PREFIX + resultId;
if (base) {
resultId = joinPaths(base, resultId);
}
return resultId;
}
export function resolveJsToTs(filePath: string) {

View file

@ -15,7 +15,6 @@ export function baseMiddleware(
const site = config.site ? new URL(config.base, config.site) : undefined;
const devRootURL = new URL(config.base, 'http://localhost');
const devRoot = site ? site.pathname : devRootURL.pathname;
const devRootReplacement = devRoot.endsWith('/') ? '/' : '';
return function devBaseMiddleware(req, res, next) {
const url = req.url!;
@ -23,7 +22,6 @@ export function baseMiddleware(
const pathname = decodeURI(new URL(url, 'http://localhost').pathname);
if (pathname.startsWith(devRoot)) {
req.url = url.replace(devRoot, devRootReplacement);
return next();
}

View file

@ -87,7 +87,7 @@ export async function handleRequest({
},
onError(_err) {
const { error, errorWithMetadata } = recordServerError(moduleLoader, config, pipeline, _err);
handle500Response(moduleLoader, incomingResponse, errorWithMetadata);
handle500Response(moduleLoader, config.base, incomingResponse, errorWithMetadata);
return error;
},
});

View file

@ -6,6 +6,7 @@ import { Readable } from 'stream';
import { getSetCookiesFromResponse } from '../core/cookies/index.js';
import { getViteErrorPayload } from '../core/errors/dev/index.js';
import notFoundTemplate from '../template/4xx.js';
import { joinPaths } from '@astrojs/internal-helpers/path';
export async function handle404Response(
origin: string,
@ -25,20 +26,22 @@ export async function handle404Response(
export async function handle500Response(
loader: ModuleLoader,
base: string,
res: http.ServerResponse,
err: ErrorWithMetadata
) {
res.on('close', async () =>
setTimeout(async () => loader.webSocketSend(await getViteErrorPayload(err)), 200)
);
const viteClientPath = joinPaths(base, '/@vite/client');
if (res.headersSent) {
res.write(`<script type="module" src="/@vite/client"></script>`);
res.write(`<script type="module" src="${viteClientPath}"></script>`);
res.end();
} else {
writeHtmlResponse(
res,
500,
`<title>${err.name}</title><script type="module" src="/@vite/client"></script>`
`<title>${err.name}</title><script type="module" src="${viteClientPath}"></script>`
);
}
}

View file

@ -35,6 +35,7 @@ import { getComponentMetadata } from './metadata.js';
import { handle404Response, writeSSRResult, writeWebResponse } from './response.js';
import { getScriptsForURL } from './scripts.js';
import { normalizeTheLocale } from '../i18n/index.js';
import { joinPaths } from '@astrojs/internal-helpers/path';
const clientLocalsSymbol = Symbol.for('astro.locals');
@ -384,13 +385,14 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
const moduleLoader = pipeline.getModuleLoader();
const settings = pipeline.getSettings();
const mode = pipeline.getEnvironment().mode;
const { root, base } = settings.config;
// Add hoisted script tags
const scripts = await getScriptsForURL(filePath, settings.config.root, moduleLoader);
const scripts = await getScriptsForURL(filePath, root, base, moduleLoader);
// Inject HMR scripts
if (isPage(filePath, settings) && mode === 'development') {
scripts.add({
props: { type: 'module', src: '/@vite/client' },
props: { type: 'module', src: joinPaths(base, '/@vite/client') },
children: '',
});
@ -401,7 +403,12 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
scripts.add({
props: {
type: 'module',
src: await resolveIdToUrl(moduleLoader, 'astro/runtime/client/dev-overlay/entrypoint.js'),
src: await resolveIdToUrl(
moduleLoader,
'astro/runtime/client/dev-overlay/entrypoint.js',
root,
base
),
},
children: '',
});
@ -441,6 +448,7 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
moduleLoader,
mode
);
console.log(filePath, styleUrls, importedStyles);
let links = new Set<SSRElement>();
[...styleUrls].forEach((href) => {
links.add({

View file

@ -8,24 +8,25 @@ import { crawlGraph } from './vite.js';
export async function getScriptsForURL(
filePath: URL,
root: URL,
base: string,
loader: ModuleLoader
): Promise<Set<SSRElement>> {
const elements = new Set<SSRElement>();
const rootID = viteID(filePath);
const modInfo = loader.getModuleInfo(rootID);
addHoistedScripts(elements, modInfo, root);
addHoistedScripts(elements, modInfo, root, base);
for await (const moduleNode of crawlGraph(loader, rootID, true)) {
const id = moduleNode.id;
if (id) {
const info = loader.getModuleInfo(id);
addHoistedScripts(elements, info, root);
addHoistedScripts(elements, info, root, base);
}
}
return elements;
}
function addHoistedScripts(set: Set<SSRElement>, info: ModuleInfo | null, root: URL) {
function addHoistedScripts(set: Set<SSRElement>, info: ModuleInfo | null, root: URL, base: string) {
if (!info?.meta?.astro) {
return;
}
@ -35,7 +36,7 @@ function addHoistedScripts(set: Set<SSRElement>, info: ModuleInfo | null, root:
for (let i = 0; i < astro.scripts.length; i++) {
let scriptId = `${id}?astro&type=script&index=${i}&lang.ts`;
scriptId = rootRelativePath(root, scriptId);
const element = createModuleScriptElementWithSrc(scriptId);
const element = createModuleScriptElementWithSrc(scriptId, base);
set.add(element);
}
}