mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(docker): fix TDZ crash, icon bundle bloat, rate-limit on static assets
- Fix "Cannot access 'a' before initialization" TDZ error after login caused by manualChunks splitting react-vendor + lucide icons into circular ES-module chunks. Removed manualChunks entirely. - Replace `import * as icons from "lucide-react"` (pulls all ~1000 icons) with a targeted icon-map of ~50 icons actually used by tool definitions. Reduces shared icons chunk from 745KB to 62KB (132KB→16KB gzip). - Exclude static files from @fastify/rate-limit via allowList so rapid page navigations don't 429 on JS/CSS chunk requests. - Move Docker auth defaults (AUTH_ENABLED, DEFAULT_USERNAME, DEFAULT_PASSWORD) from Dockerfile ENV to entrypoint.sh runtime exports to avoid SecretsUsedInArgOrEnv warnings. - Fix Docker CMD to use pnpm --filter for workspace-scoped tsx binary. - Set COREPACK_HOME system-wide so non-root user can access pnpm cache. - Lazy-load all pages in App.tsx and all controls in pipeline-step-settings.tsx to keep main bundle under 300KB.
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import type { CategoryInfo, Tool } from "@ashim/shared";
|
||||
import { CATEGORIES, TOOLS } from "@ashim/shared";
|
||||
import * as icons from "lucide-react";
|
||||
import { Eye, EyeOff, FileImage, LayoutGrid, List, Search } from "lucide-react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { GemLogo } from "@/components/common/gem-logo";
|
||||
import { apiGet } from "@/lib/api";
|
||||
import { ICON_MAP } from "@/lib/icon-map";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function FullscreenGridPage() {
|
||||
@@ -57,8 +57,6 @@ export function FullscreenGridPage() {
|
||||
|
||||
const activeCategories = CATEGORIES.filter((cat) => groupedTools.has(cat.id));
|
||||
|
||||
const iconsMap = icons as unknown as Record<string, React.ComponentType<{ className?: string }>>;
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background text-foreground">
|
||||
{/* Top bar */}
|
||||
@@ -130,7 +128,6 @@ export function FullscreenGridPage() {
|
||||
category={category}
|
||||
tools={groupedTools.get(category.id) || []}
|
||||
showDetails={showDetails}
|
||||
iconsMap={iconsMap}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -144,14 +141,13 @@ function CategoryCard({
|
||||
category,
|
||||
tools,
|
||||
showDetails,
|
||||
iconsMap,
|
||||
}: {
|
||||
category: CategoryInfo;
|
||||
tools: Tool[];
|
||||
showDetails: boolean;
|
||||
iconsMap: Record<string, React.ComponentType<{ className?: string }>>;
|
||||
}) {
|
||||
const CategoryIcon = iconsMap[category.icon] || LayoutGrid;
|
||||
const CategoryIcon =
|
||||
(ICON_MAP[category.icon] as React.ComponentType<{ className?: string }>) ?? LayoutGrid;
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-border bg-card overflow-hidden shadow-sm hover:shadow-md transition-shadow">
|
||||
@@ -183,7 +179,8 @@ function CategoryCard({
|
||||
{/* Tool list */}
|
||||
<div className="p-2">
|
||||
{tools.map((tool) => {
|
||||
const ToolIcon = iconsMap[tool.icon] || FileImage;
|
||||
const ToolIcon =
|
||||
(ICON_MAP[tool.icon] as React.ComponentType<{ className?: string }>) ?? FileImage;
|
||||
return (
|
||||
<Link
|
||||
key={tool.id}
|
||||
|
||||
Reference in New Issue
Block a user