Home / File/ vite-plugin-astro-preview.ts — astro Source File

vite-plugin-astro-preview.ts — astro Source File

Architecture documentation for vite-plugin-astro-preview.ts, a typescript file in the astro codebase. 8 imports, 0 dependents.

File typescript CoreAstro RenderingEngine 8 imports 1 functions

Entity Profile

Dependency Diagram

graph LR
  459a3537_37d7_43aa_8770_8f94e664619a["vite-plugin-astro-preview.ts"]
  6b38722c_7b48_0d95_7927_ae62c3991719["../template/4xx.js"]
  459a3537_37d7_43aa_8770_8f94e664619a --> 6b38722c_7b48_0d95_7927_ae62c3991719
  e9b74c5a_8d34_34a7_e196_5e41b87214aa["../types/astro.js"]
  459a3537_37d7_43aa_8770_8f94e664619a --> e9b74c5a_8d34_34a7_e196_5e41b87214aa
  87530382_6d99_2339_182d_074e3de33bc8["../vite-plugin-utils/index.js"]
  459a3537_37d7_43aa_8770_8f94e664619a --> 87530382_6d99_2339_182d_074e3de33bc8
  8cf28db7_8f58_521d_48ac_0a62be28c962["./util.js"]
  459a3537_37d7_43aa_8770_8f94e664619a --> 8cf28db7_8f58_521d_48ac_0a62be28c962
  e16a223b_37f3_6b25_1ee1_2b7bcb9d9415["node:fs"]
  459a3537_37d7_43aa_8770_8f94e664619a --> e16a223b_37f3_6b25_1ee1_2b7bcb9d9415
  c2f6615e_96e9_c4eb_5f71_cf120e271705["node:http"]
  459a3537_37d7_43aa_8770_8f94e664619a --> c2f6615e_96e9_c4eb_5f71_cf120e271705
  d9a92db9_c95e_9165_13ac_24b3d859d946["node:url"]
  459a3537_37d7_43aa_8770_8f94e664619a --> d9a92db9_c95e_9165_13ac_24b3d859d946
  263e522e_1aa5_ebc3_e7d6_45ebc51671f7["vite"]
  459a3537_37d7_43aa_8770_8f94e664619a --> 263e522e_1aa5_ebc3_e7d6_45ebc51671f7
  style 459a3537_37d7_43aa_8770_8f94e664619a fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

import fs from 'node:fs';
import type { IncomingMessage, ServerResponse } from 'node:http';
import { fileURLToPath } from 'node:url';
import type { Connect, Plugin } from 'vite';
import { notFoundTemplate, subpathNotUsedTemplate } from '../../template/4xx.js';
import type { AstroSettings } from '../../types/astro.js';
import { cleanUrl } from '../../vite-plugin-utils/index.js';
import { stripBase } from './util.js';

const HAS_FILE_EXTENSION_REGEXP = /\.[^/]+$/;

export function vitePluginAstroPreview(settings: AstroSettings): Plugin {
	const { base, outDir, trailingSlash } = settings.config;

	function handle404(req: IncomingMessage, res: ServerResponse) {
		const errorPagePath = fileURLToPath(outDir + '/404.html');
		if (fs.existsSync(errorPagePath)) {
			res.statusCode = 404;
			res.setHeader('Content-Type', 'text/html');
			res.end(fs.readFileSync(errorPagePath));
		} else {
			res.statusCode = 404;
			res.end(notFoundTemplate(req.url!, 'Not Found'));
		}
	}

	return {
		name: 'astro:preview',
		apply: 'serve',
		configurePreviewServer(server) {
			server.middlewares.use((req, res, next) => {
				// respond 404 to requests outside the base request directory
				if (!req.url!.startsWith(base)) {
					res.statusCode = 404;
					res.end(subpathNotUsedTemplate(base, req.url!));
					return;
				}

				const pathname = cleanUrl(stripBase(req.url!, base));
				const isRoot = pathname === '/';

				// Validate trailingSlash
				if (!isRoot) {
					const hasTrailingSlash = pathname.endsWith('/');

					if (hasTrailingSlash && trailingSlash == 'never') {
						res.statusCode = 404;
						res.end(notFoundTemplate(pathname, 'Not Found (trailingSlash is set to "never")'));
						return;
					}

					if (
						!hasTrailingSlash &&
						trailingSlash == 'always' &&
						!HAS_FILE_EXTENSION_REGEXP.test(pathname)
					) {
						res.statusCode = 404;
						res.end(notFoundTemplate(pathname, 'Not Found (trailingSlash is set to "always")'));
						return;
					}
				}

				// TODO: look into why the replacement needs to happen here
				for (const middleware of server.middlewares.stack) {
					// This hardcoded name will not break between Vite versions
					if ((middleware.handle as Connect.HandleFunction).name === 'vite404Middleware') {
						middleware.handle = handle404;
					}
				}

				next();
			});

			return () => {
				// NOTE: the `base` is stripped from `req.url` for post middlewares

				server.middlewares.use((req, _res, next) => {
					const pathname = cleanUrl(req.url!);

					// Vite doesn't handle /foo/ if /foo.html exists, we handle it anyways
					if (pathname.endsWith('/')) {
						const pathnameWithoutSlash = pathname.slice(0, -1);
						const htmlPath = fileURLToPath(outDir + pathnameWithoutSlash + '.html');
						if (fs.existsSync(htmlPath)) {
							req.url = pathnameWithoutSlash + '.html';
							return next();
						}
					}
					// Vite doesn't handle /foo if /foo/index.html exists, we handle it anyways
					else {
						const htmlPath = fileURLToPath(outDir + pathname + '/index.html');
						if (fs.existsSync(htmlPath)) {
							req.url = pathname + '/index.html';
							return next();
						}
					}

					next();
				});
			};
		},
	};
}

Domain

Subdomains

Dependencies

  • ../template/4xx.js
  • ../types/astro.js
  • ../vite-plugin-utils/index.js
  • ./util.js
  • node:fs
  • node:http
  • node:url
  • vite

Frequently Asked Questions

What does vite-plugin-astro-preview.ts do?
vite-plugin-astro-preview.ts is a source file in the astro codebase, written in typescript. It belongs to the CoreAstro domain, RenderingEngine subdomain.
What functions are defined in vite-plugin-astro-preview.ts?
vite-plugin-astro-preview.ts defines 1 function(s): vitePluginAstroPreview.
What does vite-plugin-astro-preview.ts depend on?
vite-plugin-astro-preview.ts imports 8 module(s): ../template/4xx.js, ../types/astro.js, ../vite-plugin-utils/index.js, ./util.js, node:fs, node:http, node:url, vite.
Where is vite-plugin-astro-preview.ts in the architecture?
vite-plugin-astro-preview.ts is located at packages/astro/src/core/preview/vite-plugin-astro-preview.ts (domain: CoreAstro, subdomain: RenderingEngine, directory: packages/astro/src/core/preview).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free