feat(config): Support Setting Base Path in .env

* This uses loadEnv to load an environment file at configuration
  time.
  * Documentation:
    * https://vitejs.dev/config/#environment-variables
  * More on environment files:
    * https://vitejs.dev/guide/env-and-mode.html
  * `VIKUNJA_FRONTEND_BASE` is the variable in the environment
     file that will be used to set Vite’s base option.
* This adds a commented example to .env.local.example

Signed-off-by: Jef Oliver <jef@eljef.me>
This commit is contained in:
Jef Oliver 2023-01-24 15:27:34 -08:00 committed by kolaente
parent e92559dc00
commit af55992057
Signed by untrusted user: konrad
GPG Key ID: F40E70337AB24C9B
2 changed files with 146 additions and 134 deletions

View File

@ -1,8 +1,13 @@
# Duplicate this file and remove the '.example' suffix. # (1) Duplicate this file and remove the '.example' suffix.
# Adjust the values as needed. # Naming this file '.env.local' is a Vite convention to prevent accidentally
# submitting to git.
# For more info see: https://vitejs.dev/guide/env-and-mode.html#env-files
VITE_IS_ONLINE=true # (2) Comment in and adjust the values as needed.
VITE_WORKBOX_DEBUG=false
SENTRY_AUTH_TOKEN=YOUR_TOKEN # VITE_IS_ONLINE=true
SENTRY_ORG=vikunja # VITE_WORKBOX_DEBUG=false
SENTRY_PROJECT=frontend-oss # SENTRY_AUTH_TOKEN=YOUR_TOKEN
# SENTRY_ORG=vikunja
# SENTRY_PROJECT=frontend-oss
# VIKUNJA_FRONTEND_BASE=/custom-subpath

View File

@ -1,5 +1,5 @@
/// <reference types="vitest" /> /// <reference types="vitest" />
import {defineConfig, type PluginOption} from 'vite' import {defineConfig, type PluginOption, loadEnv} from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import legacyFn from '@vitejs/plugin-legacy' import legacyFn from '@vitejs/plugin-legacy'
import {URL, fileURLToPath} from 'node:url' import {URL, fileURLToPath} from 'node:url'
@ -49,136 +49,143 @@ function createFontMatcher(fontNames: string[]) {
} }
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig(({mode}) => {
base: process.env.VIKUNJA_FRONTEND_BASE, // Load env file based on `mode` in the current working directory.
// https://vitest.dev/config/ // Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
test: { // https://vitejs.dev/config/#environment-variables
environment: 'happy-dom', const env = loadEnv(mode, process.cwd(), '')
},
css: { return {
preprocessorOptions: { base: env.VIKUNJA_FRONTEND_BASE,
scss: { // https://vitest.dev/config/
additionalData: PREFIXED_SCSS_STYLES, test: {
charset: false, // fixes "@charset" must be the first rule in the file" warnings environment: 'happy-dom',
},
css: {
preprocessorOptions: {
scss: {
additionalData: PREFIXED_SCSS_STYLES,
charset: false, // fixes "@charset" must be the first rule in the file" warnings
},
}, },
}, postcss: {
postcss: { plugins: [
plugins: [ postcssEasings(),
postcssEasings(), postcssEasingGradients(),
postcssEasingGradients(), postcssPresetEnv(),
postcssPresetEnv(),
],
},
},
plugins: [
vue({
reactivityTransform: true,
}),
legacy,
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/vite-plugin-inject-preload
VitePluginInjectPreload({
files: [{
match: 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 Lists Overview',
short_name: 'Namespaces & Lists',
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',
},
], ],
}, },
}), },
], plugins: [
resolve: { vue({
alias: [ reactivityTransform: true,
{ }),
find: '@', legacy,
replacement: pathSrc, 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/vite-plugin-inject-preload
VitePluginInjectPreload({
files: [{
match: 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 Lists Overview',
short_name: 'Namespaces & Lists',
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',
},
],
},
}),
], ],
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], resolve: {
}, alias: [
server: { {
host: '127.0.0.1', // see: https://github.com/vitejs/vite/pull/8543 find: '@',
port: 4173, replacement: pathSrc,
strictPort: true, },
},
build: {
target: 'esnext',
rollupOptions: {
plugins: [
visualizer({
filename: 'stats.html',
gzipSize: true,
// template: 'sunburst',
// brotliSize: true,
}) as PluginOption,
], ],
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,
},
build: {
target: 'esnext',
rollupOptions: {
plugins: [
visualizer({
filename: 'stats.html',
gzipSize: true,
// template: 'sunburst',
// brotliSize: true,
}) as PluginOption,
],
},
},
}
}) })