Quote: > Vite's default browser support baseline is Native ESM, native ESM dynamic import, and import.meta. This plugin provides support for legacy browsers that do not support those features when building for production. Since all three feature now have more than 97% market share it seems fine to remove them. Reviewed-on: https://kolaente.dev/vikunja/vikunja/pulls/2921 Co-authored-by: Dominik Pschenitschni <mail@celement.de> Co-committed-by: Dominik Pschenitschni <mail@celement.de>
228 lines
6.1 KiB
TypeScript
228 lines
6.1 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(({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(), '')
|
|
|
|
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({
|
|
script: {
|
|
propsDestructure: true,
|
|
},
|
|
}),
|
|
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,
|
|
],
|
|
},
|
|
},
|
|
}
|
|
})
|