server: (webui) no more gzip compression (#21073)
* webui: no more gzip * try changing a small line * Revert "try changing a small line" This reverts commit 0d7a3531593d87b724d404c8727a96becab3ab07. * fix lint * fix test * rebuild * split into html/css/js * lint * chore: update webui build output * chore: Update git hooks script * server: update webui build output * chore: Update pre-commit hook * refactor: Cleanup --------- Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>
This commit is contained in:
+8
-8
@@ -21,14 +21,6 @@ indent_style = tab
|
|||||||
[prompts/*.txt]
|
[prompts/*.txt]
|
||||||
insert_final_newline = unset
|
insert_final_newline = unset
|
||||||
|
|
||||||
[tools/server/public/*]
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[tools/server/public/deps_*]
|
|
||||||
trim_trailing_whitespace = unset
|
|
||||||
indent_style = unset
|
|
||||||
indent_size = unset
|
|
||||||
|
|
||||||
[tools/server/deps_*]
|
[tools/server/deps_*]
|
||||||
trim_trailing_whitespace = unset
|
trim_trailing_whitespace = unset
|
||||||
indent_style = unset
|
indent_style = unset
|
||||||
@@ -61,6 +53,14 @@ charset = unset
|
|||||||
trim_trailing_whitespace = unset
|
trim_trailing_whitespace = unset
|
||||||
insert_final_newline = unset
|
insert_final_newline = unset
|
||||||
|
|
||||||
|
[tools/server/public/**]
|
||||||
|
indent_style = unset
|
||||||
|
indent_size = unset
|
||||||
|
end_of_line = unset
|
||||||
|
charset = unset
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
insert_final_newline = unset
|
||||||
|
|
||||||
[benches/**]
|
[benches/**]
|
||||||
indent_style = unset
|
indent_style = unset
|
||||||
indent_size = unset
|
indent_size = unset
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Treat the generated single-file WebUI build as binary for diff purposes.
|
||||||
|
# Git's pack-file delta compression still works (byte-level), but this prevents
|
||||||
|
# git diff from printing the entire minified file on every change.
|
||||||
|
tools/server/public/index.html -diff
|
||||||
@@ -95,6 +95,8 @@
|
|||||||
# Server Web UI temporary files
|
# Server Web UI temporary files
|
||||||
/tools/server/webui/node_modules
|
/tools/server/webui/node_modules
|
||||||
/tools/server/webui/dist
|
/tools/server/webui/dist
|
||||||
|
# we no longer use gz for index.html
|
||||||
|
/tools/server/public/index.html.gz
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ option(LLAMA_BUILD_WEBUI "Build the embedded Web UI" ON)
|
|||||||
|
|
||||||
if (LLAMA_BUILD_WEBUI)
|
if (LLAMA_BUILD_WEBUI)
|
||||||
set(PUBLIC_ASSETS
|
set(PUBLIC_ASSETS
|
||||||
index.html.gz
|
index.html
|
||||||
|
bundle.js
|
||||||
|
bundle.css
|
||||||
loading.html
|
loading.html
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -259,6 +259,6 @@ npm run test
|
|||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
After `public/index.html.gz` has been generated, rebuild `llama-server` as described in the [build](#build) section to include the updated UI.
|
After `public/index.html` has been generated, rebuild `llama-server` as described in the [build](#build) section to include the updated UI.
|
||||||
|
|
||||||
**Note:** The Vite dev server automatically proxies API requests to `http://localhost:8080`. Make sure `llama-server` is running on that port during development.
|
**Note:** The Vite dev server automatically proxies API requests to `http://localhost:8080`. Make sure `llama-server` is running on that port during development.
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -10,7 +10,9 @@
|
|||||||
|
|
||||||
#ifdef LLAMA_BUILD_WEBUI
|
#ifdef LLAMA_BUILD_WEBUI
|
||||||
// auto generated files (see README.md for details)
|
// auto generated files (see README.md for details)
|
||||||
#include "index.html.gz.hpp"
|
#include "index.html.hpp"
|
||||||
|
#include "bundle.js.hpp"
|
||||||
|
#include "bundle.css.hpp"
|
||||||
#include "loading.html.hpp"
|
#include "loading.html.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -272,16 +274,19 @@ bool server_http_context::init(const common_params & params) {
|
|||||||
} else {
|
} else {
|
||||||
#ifdef LLAMA_BUILD_WEBUI
|
#ifdef LLAMA_BUILD_WEBUI
|
||||||
// using embedded static index.html
|
// using embedded static index.html
|
||||||
srv->Get(params.api_prefix + "/", [](const httplib::Request & req, httplib::Response & res) {
|
srv->Get(params.api_prefix + "/", [](const httplib::Request & /*req*/, httplib::Response & res) {
|
||||||
if (req.get_header_value("Accept-Encoding").find("gzip") == std::string::npos) {
|
// COEP and COOP headers, required by pyodide (python interpreter)
|
||||||
res.set_content("Error: gzip is not supported by this browser", "text/plain");
|
res.set_header("Cross-Origin-Embedder-Policy", "require-corp");
|
||||||
} else {
|
res.set_header("Cross-Origin-Opener-Policy", "same-origin");
|
||||||
res.set_header("Content-Encoding", "gzip");
|
res.set_content(reinterpret_cast<const char*>(index_html), index_html_len, "text/html; charset=utf-8");
|
||||||
// COEP and COOP headers, required by pyodide (python interpreter)
|
return false;
|
||||||
res.set_header("Cross-Origin-Embedder-Policy", "require-corp");
|
});
|
||||||
res.set_header("Cross-Origin-Opener-Policy", "same-origin");
|
srv->Get(params.api_prefix + "/bundle.js", [](const httplib::Request & /*req*/, httplib::Response & res) {
|
||||||
res.set_content(reinterpret_cast<const char*>(index_html_gz), index_html_gz_len, "text/html; charset=utf-8");
|
res.set_content(reinterpret_cast<const char*>(bundle_js), bundle_js_len, "application/javascript; charset=utf-8");
|
||||||
}
|
return false;
|
||||||
|
});
|
||||||
|
srv->Get(params.api_prefix + "/bundle.css", [](const httplib::Request & /*req*/, httplib::Response & res) {
|
||||||
|
res.set_content(reinterpret_cast<const char*>(bundle_css), bundle_css_len, "text/css; charset=utf-8");
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -188,14 +188,14 @@ The build process:
|
|||||||
1. **Vite Build** - Bundles all TypeScript, Svelte, and CSS
|
1. **Vite Build** - Bundles all TypeScript, Svelte, and CSS
|
||||||
2. **Static Adapter** - Outputs to `../public` (llama-server's static file directory)
|
2. **Static Adapter** - Outputs to `../public` (llama-server's static file directory)
|
||||||
3. **Post-Build Script** - Cleans up intermediate files
|
3. **Post-Build Script** - Cleans up intermediate files
|
||||||
4. **Custom Plugin** - Creates `index.html.gz` with:
|
4. **Custom Plugin** - Creates `index.html` with:
|
||||||
- Inlined favicon as base64
|
- Inlined favicon as base64
|
||||||
- GZIP compression (level 9)
|
- GZIP compression (level 9)
|
||||||
- Deterministic output (zeroed timestamps)
|
- Deterministic output (zeroed timestamps)
|
||||||
|
|
||||||
```text
|
```text
|
||||||
tools/server/webui/ → build → tools/server/public/
|
tools/server/webui/ → build → tools/server/public/
|
||||||
├── src/ ├── index.html.gz (served by llama-server)
|
├── src/ ├── index.html (served by llama-server)
|
||||||
├── static/ └── (favicon inlined)
|
├── static/ └── (favicon inlined)
|
||||||
└── ...
|
└── ...
|
||||||
```
|
```
|
||||||
@@ -219,7 +219,7 @@ output: {
|
|||||||
|
|
||||||
The WebUI is embedded directly into the llama-server binary:
|
The WebUI is embedded directly into the llama-server binary:
|
||||||
|
|
||||||
1. `npm run build` outputs `index.html.gz` to `tools/server/public/`
|
1. `npm run build` outputs `index.html` to `tools/server/public/`
|
||||||
2. llama-server compiles this into the binary at build time
|
2. llama-server compiles this into the binary at build time
|
||||||
3. When accessing `/`, llama-server serves the gzipped HTML
|
3. When accessing `/`, llama-server serves the gzipped HTML
|
||||||
4. All assets are inlined (CSS, JS, fonts, favicon)
|
4. All assets are inlined (CSS, JS, fonts, favicon)
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
"eslint-config-prettier": "^10.0.1",
|
"eslint-config-prettier": "^10.0.1",
|
||||||
"eslint-plugin-storybook": "^10.2.4",
|
"eslint-plugin-storybook": "^10.2.4",
|
||||||
"eslint-plugin-svelte": "^3.0.0",
|
"eslint-plugin-svelte": "^3.0.0",
|
||||||
"fflate": "^0.8.2",
|
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
"http-server": "^14.1.1",
|
"http-server": "^14.1.1",
|
||||||
"mdast": "^3.0.0",
|
"mdast": "^3.0.0",
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Script to install pre-commit and pre-push hooks for webui
|
# Script to install pre-commit hook for webui
|
||||||
# Pre-commit: formats code and runs checks
|
# Pre-commit: formats, checks, builds, and stages build output
|
||||||
# Pre-push: builds the project, stashes unstaged changes
|
|
||||||
|
|
||||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||||
PRE_COMMIT_HOOK="$REPO_ROOT/.git/hooks/pre-commit"
|
PRE_COMMIT_HOOK="$REPO_ROOT/.git/hooks/pre-commit"
|
||||||
PRE_PUSH_HOOK="$REPO_ROOT/.git/hooks/pre-push"
|
|
||||||
|
|
||||||
echo "Installing pre-commit and pre-push hooks for webui..."
|
echo "Installing pre-commit hook for webui..."
|
||||||
|
|
||||||
# Create the pre-commit hook
|
# Create the pre-commit hook
|
||||||
cat > "$PRE_COMMIT_HOOK" << 'EOF'
|
cat > "$PRE_COMMIT_HOOK" << 'EOF'
|
||||||
@@ -16,21 +14,19 @@ cat > "$PRE_COMMIT_HOOK" << 'EOF'
|
|||||||
|
|
||||||
# Check if there are any changes in the webui directory
|
# Check if there are any changes in the webui directory
|
||||||
if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
||||||
echo "Formatting and checking webui code..."
|
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||||
|
cd "$REPO_ROOT/tools/server/webui"
|
||||||
# Change to webui directory and run format
|
|
||||||
cd tools/server/webui
|
# Check if package.json exists
|
||||||
|
|
||||||
# Check if npm is available and package.json exists
|
|
||||||
if [ ! -f "package.json" ]; then
|
if [ ! -f "package.json" ]; then
|
||||||
echo "Error: package.json not found in tools/server/webui"
|
echo "Error: package.json not found in tools/server/webui"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Formatting and checking webui code..."
|
||||||
|
|
||||||
# Run the format command
|
# Run the format command
|
||||||
npm run format
|
npm run format
|
||||||
|
|
||||||
# Check if format command succeeded
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Error: npm run format failed"
|
echo "Error: npm run format failed"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -38,8 +34,6 @@ if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
|||||||
|
|
||||||
# Run the lint command
|
# Run the lint command
|
||||||
npm run lint
|
npm run lint
|
||||||
|
|
||||||
# Check if lint command succeeded
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Error: npm run lint failed"
|
echo "Error: npm run lint failed"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -47,156 +41,42 @@ if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
|||||||
|
|
||||||
# Run the check command
|
# Run the check command
|
||||||
npm run check
|
npm run check
|
||||||
|
|
||||||
# Check if check command succeeded
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Error: npm run check failed"
|
echo "Error: npm run check failed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Go back to repo root
|
|
||||||
cd ../../..
|
|
||||||
|
|
||||||
echo "✅ Webui code formatted and checked successfully"
|
echo "✅ Webui code formatted and checked successfully"
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
# Build the webui
|
||||||
EOF
|
echo "Building webui..."
|
||||||
|
npm run build
|
||||||
# Create the pre-push hook
|
if [ $? -ne 0 ]; then
|
||||||
cat > "$PRE_PUSH_HOOK" << 'EOF'
|
echo "❌ npm run build failed"
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Check if there are any webui changes that need building
|
|
||||||
WEBUI_CHANGES=$(git diff --name-only @{push}..HEAD | grep "^tools/server/webui/" || true)
|
|
||||||
|
|
||||||
if [ -n "$WEBUI_CHANGES" ]; then
|
|
||||||
echo "Webui changes detected, checking if build is up-to-date..."
|
|
||||||
|
|
||||||
# Change to webui directory
|
|
||||||
cd tools/server/webui
|
|
||||||
|
|
||||||
# Check if npm is available and package.json exists
|
|
||||||
if [ ! -f "package.json" ]; then
|
|
||||||
echo "Error: package.json not found in tools/server/webui"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if build output exists and is newer than source files
|
|
||||||
BUILD_FILE="../public/index.html.gz"
|
|
||||||
NEEDS_BUILD=false
|
|
||||||
|
|
||||||
if [ ! -f "$BUILD_FILE" ]; then
|
|
||||||
echo "Build output not found, building..."
|
|
||||||
NEEDS_BUILD=true
|
|
||||||
else
|
|
||||||
# Check if any source files are newer than the build output
|
|
||||||
if find src -newer "$BUILD_FILE" -type f | head -1 | grep -q .; then
|
|
||||||
echo "Source files are newer than build output, rebuilding..."
|
|
||||||
NEEDS_BUILD=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$NEEDS_BUILD" = true ]; then
|
|
||||||
echo "Building webui..."
|
|
||||||
|
|
||||||
# Stash any unstaged changes to avoid conflicts during build
|
|
||||||
echo "Checking for unstaged changes..."
|
|
||||||
if ! git diff --quiet || ! git diff --cached --quiet --diff-filter=A; then
|
|
||||||
echo "Stashing unstaged changes..."
|
|
||||||
git stash push --include-untracked -m "Pre-push hook: stashed unstaged changes"
|
|
||||||
STASH_CREATED=$?
|
|
||||||
else
|
|
||||||
echo "No unstaged changes to stash"
|
|
||||||
STASH_CREATED=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Run the build command
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
# Check if build command succeeded
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Error: npm run build failed"
|
|
||||||
if [ $STASH_CREATED -eq 0 ]; then
|
|
||||||
echo "You can restore your unstaged changes with: git stash pop"
|
|
||||||
fi
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Go back to repo root
|
# Stage the build output alongside the source changes
|
||||||
cd ../../..
|
cd "$REPO_ROOT"
|
||||||
|
git add tools/server/public/
|
||||||
# Check if build output was created/updated
|
|
||||||
if [ -f "tools/server/public/index.html.gz" ]; then
|
echo "✅ Webui built and build output staged"
|
||||||
# Add the build output and commit it
|
|
||||||
git add tools/server/public/index.html.gz
|
|
||||||
if ! git diff --cached --quiet; then
|
|
||||||
echo "Committing updated build output..."
|
|
||||||
git commit -m "chore: update webui build output"
|
|
||||||
echo "✅ Build output committed successfully"
|
|
||||||
else
|
|
||||||
echo "Build output unchanged"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Error: Build output not found after build"
|
|
||||||
if [ $STASH_CREATED -eq 0 ]; then
|
|
||||||
echo "You can restore your unstaged changes with: git stash pop"
|
|
||||||
fi
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $STASH_CREATED -eq 0 ]; then
|
|
||||||
echo "✅ Build completed. Your unstaged changes have been stashed."
|
|
||||||
echo "They will be automatically restored after the push."
|
|
||||||
# Create a marker file to indicate stash was created by pre-push hook
|
|
||||||
touch .git/WEBUI_PUSH_STASH_MARKER
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "✅ Build output is up-to-date"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Webui ready for push"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create the post-push hook (for restoring stashed changes after push)
|
# Make hook executable
|
||||||
cat > "$REPO_ROOT/.git/hooks/post-push" << 'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Check if we have a stash marker from the pre-push hook
|
|
||||||
if [ -f .git/WEBUI_PUSH_STASH_MARKER ]; then
|
|
||||||
echo "Restoring your unstaged changes after push..."
|
|
||||||
git stash pop
|
|
||||||
rm -f .git/WEBUI_PUSH_STASH_MARKER
|
|
||||||
echo "✅ Your unstaged changes have been restored."
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Make all hooks executable
|
|
||||||
chmod +x "$PRE_COMMIT_HOOK"
|
chmod +x "$PRE_COMMIT_HOOK"
|
||||||
chmod +x "$PRE_PUSH_HOOK"
|
|
||||||
chmod +x "$REPO_ROOT/.git/hooks/post-push"
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "✅ Git hooks installed successfully!"
|
echo "✅ Git hook installed successfully!"
|
||||||
echo " Pre-commit: $PRE_COMMIT_HOOK"
|
echo " Pre-commit: $PRE_COMMIT_HOOK"
|
||||||
echo " Pre-push: $PRE_PUSH_HOOK"
|
|
||||||
echo " Post-push: $REPO_ROOT/.git/hooks/post-push"
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "The hooks will automatically:"
|
echo "The hook will automatically:"
|
||||||
echo " • Format and check webui code before commits (pre-commit)"
|
echo " • Format, lint and check webui code before commits"
|
||||||
echo " • Build webui code before pushes (pre-push)"
|
echo " • Build webui and stage tools/server/public/ into the same commit"
|
||||||
echo " • Stash unstaged changes during build process"
|
|
||||||
echo " • Restore your unstaged changes after the push"
|
|
||||||
echo ""
|
|
||||||
echo "To test the hooks:"
|
|
||||||
echo " • Make a change to a file in the webui directory and commit it (triggers format/check)"
|
|
||||||
echo " • Push your commits to trigger the build process"
|
|
||||||
else
|
else
|
||||||
echo "❌ Failed to make hooks executable"
|
echo "❌ Failed to make hook executable"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
rm -rf ../public/_app;
|
rm -rf ../public/_app;
|
||||||
rm ../public/favicon.svg;
|
rm ../public/favicon.svg;
|
||||||
rm ../public/index.html;
|
rm -f ../public/index.html.gz; # deprecated, but may still be generated by older versions of the build process
|
||||||
|
|||||||
@@ -40,6 +40,17 @@
|
|||||||
--code-background: oklch(0.985 0 0);
|
--code-background: oklch(0.985 0 0);
|
||||||
--code-foreground: oklch(0.145 0 0);
|
--code-foreground: oklch(0.145 0 0);
|
||||||
--layer-popover: 1000000;
|
--layer-popover: 1000000;
|
||||||
|
|
||||||
|
--chat-form-area-height: 8rem;
|
||||||
|
--chat-form-area-offset: 2rem;
|
||||||
|
--max-message-height: max(24rem, min(80dvh, calc(100dvh - var(--chat-form-area-height) - 12rem)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
:root {
|
||||||
|
--chat-form-area-height: 24rem;
|
||||||
|
--chat-form-area-offset: 12rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
@@ -116,19 +127,6 @@
|
|||||||
--color-sidebar-ring: var(--sidebar-ring);
|
--color-sidebar-ring: var(--sidebar-ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
|
||||||
--chat-form-area-height: 8rem;
|
|
||||||
--chat-form-area-offset: 2rem;
|
|
||||||
--max-message-height: max(24rem, min(80dvh, calc(100dvh - var(--chat-form-area-height) - 12rem)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
|
||||||
:root {
|
|
||||||
--chat-form-area-height: 24rem;
|
|
||||||
--chat-form-area-offset: 12rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
* {
|
* {
|
||||||
@apply border-border outline-ring/50;
|
@apply border-border outline-ring/50;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const config = {
|
|||||||
strict: true
|
strict: true
|
||||||
}),
|
}),
|
||||||
output: {
|
output: {
|
||||||
bundleStrategy: 'inline'
|
bundleStrategy: 'single'
|
||||||
},
|
},
|
||||||
alias: {
|
alias: {
|
||||||
$styles: 'src/styles'
|
$styles: 'src/styles'
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ import { expect, test } from '@playwright/test';
|
|||||||
|
|
||||||
test('home page has expected h1', async ({ page }) => {
|
test('home page has expected h1', async ({ page }) => {
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
await expect(page.locator('h1')).toBeVisible();
|
await expect(page.locator('h1').first()).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import tailwindcss from '@tailwindcss/vite';
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
import { sveltekit } from '@sveltejs/kit/vite';
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
import * as fflate from 'fflate';
|
import { readFileSync, writeFileSync, existsSync, readdirSync, copyFileSync } from 'fs';
|
||||||
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
||||||
import { dirname, resolve } from 'path';
|
import { dirname, resolve } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
@@ -20,15 +19,13 @@ const GUIDE_FOR_FRONTEND = `
|
|||||||
-->
|
-->
|
||||||
`.trim();
|
`.trim();
|
||||||
|
|
||||||
const MAX_BUNDLE_SIZE = 2 * 1024 * 1024;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the maximum size of an embedded asset in bytes,
|
* the maximum size of an embedded asset in bytes,
|
||||||
* e.g. maximum size of embedded font (see node_modules/katex/dist/fonts/*.woff2)
|
* e.g. maximum size of embedded font (see node_modules/katex/dist/fonts/*.woff2)
|
||||||
*/
|
*/
|
||||||
const MAX_ASSET_SIZE = 32000;
|
const MAX_ASSET_SIZE = 32000;
|
||||||
|
|
||||||
/** public/index.html.gz minified flag */
|
/** public/index.html minified flag */
|
||||||
const ENABLE_JS_MINIFICATION = true;
|
const ENABLE_JS_MINIFICATION = true;
|
||||||
|
|
||||||
function llamaCppBuildPlugin() {
|
function llamaCppBuildPlugin() {
|
||||||
@@ -40,7 +37,6 @@ function llamaCppBuildPlugin() {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
try {
|
try {
|
||||||
const indexPath = resolve('../public/index.html');
|
const indexPath = resolve('../public/index.html');
|
||||||
const gzipPath = resolve('../public/index.html.gz');
|
|
||||||
|
|
||||||
if (!existsSync(indexPath)) {
|
if (!existsSync(indexPath)) {
|
||||||
return;
|
return;
|
||||||
@@ -61,26 +57,35 @@ function llamaCppBuildPlugin() {
|
|||||||
|
|
||||||
content = content.replace(/\r/g, '');
|
content = content.replace(/\r/g, '');
|
||||||
content = GUIDE_FOR_FRONTEND + '\n' + content;
|
content = GUIDE_FOR_FRONTEND + '\n' + content;
|
||||||
|
content = content.replace(/\/_app\/immutable\/bundle\.[^"]+\.js/g, './bundle.js');
|
||||||
|
content = content.replace(
|
||||||
|
/\/_app\/immutable\/assets\/bundle\.[^"]+\.css/g,
|
||||||
|
'./bundle.css'
|
||||||
|
);
|
||||||
|
|
||||||
const compressed = fflate.gzipSync(Buffer.from(content, 'utf-8'), { level: 9 });
|
writeFileSync(indexPath, content, 'utf-8');
|
||||||
|
console.log('✓ Updated index.html');
|
||||||
|
|
||||||
compressed[0x4] = 0;
|
// Copy bundle.*.js -> ../public/bundle.js
|
||||||
compressed[0x5] = 0;
|
const immutableDir = resolve('../public/_app/immutable');
|
||||||
compressed[0x6] = 0;
|
const bundleDir = resolve('../public/_app/immutable/assets');
|
||||||
compressed[0x7] = 0;
|
if (existsSync(immutableDir)) {
|
||||||
compressed[0x9] = 0;
|
const jsFiles = readdirSync(immutableDir).filter((f) => f.match(/^bundle\..+\.js$/));
|
||||||
|
if (jsFiles.length > 0) {
|
||||||
if (compressed.byteLength > MAX_BUNDLE_SIZE) {
|
copyFileSync(resolve(immutableDir, jsFiles[0]), resolve('../public/bundle.js'));
|
||||||
throw new Error(
|
console.log(`✓ Copied ${jsFiles[0]} -> bundle.js`);
|
||||||
`Bundle size is too large (${Math.ceil(compressed.byteLength / 1024)} KB).\n` +
|
}
|
||||||
`Please reduce the size of the frontend or increase MAX_BUNDLE_SIZE in vite.config.ts.\n`
|
}
|
||||||
);
|
// Copy bundle.*.css -> ../public/bundle.css
|
||||||
|
if (existsSync(bundleDir)) {
|
||||||
|
const cssFiles = readdirSync(bundleDir).filter((f) => f.match(/^bundle\..+\.css$/));
|
||||||
|
if (cssFiles.length > 0) {
|
||||||
|
copyFileSync(resolve(bundleDir, cssFiles[0]), resolve('../public/bundle.css'));
|
||||||
|
console.log(`✓ Copied ${cssFiles[0]} -> bundle.css`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync(gzipPath, compressed);
|
|
||||||
console.log('✓ Created index.html.gz');
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to create gzip file:', error);
|
console.error('Failed to update index.html:', error);
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user