index.ts 6.3 KB

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