index.ts 5.8 KB

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