feat(dev): use proxy server in dev mode (#3069)

In dev environment, this PR allows to proxy to whatever backend without CORS issue by specifying the backend URL in `.env.local` variable.

I believe this would ease contribution by frontend developpers that would only have to run the unstable docker to work on the frontend without need for all the go toolchain to build the whole backend to have a cors enabled backend.

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/vikunja/pulls/3069
Co-authored-by: Marc <marc88@free.fr>
Co-committed-by: Marc <marc88@free.fr>
This commit is contained in:
Marc
2025-03-09 13:40:57 +00:00
committed by konrad
parent 96ec7b17bc
commit 25ff8939f6
7 changed files with 67 additions and 15 deletions

View File

@@ -448,7 +448,7 @@ steps:
from_secret: cypress_project_key
commands:
- cd frontend
- sed -i 's/localhost/test-api-run/g' dist-test/index.html
- sed -i 's@/api/v1@http://test-api-run:3456/api/v1@g' dist-test/index.html
- npm install -g corepack && corepack enable && pnpm config set store-dir .cache/pnpm
- pnpm cypress install
- pnpm run test:e2e-record-test
@@ -470,8 +470,6 @@ steps:
commands:
- cd frontend
- cp -r dist-test dist-preview
# Override the default api url used for preview
- sed -i 's|http://localhost:3456|https://try.vikunja.io|g' dist-preview/index.html
# create via:
# `shasum -a 384 ./scripts/deploy-preview-netlify.mjs > ./scripts/deploy-preview-netlify.mjs.sha384`
- shasum -a 384 -c ./scripts/deploy-preview-netlify.mjs.sha384
@@ -973,7 +971,6 @@ steps:
- pnpm install --fetch-timeout 100000 --frozen-lockfile
- pnpm run lint
- pnpm run build
- sed -i 's/http\:\\/\\/localhost\\:3456\\/api\\/v1/\\/api\\/v1/g' dist/index.html # Override the default api url used for developing
- name: static
image: kolaente/zip
@@ -1032,7 +1029,6 @@ steps:
- npm install -g corepack && corepack enable && pnpm config set store-dir .cache/pnpm
- pnpm install --fetch-timeout 100000 --frozen-lockfile
- pnpm run build
- sed -i 's/http\:\\/\\/localhost\\:3456\\/api\\/v1/\\/api\\/v1/g' dist/index.html # Override the default api url used for developing
- name: static
image: kolaente/zip
@@ -1208,6 +1204,6 @@ steps:
---
kind: signature
hmac: 03f04eb6ba48191e7a854126243382c9ff0213f728b9f8525e74331535dd4968
hmac: 321cc0f212caa1566aa5139c8f983f0e55653ddc241e3093b24697802be733be
...

View File

@@ -9,4 +9,6 @@
# SENTRY_AUTH_TOKEN=YOUR_TOKEN
# SENTRY_ORG=vikunja
# SENTRY_PROJECT=frontend-oss
# VIKUNJA_FRONTEND_BASE=/custom-subpath
# VIKUNJA_FRONTEND_BASE=/custom-subpath
# DEV_PROXY=http://vikunja-backend.domain.tld

View File

@@ -17,7 +17,22 @@ For general information about the project, refer to the top-level readme of this
pnpm install
```
### Compiles and hot-reloads for development
### Development
#### Define backend server
You can develop the web front end against any accessible backend, including the demo at https://try.vikunja.io
In order to do so, you need to set the `DEV_PROXY` env variable. The recommended way to do so is to:
- Copy `.env.local.exemple` as `.env.local`
- Uncomment the `DEV_PROXY` line
- Set the backend url you want to use
In the end, it should look like `DEV_PROXY=https://try.vikunja.io` if you work against the online demo backend.
#### Start dev server (compiles and hot-reloads)
```shell
pnpm run dev

View File

@@ -22,7 +22,7 @@
// This variable points the frontend to the api.
// It has to be the full url, including the last /api/v1 part and port.
// You can change this if your api is not reachable on the same port as the frontend.
window.API_URL = 'http://localhost:3456/api/v1'
window.API_URL = '/api/v1'
</script>
</body>
</html>

View File

@@ -2,6 +2,12 @@
command = "pnpm run build"
publish = "dist-preview"
[[redirects]]
from = "/api/*"
to = "https://try.vikunja.io/api/:splat"
status = 200
force = true
[[redirects]]
from = "/*"
to = "/index.html"
@@ -10,6 +16,6 @@
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
X-Robots-Tag = "noindex"
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
X-Robots-Tag = "noindex"

View File

@@ -20,7 +20,8 @@ export class InvalidApiUrlProvidedError extends Error {
}
}
export const checkAndSetApiUrl = (url: string | undefined | null): Promise<string> => {
export const checkAndSetApiUrl = (pUrl: string | undefined | null): Promise<string> => {
let url = pUrl
if (url === '' || url === null || typeof url === 'undefined') {
throw new NoApiUrlProvidedError()
}
@@ -55,6 +56,7 @@ export const checkAndSetApiUrl = (url: string | undefined | null): Promise<strin
// Check if the api is reachable at the provided url
return configStore.update()
.catch(e => {
console.warn(`Could not fetch 'info' from the provided endpoint ${pUrl} on ${window.API_URL}/info. Some automatic fallback will be tried.`)
// Check if it is reachable at /api/v1 and http
if (
!urlToCheck.pathname.endsWith('/api/v1') &&

View File

@@ -66,12 +66,24 @@ function createFontMatcher(fontNames: string[]) {
}
// https://vitejs.dev/config/
export default defineConfig(({mode}) => {
export default defineConfig(({command, mode}) => {
// Load env file based on `mode` in the current working directory.
// Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
// https://vitejs.dev/config/#environment-variables
const env = loadEnv(mode, process.cwd(), '')
switch (command) {
case 'serve':
// this is DEV mode
return getServeConfig(env)
// return getBuildConfig(env)
case 'build':
// build for prodution
return getBuildConfig(env)
}
})
function getBuildConfig(env: Record<string, string>) {
return {
base: env.VIKUNJA_FRONTEND_BASE,
// https://vitest.dev/config/
@@ -220,4 +232,23 @@ export default defineConfig(({mode}) => {
},
},
}
})
}
function getServeConfig(env: Record<string, string>) {
// get some default settings from prod mod
const buildConfig = getBuildConfig(env)
// override prod settings with dev settings
return {
...buildConfig,
server: {
...buildConfig.server,
...(env.DEV_PROXY && { proxy: {
'/api': {
target: env.DEV_PROXY,
changeOrigin: true,
secure: false,
},
}}),
},
}
}