index.ts 5.5 KB

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