Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vite): auto-detect SPA index.html #57

Merged
merged 2 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ clean: ## Cleanup temporary build a
.PHONY: test
test: ## Run the tests
@echo "${INFO} Running test cases... 🧪"
@npm run test >/dev/null 2>&1
@NODE_OPTIONS="--no-deprecation --disable-warning=ExperimentalWarning" npm run test
@uv run pytest -n 2 --quiet
@echo "${OK} Tests passed ✨"

Expand Down Expand Up @@ -177,7 +177,7 @@ type-check: mypy pyright ## Run all type checking
.PHONY: pre-commit
pre-commit: ## Run pre-commit hooks
@echo "${INFO} Running pre-commit checks... 🔎"
@uv run pre-commit run --color=always --all-files
@NODE_OPTIONS="--no-deprecation --disable-warning=ExperimentalWarning" uv run pre-commit run --color=always --all-files
@echo "${OK} Pre-commit checks passed ✨"

.PHONY: slotscheck
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@
"vitest": "^2.1.6"
},
"peerDependencies": {
"vite": ">=5.0.0"
"vite": "^5.0.0 || ^6.0.0"
},
"engines": {
"node": "^18.0.0 || >=20.0.0"
"node": "^18.0.0 || ^20.0.0 || >=22.0.0"
},
"dependencies": {
"picocolors": "^1.1.1",
Expand Down
46 changes: 41 additions & 5 deletions src/js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ interface PluginConfig {
* @default null
*/
detectTls?: string | boolean | null
/**
* Automatically detect the index.html file.
*
* @default true
*/
autoDetectIndex?: boolean
/**
* Transform the code while serving.
*/
Expand All @@ -82,7 +88,7 @@ type DevServerUrl = `${"http" | "https"}://${string}:${number}`

let exitHandlersBound = false

export const refreshPaths = ["**/*.py", "**/*.j2", "**/*.html.j2", "**/*.html", "**/assets/**/*"]
export const refreshPaths = ["src/**", "resources/**", "assets/**"].filter((path) => fs.existsSync(path.replace(/\*\*$/, "")))

/**
* Litestar plugin for Vite.
Expand Down Expand Up @@ -184,10 +190,30 @@ function resolveLitestarPlugin(pluginConfig: Required<PluginConfig>): LitestarPl
}
return undefined
},
configureServer(server) {
async configureServer(server) {
const envDir = resolvedConfig.envDir || process.cwd()
const appUrl = loadEnv(resolvedConfig.mode, envDir, "APP_URL").APP_URL ?? "undefined"

// Check if we should serve SPA directly
const shouldServeIndex = () => {
if (!pluginConfig.autoDetectIndex) return false

// Check various common locations for index.html
const possiblePaths = [
path.join(server.config.root, "index.html"),
path.join(server.config.root, pluginConfig.resourceDirectory, "index.html"),
path.join(server.config.root, "public", "index.html"),
]

for (const indexPath of possiblePaths) {
try {
fs.accessSync(indexPath)
return true
} catch {}
}
return false
}

server.httpServer?.once("listening", () => {
const address = server.httpServer?.address()

Expand All @@ -197,14 +223,23 @@ function resolveLitestarPlugin(pluginConfig: Required<PluginConfig>): LitestarPl
fs.mkdirSync(path.dirname(pluginConfig.hotFile), { recursive: true })
fs.writeFileSync(pluginConfig.hotFile, viteDevServerUrl)

const hasIndex = shouldServeIndex()

setTimeout(() => {
server.config.logger.info(`\n ${colors.red(`${colors.bold("LITESTAR")} ${litestarVersion()}`)} ${colors.dim("plugin")} ${colors.bold(`v${pluginVersion()}`)}`)
server.config.logger.info("")
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("APP_URL")}: ${colors.cyan(appUrl.replace(/:(\d+)/, (_, port) => `:${colors.bold(port)}`))}`)
if (hasIndex) {
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("Serve Index")}: Serving application index with Vite`)
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("DEV URL")}: ${colors.cyan(viteDevServerUrl)}`)
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("APP_URL")}: ${colors.cyan(appUrl.replace(/:(\d+)/, (_, port) => `:${colors.bold(port)}`))}`)
} else {
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("Serve Index")}: Serving Litestar index with Vite`)
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("DEV URL")}: ${colors.cyan(viteDevServerUrl)}`)
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("APP_URL")}: ${colors.cyan(appUrl.replace(/:(\d+)/, (_, port) => `:${colors.bold(port)}`))}`)
}
}, 100)
}
})

if (!exitHandlersBound) {
const clean = () => {
if (fs.existsSync(pluginConfig.hotFile)) {
Expand All @@ -222,7 +257,7 @@ function resolveLitestarPlugin(pluginConfig: Required<PluginConfig>): LitestarPl

return () =>
server.middlewares.use((req, res, next) => {
if (req.url === "/index.html") {
if (!shouldServeIndex() && req.url === "/index.html") {
res.statusCode = 404

res.end(
Expand Down Expand Up @@ -325,6 +360,7 @@ function resolvePluginConfig(config: string | string[] | PluginConfig): Required
refresh: resolvedConfig.refresh ?? false,
hotFile: resolvedConfig.hotFile ?? path.join(resolvedConfig.bundleDirectory ?? "public", "hot"),
detectTls: resolvedConfig.detectTls ?? false,
autoDetectIndex: resolvedConfig.autoDetectIndex ?? true,
transformOnServe: resolvedConfig.transformOnServe ?? ((code) => code),
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/js/src/inertia-helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ export function isRoute(url: string, routeName: string): boolean {
const regexPattern = routePattern.replace(/\//g, "\\/").replace(/\{([^}]+):([^}]+)\}/g, (match, paramName, paramType) => {
switch (paramType) {
case "str":
case "path":
return "([^/]+)"
case "path":
return "(.*)"
case "uuid":
return "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
default:
Expand Down
Loading
Loading