Revert "fix vite web build to work with subpath"

This reverts commit 1a9f36ce9e.
This commit is contained in:
jeffvli
2026-02-12 18:17:44 -08:00
parent 80292ae579
commit 96f5b2b82a
4 changed files with 120 additions and 139 deletions
+2 -13
View File
@@ -2,11 +2,6 @@
FROM node:23-alpine as builder FROM node:23-alpine as builder
WORKDIR /app WORKDIR /app
# PUBLIC_PATH at build time: passed as VITE_BASE_PATH so assets are built for that subpath.
# Use "/" for root or "/feishin/" for a subpath (trailing slash required for subpaths).
ARG PUBLIC_PATH=/
ENV PUBLIC_PATH=${PUBLIC_PATH}
# Copy package.json first to cache node_modules # Copy package.json first to cache node_modules
COPY package.json pnpm-lock.yaml . COPY package.json pnpm-lock.yaml .
@@ -15,24 +10,18 @@ RUN npm install -g pnpm
RUN pnpm install RUN pnpm install
# Copy code and build with cached modules # Copy code and build with cached modules
# Normalize PUBLIC_PATH to trailing slash for subpaths (Vite base expects "/" or "/foo/")
COPY . . COPY . .
RUN VITE_BASE_PATH=$(echo "$PUBLIC_PATH" | sed 's|/*$|/|') && \ RUN pnpm run build:web
export VITE_BASE_PATH && \
pnpm run build:web
# --- Production stage # --- Production stage
FROM nginx:alpine-slim FROM nginx:alpine-slim
ARG PUBLIC_PATH=/
ENV PUBLIC_PATH=${PUBLIC_PATH}
COPY --chown=nginx:nginx --from=builder /app/out/web /usr/share/nginx/html COPY --chown=nginx:nginx --from=builder /app/out/web /usr/share/nginx/html
COPY ./settings.js.template /etc/nginx/templates/settings.js.template COPY ./settings.js.template /etc/nginx/templates/settings.js.template
COPY ng.conf.template /etc/nginx/templates/default.conf.template COPY ng.conf.template /etc/nginx/templates/default.conf.template
ENV SERVER_LOCK=false SERVER_NAME="" SERVER_TYPE="" SERVER_URL="" ENV SERVER_LOCK=false SERVER_NAME="" SERVER_TYPE="" SERVER_URL=""
ENV LEGACY_AUTHENTICATION="" ANALYTICS_DISABLED="" ENV LEGACY_AUTHENTICATION="" ANALYTICS_DISABLED="" PUBLIC_PATH="/"
EXPOSE 9180 EXPOSE 9180
CMD ["nginx", "-g", "daemon off;"] CMD ["nginx", "-g", "daemon off;"]
+1 -2
View File
@@ -116,7 +116,6 @@ services:
- SERVER_URL= # http://address:port or https://address:port - SERVER_URL= # http://address:port or https://address:port
- LEGACY_AUTHENTICATION=false # When SERVER_LOCK is true, sets the legacy (plaintext) authentication flag for Subsonic/OpenSubsonic servers - LEGACY_AUTHENTICATION=false # When SERVER_LOCK is true, sets the legacy (plaintext) authentication flag for Subsonic/OpenSubsonic servers
- ANALYTICS_DISABLED=true # Set to true to disable Umami analytics tracking - ANALYTICS_DISABLED=true # Set to true to disable Umami analytics tracking
- PUBLIC_PATH=/feishin/ # Optional: if you want to host Feishin on a subpath (not `/`)
ports: ports:
- 9180:9180 - 9180:9180
# Alternatively, to restrict to only localhost, - 127.0.0.1:9180:8190 # Alternatively, to restrict to only localhost, - 127.0.0.1:9180:8190
@@ -131,7 +130,7 @@ services:
- **Navidrome** - For the best experience, select "Save password" when creating the server and configure the `SessionTimeout` setting in your Navidrome config to a larger value (e.g. 72h). - **Navidrome** - For the best experience, select "Save password" when creating the server and configure the `SessionTimeout` setting in your Navidrome config to a larger value (e.g. 72h).
- **Linux users** - The default password store uses `libsecret`. `kwallet4/5/6` are also supported, but must be explicitly set in Settings > Window > Passwords/secret store. - **Linux users** - The default password store uses `libsecret`. `kwallet4/5/6` are also supported, but must be explicitly set in Settings > Window > Passwords/secret store.
3. _Optional_ - If you want to host Feishin on a subpath (not `/`), pass `PUBLIC_PATH` at **build time** (and the same value at run time for nginx). Use a trailing slash for subpaths, e.g. `PUBLIC_PATH=/feishin/`. Example: `docker build --build-arg PUBLIC_PATH=/feishin/ .` then run with `-e PUBLIC_PATH=/feishin/`. 3. _Optional_ - If you want to host Feishin on a subpath (not `/`), then pass in the following environment variable: `PUBLIC_PATH=PATH`. For example, to host on `/feishin`, pass in `PUBLIC_PATH=/feishin`.
4. _Optional_ - To hard code the server url, pass the following environment variables: `SERVER_NAME`, `SERVER_TYPE` (one of `jellyfin` or `navidrome` or `subsonic`), `SERVER_URL`. To prevent users from changing these settings, pass `SERVER_LOCK=true`. This can only be set if all three of the previous values are set. When `SERVER_LOCK=true`, you can also set `LEGACY_AUTHENTICATION=true` or `LEGACY_AUTHENTICATION=false` to configure the legacy authentication flag for the server (only applicable for Subsonic/OpenSubsonic servers). 4. _Optional_ - To hard code the server url, pass the following environment variables: `SERVER_NAME`, `SERVER_TYPE` (one of `jellyfin` or `navidrome` or `subsonic`), `SERVER_URL`. To prevent users from changing these settings, pass `SERVER_LOCK=true`. This can only be set if all three of the previous values are set. When `SERVER_LOCK=true`, you can also set `LEGACY_AUTHENTICATION=true` or `LEGACY_AUTHENTICATION=false` to configure the legacy authentication flag for the server (only applicable for Subsonic/OpenSubsonic servers).
+1 -2
View File
@@ -12,10 +12,9 @@ server {
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 9; gzip_comp_level 9;
# PUBLIC_PATH must be "/" or a subpath with trailing slash (e.g. "/feishin/")
location ${PUBLIC_PATH} { location ${PUBLIC_PATH} {
alias /usr/share/nginx/html/; alias /usr/share/nginx/html/;
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html =404;
} }
location ${PUBLIC_PATH}settings.js { location ${PUBLIC_PATH}settings.js {
+116 -122
View File
@@ -4,132 +4,126 @@ import { defineConfig, normalizePath } from 'vite';
import { ViteEjsPlugin } from 'vite-plugin-ejs'; import { ViteEjsPlugin } from 'vite-plugin-ejs';
import { VitePWA } from 'vite-plugin-pwa'; import { VitePWA } from 'vite-plugin-pwa';
// eslint-disable-next-line @typescript-eslint/no-unused-vars export default defineConfig({
export default defineConfig(({ mode }) => { base: '/',
const base = process.env.VITE_BASE_PATH || '/'; build: {
emptyOutDir: true,
return { outDir: path.resolve(__dirname, './out/web'),
base, rollupOptions: {
build: { input: {
emptyOutDir: true, '32x32': normalizePath(path.resolve(__dirname, './assets/icons/32x32.png')),
outDir: path.resolve(__dirname, './out/web'), '64x64': normalizePath(path.resolve(__dirname, './assets/icons/64x64.png')),
rollupOptions: { '128x128': normalizePath(path.resolve(__dirname, './assets/icons/128x128.png')),
input: { '256x256': normalizePath(path.resolve(__dirname, './assets/icons/256x256.png')),
'32x32': normalizePath(path.resolve(__dirname, './assets/icons/32x32.png')), '512x512': normalizePath(path.resolve(__dirname, './assets/icons/512x512.png')),
'64x64': normalizePath(path.resolve(__dirname, './assets/icons/64x64.png')), '1024x1024': normalizePath(path.resolve(__dirname, './assets/icons/1024x1024.png')),
'128x128': normalizePath(path.resolve(__dirname, './assets/icons/128x128.png')), favicon: normalizePath(path.resolve(__dirname, './assets/icons/favicon.ico')),
'256x256': normalizePath(path.resolve(__dirname, './assets/icons/256x256.png')), index: normalizePath(path.resolve(__dirname, './src/renderer/index.html')),
'512x512': normalizePath(path.resolve(__dirname, './assets/icons/512x512.png')), preview_full_screen_player: normalizePath(
'1024x1024': normalizePath( path.resolve(__dirname, './media/preview_full_screen_player.webp'),
path.resolve(__dirname, './assets/icons/1024x1024.png'), ),
),
favicon: normalizePath(path.resolve(__dirname, './assets/icons/favicon.ico')),
index: normalizePath(path.resolve(__dirname, './src/renderer/index.html')),
preview_full_screen_player: normalizePath(
path.resolve(__dirname, './media/preview_full_screen_player.webp'),
),
},
},
sourcemap: true,
},
css: {
modules: {
generateScopedName: 'fs-[name]-[local]',
localsConvention: 'camelCase',
}, },
}, },
optimizeDeps: { sourcemap: true,
exclude: [ },
'@atlaskit/pragmatic-drag-and-drop', css: {
'@atlaskit/pragmatic-drag-and-drop-auto-scroll', modules: {
'@atlaskit/pragmatic-drag-and-drop-hitbox', generateScopedName: 'fs-[name]-[local]',
'@tanstack/react-query-persist-client', localsConvention: 'camelCase',
'idb-keyval',
],
}, },
plugins: [ },
react(), optimizeDeps: {
ViteEjsPlugin({ exclude: [
root: normalizePath(path.resolve(__dirname, './src/renderer')), '@atlaskit/pragmatic-drag-and-drop',
web: true, '@atlaskit/pragmatic-drag-and-drop-auto-scroll',
}), '@atlaskit/pragmatic-drag-and-drop-hitbox',
VitePWA({ '@tanstack/react-query-persist-client',
devOptions: { 'idb-keyval',
// The PWA will not be shown during development
enabled: false,
},
filename: 'sw.js',
injectRegister: 'inline',
manifest: {
background_color: '#FFDCB5',
display: 'standalone',
icons: [
{
sizes: '32x32',
src: '32x32.png',
type: 'image/png',
},
{
sizes: '64x64',
src: '64x64.png',
type: 'image/png',
},
{
sizes: '128x128',
src: '128x128.png',
type: 'image/png',
},
{
sizes: '256x256',
src: '256x256.png',
type: 'image/png',
},
{
purpose: 'any',
sizes: '512x512',
src: '512x512.png',
type: 'image/png',
},
{
sizes: '1024x1024',
src: '1024x1024.png',
type: 'image/png',
},
],
name: 'Feishin',
orientation: 'portrait',
screenshots: [
{
form_factor: 'wide',
label: 'Full screen player showing music player and lyrics',
sizes: '720x450',
src: 'preview_full_screen_player.webp',
type: 'image/webp',
},
],
short_name: 'Feishin',
start_url: '.',
theme_color: '#1E003D',
},
manifestFilename: 'assets/manifest.webmanifest',
outDir: path.resolve(__dirname, './out/web/'),
registerType: 'autoUpdate',
workbox: {
cleanupOutdatedCaches: true,
clientsClaim: true,
maximumFileSizeToCacheInBytes: 1000000 * 5, // 5 MB
skipWaiting: true,
},
}),
], ],
resolve: { },
alias: { plugins: [
'/@/i18n': path.resolve(__dirname, './src/i18n'), react(),
'/@/remote': path.resolve(__dirname, './src/remote'), ViteEjsPlugin({
'/@/renderer': path.resolve(__dirname, './src/renderer'), root: normalizePath(path.resolve(__dirname, './src/renderer')),
'/@/shared': path.resolve(__dirname, './src/shared'), web: true,
}),
VitePWA({
devOptions: {
// The PWA will not be shown during development
enabled: false,
}, },
filename: 'sw.js',
injectRegister: 'inline',
manifest: {
background_color: '#FFDCB5',
display: 'standalone',
icons: [
{
sizes: '32x32',
src: '32x32.png',
type: 'image/png',
},
{
sizes: '64x64',
src: '64x64.png',
type: 'image/png',
},
{
sizes: '128x128',
src: '128x128.png',
type: 'image/png',
},
{
sizes: '256x256',
src: '256x256.png',
type: 'image/png',
},
{
purpose: 'any',
sizes: '512x512',
src: '512x512.png',
type: 'image/png',
},
{
sizes: '1024x1024',
src: '1024x1024.png',
type: 'image/png',
},
],
name: 'Feishin',
orientation: 'portrait',
screenshots: [
{
form_factor: 'wide',
label: 'Full screen player showing music player and lyrics',
sizes: '720x450',
src: 'preview_full_screen_player.webp',
type: 'image/webp',
},
],
short_name: 'Feishin',
start_url: '/',
theme_color: '#1E003D',
},
manifestFilename: 'assets/manifest.webmanifest',
outDir: path.resolve(__dirname, './out/web/'),
registerType: 'autoUpdate',
scope: '/',
workbox: {
cleanupOutdatedCaches: true,
clientsClaim: true,
maximumFileSizeToCacheInBytes: 1000000 * 5, // 5 MB
skipWaiting: true,
},
}),
],
resolve: {
alias: {
'/@/i18n': path.resolve(__dirname, './src/i18n'),
'/@/remote': path.resolve(__dirname, './src/remote'),
'/@/renderer': path.resolve(__dirname, './src/renderer'),
'/@/shared': path.resolve(__dirname, './src/shared'),
}, },
root: path.resolve(__dirname, './src/renderer'), },
}; root: path.resolve(__dirname, './src/renderer'),
}); });