vite.config.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. import { createRequire } from 'module'
  3. import type { ServerOptions } from 'https'
  4. import { defineConfig, type ResolvedConfig } from 'vite'
  5. import VuePlugin from '@vitejs/plugin-vue'
  6. import {
  7. createSvgIconsPlugin,
  8. type ViteSvgIconsPlugin,
  9. } from 'vite-plugin-svg-icons'
  10. import { VitePWA } from 'vite-plugin-pwa'
  11. import path from 'path'
  12. import fs from 'fs'
  13. import tsconfig from './tsconfig.base.json'
  14. const SSL_PATH = path.resolve(__dirname, 'config', 'ssl')
  15. export default defineConfig(({ mode, command }) => {
  16. const isStory = Boolean(process.env.HISTOIRE)
  17. const isTesting = ['test', 'cypress'].includes(mode) || isStory
  18. const isBuild = command === 'build' && !isStory
  19. const require = createRequire(import.meta.url)
  20. const svgPlugin = createSvgIconsPlugin({
  21. // Specify the directory containing all icon assets assorted by sets.
  22. iconDirs: [
  23. path.resolve(
  24. __dirname,
  25. 'app/frontend/shared/components/CommonIcon/assets',
  26. ),
  27. ],
  28. // Specify symbolId format to include directory as icon set and filename as icon name.
  29. symbolId: 'icon-[dir]-[name]',
  30. svgoOptions: {
  31. plugins: [{ name: 'preset-default' }],
  32. } as ViteSvgIconsPlugin['svgoOptions'],
  33. })
  34. if (isStory) {
  35. // Patch svg plugin for stories, because it's not working with SSR.
  36. const svgConfigResolved = svgPlugin.configResolved as (
  37. cfg: ResolvedConfig,
  38. ) => void
  39. svgConfigResolved({ command: 'build' } as ResolvedConfig)
  40. delete svgPlugin.configResolved
  41. const { load } = svgPlugin
  42. svgPlugin.load = function fakeLoad(id) {
  43. // @ts-expect-error the plugin is not updated
  44. return load?.call(this, id, true)
  45. }
  46. }
  47. const plugins = [
  48. VuePlugin({
  49. template: {
  50. compilerOptions: {
  51. nodeTransforms:
  52. isTesting || !!process.env.VITE_TEST_MODE
  53. ? []
  54. : [require('./app/frontend/build/transforms/transformTestId')],
  55. },
  56. },
  57. }),
  58. svgPlugin,
  59. ]
  60. // Ruby plugin is not needed inside of the vitest context and has some side effects.
  61. if (!isTesting || isBuild) {
  62. const { default: RubyPlugin } = require('vite-plugin-ruby')
  63. // const ManualChunks = require('./app/frontend/build/manualChunks')
  64. plugins.push(RubyPlugin())
  65. plugins.push(
  66. ...VitePWA({
  67. // should be generated on ruby side
  68. manifest: false,
  69. registerType: 'prompt',
  70. srcDir: 'apps/mobile/sw',
  71. filename: 'sw.ts',
  72. includeManifestIcons: false,
  73. injectRegister: null,
  74. strategies: 'injectManifest',
  75. }),
  76. )
  77. // TODO: Disable manual chunks for now, check if it's still neded with Vite 3.0.
  78. // plugins.push(ManualChunks())
  79. }
  80. let https: ServerOptions | false = false
  81. // vite-ruby controlls this variable, it's either "true" or "false"
  82. if (process.env.VITE_RUBY_HTTPS === 'true') {
  83. const SSL_CERT = fs.readFileSync(path.resolve(SSL_PATH, 'localhost.crt'))
  84. const SSL_KEY = fs.readFileSync(path.resolve(SSL_PATH, 'localhost.key'))
  85. https = {
  86. cert: SSL_CERT,
  87. key: SSL_KEY,
  88. }
  89. }
  90. return {
  91. esbuild: {
  92. target: tsconfig.compilerOptions.target,
  93. },
  94. resolve: {
  95. alias: {
  96. '@mobile': path.resolve(__dirname, 'app/frontend/apps/mobile'),
  97. '@shared': path.resolve(__dirname, 'app/frontend/shared'),
  98. '@tests': path.resolve(__dirname, 'app/frontend/tests'),
  99. '@stories': path.resolve(__dirname, 'app/frontend/stories'),
  100. '@cy': path.resolve(__dirname, '.cypress'),
  101. '@': path.resolve(__dirname, 'app/frontend'),
  102. '^vue-easy-lightbox$':
  103. 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js',
  104. },
  105. },
  106. server: {
  107. https,
  108. watch: {
  109. ignored: isTesting
  110. ? []
  111. : ['**/*.spec.*', '**/__tests__/**/*', 'app/frontend/tests/**/*'],
  112. },
  113. },
  114. define: {
  115. VITE_TEST_MODE: !!process.env.VITEST || !!process.env.VITE_TEST_MODE,
  116. },
  117. test: {
  118. globals: true,
  119. // narrowing down test folder speeds up fast-glob in Vitest
  120. dir: 'app/frontend',
  121. setupFiles: ['app/frontend/tests/vitest.setup.ts'],
  122. environment: 'jsdom',
  123. clearMocks: true,
  124. css: false,
  125. testTimeout: 30_000,
  126. },
  127. plugins,
  128. }
  129. })