vite.config.mjs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. /* eslint-disable security/detect-non-literal-fs-filename */
  3. import { createRequire } from 'module'
  4. import { readFileSync } from 'node:fs'
  5. import { resolve, dirname } from 'node:path'
  6. import { fileURLToPath } from 'node:url'
  7. import { homedir } from 'os'
  8. import VuePlugin from '@vitejs/plugin-vue'
  9. import { defineConfig } from 'vite'
  10. import { VitePWA } from 'vite-plugin-pwa'
  11. import tailwindcss from '@tailwindcss/vite'
  12. import svgIconsPlugin from './app/frontend/build/iconsPlugin.mjs'
  13. import ManualChunksPlugin from './app/frontend/build/manualChunks.mjs'
  14. import tsconfig from './tsconfig.base.json' with { type: 'json' }
  15. const dir = dirname(fileURLToPath(import.meta.url))
  16. const SSL_PATH = resolve(homedir(), '.local/state/localhost.rb')
  17. const isEnvBooleanSet = (value) => ['true', '1'].includes(value)
  18. // eslint-disable-next-line sonarjs/cognitive-complexity
  19. export default defineConfig(({ mode, command }) => {
  20. const isTesting = ['test', 'cypress'].includes(mode)
  21. const isBuild = command === 'build'
  22. const require = createRequire(import.meta.url)
  23. const plugins = [
  24. tailwindcss(),
  25. VuePlugin({
  26. template: {
  27. compilerOptions: {
  28. nodeTransforms:
  29. isTesting || isEnvBooleanSet(process.env.VITE_TEST_MODE)
  30. ? []
  31. : [require('./app/frontend/build/transforms/transformTestId.js')],
  32. },
  33. },
  34. }),
  35. svgIconsPlugin(),
  36. ]
  37. if (!isTesting || isBuild) {
  38. // Ruby plugin is not needed inside of the vitest context and has some side effects.
  39. const { default: RubyPlugin } = require('vite-plugin-ruby')
  40. plugins.push(RubyPlugin())
  41. plugins.push(
  42. ...VitePWA({
  43. disable: isTesting || isEnvBooleanSet(process.env.VITE_TEST_MODE),
  44. // should be generated on ruby side
  45. manifest: false,
  46. registerType: 'prompt',
  47. srcDir: 'apps/mobile/sw',
  48. filename: 'sw.ts',
  49. includeManifestIcons: false,
  50. injectRegister: null,
  51. strategies: 'injectManifest',
  52. }),
  53. )
  54. plugins.push(ManualChunksPlugin())
  55. }
  56. let https = false
  57. // vite-ruby controlls this variable, it's either "true" or "false"
  58. if (isEnvBooleanSet(process.env.VITE_RUBY_HTTPS)) {
  59. const SSL_CERT = readFileSync(resolve(SSL_PATH, 'localhost.crt'))
  60. const SSL_KEY = readFileSync(resolve(SSL_PATH, 'localhost.key'))
  61. https = {
  62. cert: SSL_CERT,
  63. key: SSL_KEY,
  64. }
  65. }
  66. let publicDir
  67. if (!isBuild) {
  68. publicDir = resolve(dir, 'public')
  69. }
  70. return {
  71. publicDir,
  72. esbuild: {
  73. target: isTesting ? 'esnext' : tsconfig.compilerOptions.target,
  74. },
  75. resolve: {
  76. preserveSymlinks: isEnvBooleanSet(process.env.PRESERVE_SYMLINKS),
  77. alias: {
  78. '^vue-easy-lightbox$':
  79. 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js',
  80. },
  81. },
  82. server: {
  83. https,
  84. watch: {
  85. ignored: isTesting
  86. ? []
  87. : [
  88. '**/*.spec.*',
  89. '**/__tests__/**/*',
  90. (path) =>
  91. !path.includes('app/frontend') ||
  92. path.includes('frontend/tests'),
  93. ],
  94. },
  95. },
  96. define: {
  97. VITE_TEST_MODE:
  98. isEnvBooleanSet(process.env.VITEST) ||
  99. isEnvBooleanSet(process.env.VITE_TEST_MODE),
  100. },
  101. test: {
  102. globals: true,
  103. // narrowing down test folder speeds up fast-glob in Vitest
  104. dir: 'app/frontend',
  105. setupFiles: ['app/frontend/tests/vitest.setup.ts'],
  106. environment: 'jsdom',
  107. clearMocks: true,
  108. css: false,
  109. testTimeout: isEnvBooleanSet(process.env.CI) ? 30_000 : 5_000,
  110. unstubGlobals: true,
  111. onConsoleLog(log) {
  112. if (
  113. log.includes('Not implemented: navigation') ||
  114. log.includes('<Suspense> is an experimental feature')
  115. )
  116. return false
  117. },
  118. },
  119. plugins,
  120. }
  121. })