mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-03-11 17:48:44 -05:00
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>
255 lines
6.7 KiB
TypeScript
255 lines
6.7 KiB
TypeScript
/// <reference types="vitest" />
|
|
import {defineConfig, type PluginOption, loadEnv} from 'vite'
|
|
import {configDefaults} from 'vitest/config'
|
|
import vue from '@vitejs/plugin-vue'
|
|
import {URL, fileURLToPath} from 'node:url'
|
|
import {dirname, resolve} from 'node:path'
|
|
|
|
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
|
|
import {VitePWA} from 'vite-plugin-pwa'
|
|
import UnpluginInjectPreload from 'unplugin-inject-preload/vite'
|
|
import {visualizer} from 'rollup-plugin-visualizer'
|
|
|
|
import viteSentry, {type ViteSentryPluginOptions} from 'vite-plugin-sentry'
|
|
import svgLoader from 'vite-svg-loader'
|
|
import postcssPresetEnv from 'postcss-preset-env'
|
|
import postcssEasingGradients from 'postcss-easing-gradients'
|
|
import tailwindcss from 'tailwindcss'
|
|
import vueDevTools from 'vite-plugin-vue-devtools'
|
|
|
|
const pathSrc = fileURLToPath(new URL('./src', import.meta.url)).replaceAll('\\', '/')
|
|
|
|
// the @use rules have to be the first in the compiled stylesheets
|
|
const PREFIXED_SCSS_STYLES = `@use "sass:math";
|
|
@import "${pathSrc}/styles/common-imports.scss";`
|
|
|
|
/*
|
|
** Configure sentry plugin
|
|
*/
|
|
function getSentryConfig(env: ImportMetaEnv): ViteSentryPluginOptions {
|
|
return {
|
|
skipEnvironmentCheck: true,
|
|
|
|
url: 'https://sentry.io',
|
|
authToken: env.SENTRY_AUTH_TOKEN,
|
|
org: env.SENTRY_ORG,
|
|
project: env.SENTRY_PROJECT,
|
|
cleanSourcemapsAfterUpload: true,
|
|
legacyErrorHandlingMode: true,
|
|
deploy: {
|
|
env: env.MODE,
|
|
},
|
|
setCommits: {
|
|
auto: true,
|
|
ignoreMissing: true,
|
|
},
|
|
sourceMaps: {
|
|
include: ['./dist/assets'],
|
|
ignore: ['node_modules'],
|
|
urlPrefix: '~/assets',
|
|
},
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param fontNames Array of the file names of the fonts without axis and hash suffixes
|
|
*/
|
|
function createFontMatcher(fontNames: string[]) {
|
|
// The `match` option for the files of VitePluginInjectPreload
|
|
// matches the _output_ files.
|
|
// Since we only want to mach variable fonts, we exploit here the fact
|
|
// that we added the `wght` term to indicate the variable weight axis.
|
|
// The format is something like:
|
|
// `/assets/OpenSans-Italic_wght__c9a8fe68-5f21f1e7.woff2`
|
|
// see: https://regex101.com/r/UgUWr1/1
|
|
return new RegExp(`^.+\\/(${fontNames.join('|')})_wght__[a-z1-9]{8}-[a-z1-9]{8}\\.woff2$`)
|
|
}
|
|
|
|
// https://vitejs.dev/config/
|
|
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/
|
|
test: {
|
|
environment: 'happy-dom',
|
|
exclude: [...configDefaults.exclude, 'e2e/**'],
|
|
'vitest.commandLine': 'pnpm test:unit',
|
|
},
|
|
css: {
|
|
preprocessorOptions: {
|
|
sass: {
|
|
quietDeps: true, // silence deprecation warnings
|
|
},
|
|
scss: {
|
|
additionalData: PREFIXED_SCSS_STYLES,
|
|
charset: false, // fixes "@charset" must be the first rule in the file" warnings,
|
|
quietDeps: true, // silence deprecation warnings
|
|
},
|
|
},
|
|
postcss: {
|
|
plugins: [
|
|
tailwindcss(),
|
|
postcssEasingGradients(),
|
|
postcssPresetEnv(),
|
|
],
|
|
},
|
|
},
|
|
plugins: [
|
|
vue(),
|
|
svgLoader({
|
|
// Since the svgs are already manually optimized via https://jakearchibald.github.io/svgomg/
|
|
// we don't need to optimize them again.
|
|
svgo: false,
|
|
}),
|
|
VueI18nPlugin({
|
|
// TODO: only install needed stuff
|
|
// Whether to install the full set of APIs, components, etc. provided by Vue I18n.
|
|
// By default, all of them will be installed.
|
|
fullInstall: true,
|
|
include: resolve(dirname(pathSrc), './src/i18n/lang/**'),
|
|
}),
|
|
// https://github.com/Applelo/unplugin-inject-preload
|
|
UnpluginInjectPreload({
|
|
files: [{
|
|
outputMatch: createFontMatcher(['Quicksand', 'OpenSans', 'OpenSans-Italic']),
|
|
attributes: {crossorigin: 'anonymous'},
|
|
}],
|
|
injectTo: 'custom',
|
|
}),
|
|
VitePWA({
|
|
srcDir: 'src',
|
|
filename: 'sw.ts',
|
|
strategies: 'injectManifest',
|
|
injectRegister: false,
|
|
manifest: {
|
|
name: 'Vikunja',
|
|
short_name: 'Vikunja',
|
|
theme_color: '#1973ff',
|
|
icons: [
|
|
{
|
|
src: './images/icons/android-chrome-192x192.png',
|
|
sizes: '192x192',
|
|
type: 'image/png',
|
|
},
|
|
{
|
|
src: './images/icons/android-chrome-512x512.png',
|
|
sizes: '512x512',
|
|
type: 'image/png',
|
|
},
|
|
{
|
|
src: './images/icons/icon-maskable.png',
|
|
sizes: '1024x1024',
|
|
type: 'image/png',
|
|
purpose: 'maskable',
|
|
},
|
|
],
|
|
start_url: '.',
|
|
display: 'standalone',
|
|
background_color: '#000000',
|
|
shortcuts: [
|
|
{
|
|
name: 'Overview',
|
|
url: '/',
|
|
},
|
|
{
|
|
name: 'Namespaces And Projects Overview',
|
|
short_name: 'Namespaces & Projects',
|
|
url: '/namespaces',
|
|
},
|
|
{
|
|
name: 'Tasks Next Week',
|
|
short_name: 'Next Week',
|
|
url: '/tasks/by/week',
|
|
},
|
|
{
|
|
name: 'Tasks Next Month',
|
|
short_name: 'Next Month',
|
|
url: '/tasks/by/month',
|
|
},
|
|
{
|
|
name: 'Teams Overview',
|
|
short_name: 'Teams',
|
|
url: '/teams',
|
|
},
|
|
],
|
|
},
|
|
}),
|
|
vueDevTools({
|
|
launchEditor: env.VUE_DEVTOOLS_LAUNCH_EDITOR || 'code',
|
|
}),
|
|
viteSentry(getSentryConfig(env)),
|
|
],
|
|
resolve: {
|
|
alias: [
|
|
{
|
|
find: '@',
|
|
replacement: pathSrc,
|
|
},
|
|
],
|
|
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
|
|
},
|
|
server: {
|
|
host: '127.0.0.1', // see: https://github.com/vitejs/vite/pull/8543
|
|
port: 4173,
|
|
strictPort: true,
|
|
},
|
|
output: {
|
|
manualChunks: {
|
|
// by putting tracking related stuff in a separated file we try to prevent unwanted blocking from ad-blockers
|
|
sentry: ['./src/sentry.ts', '@sentry/vue', '@sentry/tracing'],
|
|
},
|
|
},
|
|
build: {
|
|
target: 'esnext',
|
|
// required for sentry debugging: tells vite to create source maps
|
|
sourcemap: Boolean(env.SENTRY_AUTH_TOKEN),
|
|
rollupOptions: {
|
|
plugins: [
|
|
visualizer({
|
|
filename: 'stats.html',
|
|
gzipSize: true,
|
|
// template: 'sunburst',
|
|
// brotliSize: true,
|
|
}) as PluginOption,
|
|
],
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
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,
|
|
},
|
|
}}),
|
|
},
|
|
}
|
|
}
|