vite.config.mjs 3.9 KB

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