index.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. import type { PluginOption } from 'vite';
  2. import type {
  3. ApplicationPluginOptions,
  4. CommonPluginOptions,
  5. ConditionPlugin,
  6. LibraryPluginOptions,
  7. } from '../typing';
  8. import viteVueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
  9. import tailwindcss from '@tailwindcss/vite';
  10. import viteVue from '@vitejs/plugin-vue';
  11. import viteVueJsx from '@vitejs/plugin-vue-jsx';
  12. import { visualizer as viteVisualizerPlugin } from 'rollup-plugin-visualizer';
  13. import viteCompressPlugin from 'vite-plugin-compression';
  14. import viteDtsPlugin from 'vite-plugin-dts';
  15. import { createHtmlPlugin as viteHtmlPlugin } from 'vite-plugin-html';
  16. import { VitePWA } from 'vite-plugin-pwa';
  17. import viteVueDevTools from 'vite-plugin-vue-devtools';
  18. import { viteArchiverPlugin } from './archiver';
  19. import { viteExtraAppConfigPlugin } from './extra-app-config';
  20. import { viteImportMapPlugin } from './importmap';
  21. import { viteInjectAppLoadingPlugin } from './inject-app-loading';
  22. import { viteMetadataPlugin } from './inject-metadata';
  23. import { viteLicensePlugin } from './license';
  24. import { viteNitroMockPlugin } from './nitro-mock';
  25. import { vitePrintPlugin } from './print';
  26. import { viteTailwindReferencePlugin } from './tailwind-reference';
  27. import { viteVxeTableImportsPlugin } from './vxe-table';
  28. /**
  29. * 获取条件成立的 vite 插件
  30. * @param conditionPlugins
  31. */
  32. async function loadConditionPlugins(conditionPlugins: ConditionPlugin[]) {
  33. const plugins: PluginOption[] = [];
  34. for (const conditionPlugin of conditionPlugins) {
  35. if (conditionPlugin.condition) {
  36. const realPlugins = await conditionPlugin.plugins();
  37. plugins.push(...realPlugins);
  38. }
  39. }
  40. return plugins.flat();
  41. }
  42. /**
  43. * 根据条件获取通用的vite插件
  44. */
  45. async function loadCommonPlugins(
  46. options: CommonPluginOptions,
  47. ): Promise<ConditionPlugin[]> {
  48. const { devtools, injectMetadata, isBuild, visualizer } = options;
  49. return [
  50. {
  51. condition: true,
  52. plugins: () => [
  53. viteVue({
  54. script: {
  55. defineModel: true,
  56. // propsDestructure: true,
  57. },
  58. }),
  59. viteVueJsx(),
  60. viteTailwindReferencePlugin(),
  61. tailwindcss(),
  62. ],
  63. },
  64. {
  65. condition: !isBuild && devtools,
  66. plugins: () => [viteVueDevTools()],
  67. },
  68. {
  69. condition: injectMetadata,
  70. plugins: async () => [await viteMetadataPlugin()],
  71. },
  72. {
  73. condition: isBuild && !!visualizer,
  74. plugins: () => [
  75. viteVisualizerPlugin({
  76. filename: './node_modules/.cache/visualizer/stats.html',
  77. gzipSize: true,
  78. open: true,
  79. }) as PluginOption,
  80. ],
  81. },
  82. ];
  83. }
  84. /**
  85. * 根据条件获取应用类型的vite插件
  86. */
  87. async function loadApplicationPlugins(
  88. options: ApplicationPluginOptions,
  89. ): Promise<PluginOption[]> {
  90. // 单独取,否则commonOptions拿不到
  91. const isBuild = options.isBuild;
  92. const env = options.env;
  93. const {
  94. archiver,
  95. archiverPluginOptions,
  96. compress,
  97. compressTypes,
  98. extraAppConfig,
  99. html,
  100. i18n,
  101. importmap,
  102. importmapOptions,
  103. injectAppLoading,
  104. license,
  105. nitroMock,
  106. nitroMockOptions,
  107. print,
  108. printInfoMap,
  109. pwa,
  110. pwaOptions,
  111. vxeTableLazyImport,
  112. ...commonOptions
  113. } = options;
  114. const commonPlugins = await loadCommonPlugins(commonOptions);
  115. return await loadConditionPlugins([
  116. ...commonPlugins,
  117. {
  118. condition: i18n,
  119. plugins: async () => {
  120. return [
  121. viteVueI18nPlugin({
  122. compositionOnly: true,
  123. fullInstall: true,
  124. runtimeOnly: true,
  125. }),
  126. ];
  127. },
  128. },
  129. {
  130. condition: print,
  131. plugins: async () => {
  132. return [await vitePrintPlugin({ infoMap: printInfoMap })];
  133. },
  134. },
  135. {
  136. condition: vxeTableLazyImport,
  137. plugins: async () => {
  138. return [await viteVxeTableImportsPlugin()];
  139. },
  140. },
  141. {
  142. condition: nitroMock,
  143. plugins: async () => {
  144. return [await viteNitroMockPlugin(nitroMockOptions)];
  145. },
  146. },
  147. {
  148. condition: injectAppLoading,
  149. plugins: async () => [await viteInjectAppLoadingPlugin(!!isBuild, env)],
  150. },
  151. {
  152. condition: license,
  153. plugins: async () => [await viteLicensePlugin()],
  154. },
  155. {
  156. condition: pwa,
  157. plugins: () =>
  158. VitePWA({
  159. injectRegister: false,
  160. workbox: {
  161. globPatterns: [],
  162. },
  163. ...pwaOptions,
  164. manifest: {
  165. display: 'standalone',
  166. start_url: '/',
  167. theme_color: '#ffffff',
  168. ...pwaOptions?.manifest,
  169. },
  170. }),
  171. },
  172. {
  173. condition: isBuild && !!compress,
  174. plugins: () => {
  175. const compressPlugins: PluginOption[] = [];
  176. if (compressTypes?.includes('brotli')) {
  177. compressPlugins.push(
  178. viteCompressPlugin({ deleteOriginFile: false, ext: '.br' }),
  179. );
  180. }
  181. if (compressTypes?.includes('gzip')) {
  182. compressPlugins.push(
  183. viteCompressPlugin({ deleteOriginFile: false, ext: '.gz' }),
  184. );
  185. }
  186. return compressPlugins;
  187. },
  188. },
  189. {
  190. condition: !!html,
  191. plugins: () => [viteHtmlPlugin({ minify: true })],
  192. },
  193. {
  194. condition: isBuild && importmap,
  195. plugins: () => {
  196. return [viteImportMapPlugin(importmapOptions)];
  197. },
  198. },
  199. {
  200. condition: isBuild && extraAppConfig,
  201. plugins: async () => [
  202. await viteExtraAppConfigPlugin({ isBuild: true, root: process.cwd() }),
  203. ],
  204. },
  205. {
  206. condition: archiver,
  207. plugins: async () => {
  208. return [await viteArchiverPlugin(archiverPluginOptions)];
  209. },
  210. },
  211. ]);
  212. }
  213. /**
  214. * 根据条件获取库类型的vite插件
  215. */
  216. async function loadLibraryPlugins(
  217. options: LibraryPluginOptions,
  218. ): Promise<PluginOption[]> {
  219. // 单独取,否则commonOptions拿不到
  220. const isBuild = options.isBuild;
  221. const { dts, ...commonOptions } = options;
  222. const commonPlugins = await loadCommonPlugins(commonOptions);
  223. return await loadConditionPlugins([
  224. ...commonPlugins,
  225. {
  226. condition: isBuild && !!dts,
  227. plugins: () => [viteDtsPlugin({ logLevel: 'error' })],
  228. },
  229. ]);
  230. }
  231. export {
  232. loadApplicationPlugins,
  233. loadLibraryPlugins,
  234. viteArchiverPlugin,
  235. viteCompressPlugin,
  236. viteDtsPlugin,
  237. viteHtmlPlugin,
  238. viteVisualizerPlugin,
  239. viteVxeTableImportsPlugin,
  240. };