manualChunks.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. const { splitVendorChunk } = require('vite')
  3. const graphqlChunk = ['graphql', '@apollo', '@wry']
  4. const isGraphqlChunk = (id) =>
  5. graphqlChunk.some((chunk) => id.includes(`node_modules/${chunk}`))
  6. const graphqlIds = new Set()
  7. const matchers = [
  8. {
  9. vendor: false,
  10. matcher: (id) => id === 'virtual:svg-icons-register',
  11. chunk: 'icons',
  12. },
  13. {
  14. vendor: false,
  15. matcher: (id) => id.includes('vite/preload-helper'),
  16. chunk: 'vite',
  17. },
  18. {
  19. vendor: false,
  20. matcher: (id) => id.endsWith('/routes.ts'),
  21. chunk: 'routes',
  22. },
  23. {
  24. vendor: true,
  25. matcher: (id) => id.includes('@vue/apollo'),
  26. chunk: 'apollo',
  27. },
  28. {
  29. vendor: false,
  30. matcher: (id) => id.includes('frontend/shared/server'),
  31. chunk: 'apollo',
  32. },
  33. {
  34. vendor: true,
  35. matcher: (id) => id.includes('node_modules/lodash-es'),
  36. chunk: 'lodash',
  37. },
  38. {
  39. vendor: true,
  40. matcher: (id, api) => {
  41. const { importers, dynamicImporters } = api.getModuleInfo(id)
  42. const match =
  43. graphqlIds.has(id) ||
  44. isGraphqlChunk(id) ||
  45. importers.some(isGraphqlChunk) ||
  46. dynamicImporters.some(isGraphqlChunk)
  47. if (match) {
  48. dynamicImporters.forEach(() => graphqlIds.add(id))
  49. importers.forEach(() => graphqlIds.add(id))
  50. }
  51. return match
  52. },
  53. chunk: 'graphql',
  54. },
  55. {
  56. vendor: true,
  57. matcher: (id) => /node_modules\/@?vue/.test(id),
  58. chunk: 'vue',
  59. },
  60. ]
  61. /**
  62. * @returns {import("vite").Plugin}
  63. */
  64. const PluginManualChunks = () => {
  65. const getChunk = splitVendorChunk()
  66. return {
  67. name: 'zammad:manual-chunks',
  68. // eslint-disable-next-line sonarjs/cognitive-complexity
  69. config() {
  70. return {
  71. build: {
  72. rollupOptions: {
  73. output: {
  74. manualChunks(id, api) {
  75. const chunk = getChunk(id, api)
  76. // FieldEditor is a special case, it's a dynamic import with a large dependency
  77. if (!chunk && id.includes('FieldEditor')) {
  78. return
  79. }
  80. if (!chunk) {
  81. for (const { vendor, matcher, chunk } of matchers) {
  82. if (vendor === false && matcher(id)) {
  83. return chunk
  84. }
  85. }
  86. }
  87. if (chunk !== 'vendor') return chunk
  88. for (const { vendor, matcher, chunk } of matchers) {
  89. if (vendor === true && matcher(id, api)) {
  90. return chunk
  91. }
  92. }
  93. return 'vendor'
  94. },
  95. },
  96. },
  97. },
  98. }
  99. },
  100. }
  101. }
  102. module.exports = PluginManualChunks