2025-02-28 10:52:04 -05:00
import { dirname , resolve } from 'node:path'
2026-01-06 16:23:17 +02:00
import { fileURLToPath } from 'node:url'
2025-02-28 10:52:04 -05:00
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
2026-01-06 16:23:17 +02:00
import { defineConfig } from 'vite'
2025-02-28 15:15:28 -05:00
import eslint from 'vite-plugin-eslint2'
2026-01-06 16:23:17 +02:00
import stylelint from 'vite-plugin-stylelint'
2026-01-08 16:48:27 +02:00
import { configDefaults } from 'vitest/config'
2026-01-08 17:26:52 +02:00
2026-01-06 16:23:17 +02:00
import { getCommitHash } from './build/commit_hash.js'
import copyPlugin from './build/copy_plugin.js'
2025-03-09 16:18:27 -04:00
import emojisPlugin from './build/emojis_plugin.js'
2026-01-06 16:23:17 +02:00
import mswPlugin from './build/msw_plugin.js'
2026-01-06 16:22:52 +02:00
import {
buildSwPlugin ,
2026-01-06 16:23:17 +02:00
devSwPlugin ,
2026-01-06 16:22:52 +02:00
swMessagesPlugin ,
} from './build/sw_plugin.js'
2025-02-28 10:52:04 -05:00
2025-02-28 13:29:27 -05:00
const localConfigPath = '<projectRoot>/config/local.json'
2026-01-07 09:44:50 +04:00
const normalizeTarget = ( target ) => {
if ( ! target || typeof target !== 'string' ) return target
return target . endsWith ( '/' ) ? target . replace ( /\/$/ , '' ) : target
}
2025-02-28 10:52:04 -05:00
const getLocalDevSettings = async ( ) => {
2026-01-07 09:44:50 +04:00
const envTarget = normalizeTarget ( process . env . VITE _PROXY _TARGET )
const envOrigin = normalizeTarget ( process . env . VITE _PROXY _ORIGIN )
2025-02-28 10:52:04 -05:00
try {
const settings = ( await import ( './config/local.json' ) ) . default
2026-01-07 09:44:50 +04:00
settings . target = normalizeTarget ( settings . target )
settings . origin = normalizeTarget ( settings . origin )
if ( envTarget ) settings . target = envTarget
if ( envOrigin ) settings . origin = envOrigin
2025-02-28 13:29:27 -05:00
console . info ( ` Using local dev server settings ( ${ localConfigPath } ): ` )
2025-02-28 10:52:04 -05:00
console . info ( JSON . stringify ( settings , null , 2 ) )
return settings
} catch ( e ) {
2026-01-07 09:44:50 +04:00
if ( ! envTarget && ! envOrigin ) {
2026-01-08 16:48:27 +02:00
console . info (
` Local dev server settings not found ( ${ localConfigPath } ), using default ` ,
e ,
)
2026-01-07 09:44:50 +04:00
return { }
}
const settings = { target : envTarget , origin : envOrigin }
2026-01-06 16:22:52 +02:00
console . info (
2026-01-08 16:48:27 +02:00
'Using dev server settings from VITE_PROXY_TARGET/VITE_PROXY_ORIGIN:' ,
2026-01-06 16:22:52 +02:00
)
2026-01-07 09:44:50 +04:00
console . info ( JSON . stringify ( settings , null , 2 ) )
return settings
2025-02-28 10:52:04 -05:00
}
}
const projectRoot = dirname ( fileURLToPath ( import . meta . url ) )
2025-02-28 13:29:27 -05:00
const getTransformSWSettings = ( settings ) => {
if ( 'transformSW' in settings ) {
return settings . transformSW
} else {
console . info (
'`transformSW` is not present in your local settings.\n' +
'This option controls whether the service worker should be bundled and transformed into iife (immediately-invoked function expression) during development.\n' +
'If set to false, the service worker will be served as-is, as an ES Module.\n' +
'Some browsers (e.g. Firefox) does not support ESM service workers.\n' +
'To avoid surprises, it is defaulted to true, but this can be slow.\n' +
'If you are using a browser that supports ESM service workers, you can set this option to false.\n' +
2026-01-06 16:22:52 +02:00
` No matter your choice, you can set the transformSW option in ${ localConfigPath } in to disable this message. ` ,
2025-02-28 13:29:27 -05:00
)
return true
}
}
2025-02-27 22:54:23 -05:00
export default defineConfig ( async ( { mode , command } ) => {
2025-02-28 10:52:04 -05:00
const settings = await getLocalDevSettings ( )
const target = settings . target || 'http://localhost:4000/'
2026-01-07 09:44:50 +04:00
const origin = settings . origin || target
2025-02-28 13:29:27 -05:00
const transformSW = getTransformSWSettings ( settings )
2025-02-28 10:52:04 -05:00
const proxy = {
'/api' : {
target ,
changeOrigin : true ,
cookieDomainRewrite : 'localhost' ,
2026-01-06 16:22:52 +02:00
ws : true ,
2025-02-28 10:52:04 -05:00
} ,
'/nodeinfo' : {
target ,
changeOrigin : true ,
2026-01-06 16:22:52 +02:00
cookieDomainRewrite : 'localhost' ,
2025-02-28 10:52:04 -05:00
} ,
'/socket' : {
target ,
changeOrigin : true ,
cookieDomainRewrite : 'localhost' ,
ws : true ,
headers : {
2026-01-08 16:48:27 +02:00
Origin : origin ,
2026-01-06 16:22:52 +02:00
} ,
2025-02-28 10:52:04 -05:00
} ,
'/oauth' : {
target ,
changeOrigin : true ,
2026-01-06 16:22:52 +02:00
cookieDomainRewrite : 'localhost' ,
} ,
2025-02-28 10:52:04 -05:00
}
const swSrc = 'src/sw.js'
const swDest = 'sw-pleroma.js'
2025-02-28 13:29:27 -05:00
const alias = {
src : '/src' ,
components : '/src/components' ,
2026-01-06 16:22:52 +02:00
... ( mode === 'test' ? { vue : 'vue/dist/vue.esm-bundler.js' } : { } ) ,
2025-02-28 13:29:27 -05:00
}
2025-02-28 10:52:04 -05:00
return {
plugins : [
vue ( {
template : {
compilerOptions : {
isCustomElement ( tag ) {
if ( tag === 'pinch-zoom' ) {
return true
}
2025-03-30 17:06:19 +03:00
if ( tag . startsWith ( 'cropper-' ) ) {
return true
}
2025-02-28 10:52:04 -05:00
return false
2026-01-06 16:22:52 +02:00
} ,
} ,
} ,
2025-02-28 10:52:04 -05:00
} ) ,
vueJsx ( ) ,
2025-02-28 13:29:27 -05:00
devSwPlugin ( { swSrc , swDest , transformSW , alias } ) ,
2025-02-28 10:52:04 -05:00
buildSwPlugin ( { swSrc , swDest } ) ,
2025-02-26 20:23:10 -05:00
swMessagesPlugin ( ) ,
2025-03-09 16:18:27 -04:00
emojisPlugin ( ) ,
2025-02-26 20:23:10 -05:00
copyPlugin ( {
inUrl : '/static/ruffle' ,
2026-01-06 16:22:52 +02:00
inFs : resolve ( projectRoot , 'node_modules/@ruffle-rs/ruffle' ) ,
2025-02-28 15:15:28 -05:00
} ) ,
eslint ( {
lintInWorker : true ,
lintOnStart : true ,
2026-01-06 16:22:52 +02:00
cacheLocation : resolve ( projectRoot , 'node_modules/.cache/eslintcache' ) ,
2025-02-28 15:15:28 -05:00
} ) ,
stylelint ( {
lintInWorker : true ,
lintOnStart : true ,
2026-01-06 16:22:52 +02:00
cacheLocation : resolve (
projectRoot ,
'node_modules/.cache/stylelintcache' ,
) ,
2025-03-09 15:06:19 -04:00
} ) ,
2026-01-06 16:22:52 +02:00
... ( mode === 'test' ? [ mswPlugin ( ) ] : [ ] ) ,
2025-02-28 10:52:04 -05:00
] ,
2025-02-28 16:08:36 -05:00
optimizeDeps : {
// For unknown reasons, during vitest, vite will re-optimize the following
// deps, causing the test to reload, so add them here so that it will not
// reload during tests
include : [
'custom-event-polyfill' ,
'vue-i18n' ,
'@ungap/event-target' ,
'lodash.merge' ,
'body-scroll-lock' ,
2026-01-06 16:22:52 +02:00
'@kazvmoe-infra/pinch-zoom-element' ,
] ,
2025-02-28 16:08:36 -05:00
} ,
2025-02-28 14:26:27 -05:00
css : {
2026-01-06 16:22:52 +02:00
devSourcemap : true ,
2025-02-28 14:26:27 -05:00
} ,
2025-02-28 10:52:04 -05:00
resolve : {
2026-01-06 16:22:52 +02:00
alias ,
2025-02-28 10:52:04 -05:00
} ,
define : {
'process.env' : JSON . stringify ( {
2026-01-06 16:22:52 +02:00
NODE _ENV :
mode === 'test'
? 'testing'
: command === 'serve'
? 'development'
: 'production' ,
HAS _MODULE _SERVICE _WORKER : command === 'serve' && ! transformSW ,
2025-02-28 10:52:04 -05:00
} ) ,
2026-01-06 16:22:52 +02:00
COMMIT _HASH : JSON . stringify (
command === 'serve' ? 'DEV' : getCommitHash ( ) ,
) ,
DEV _OVERRIDES : JSON . stringify ( command === 'serve' ? settings : undefined ) ,
_ _VUE _OPTIONS _API _ _ : true ,
_ _VUE _PROD _DEVTOOLS _ _ : false ,
_ _VUE _PROD _HYDRATION _MISMATCH _DETAILS _ _ : false ,
2025-02-28 10:52:04 -05:00
} ,
build : {
sourcemap : true ,
rollupOptions : {
input : {
2026-01-06 16:22:52 +02:00
main : 'index.html' ,
2025-02-28 10:52:04 -05:00
} ,
output : {
inlineDynamicImports : false ,
2026-01-06 16:22:52 +02:00
entryFileNames ( chunkInfo ) {
2025-02-28 10:52:04 -05:00
const id = chunkInfo . facadeModuleId
if ( id . endsWith ( swSrc ) ) {
return swDest
} else {
return 'static/js/[name].[hash].js'
}
} ,
2026-01-06 16:22:52 +02:00
chunkFileNames ( chunkInfo ) {
2025-03-04 18:39:20 -05:00
if ( chunkInfo . facadeModuleId ) {
2026-01-06 16:22:52 +02:00
if (
chunkInfo . facadeModuleId . includes (
'node_modules/@kazvmoe-infra/unicode-emoji-json/annotations/' ,
)
) {
2025-03-04 18:39:20 -05:00
return 'static/js/emoji-annotations/[name].[hash].js'
} else if ( chunkInfo . facadeModuleId . includes ( 'src/i18n/' ) ) {
return 'static/js/i18n/[name].[hash].js'
}
}
2025-02-28 10:52:04 -05:00
return 'static/js/[name].[hash].js'
} ,
2026-01-06 16:22:52 +02:00
assetFileNames ( assetInfo ) {
2025-02-28 10:52:04 -05:00
const name = assetInfo . names ? . [ 0 ] || ''
if ( /\.(png|jpe?g|gif|svg)(\?.*)?$/ . test ( name ) ) {
return 'static/img/[name].[hash][extname]'
} else if ( /\.css$/ . test ( name ) ) {
return 'static/css/[name].[hash][extname]'
} else {
return 'static/misc/[name].[hash][extname]'
}
2026-01-06 16:22:52 +02:00
} ,
} ,
2025-02-28 10:52:04 -05:00
} ,
} ,
server : {
2025-02-27 22:54:23 -05:00
... ( mode === 'test' ? { } : { proxy } ) ,
2026-01-06 16:22:52 +02:00
port : Number ( process . env . PORT ) || 8080 ,
2025-02-28 10:52:04 -05:00
} ,
preview : {
2026-01-06 16:22:52 +02:00
proxy ,
2025-02-27 22:54:23 -05:00
} ,
test : {
globals : true ,
2026-01-08 16:48:27 +02:00
exclude : [ ... configDefaults . exclude , 'test/e2e-playwright/**' ] ,
2025-02-27 22:54:23 -05:00
browser : {
enabled : true ,
provider : 'playwright' ,
2026-01-06 16:22:52 +02:00
instances : [ { browser : 'firefox' } ] ,
} ,
} ,
2025-02-28 10:52:04 -05:00
}
} )