index.ts 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import type { PluginOption } from 'vite';
  2. import fs from 'node:fs';
  3. import fsp from 'node:fs/promises';
  4. import { join } from 'node:path';
  5. import { fileURLToPath } from 'node:url';
  6. import { readPackageJSON } from '@vben/node-utils';
  7. /**
  8. * 用于生成将loading样式注入到项目中
  9. * 为多app提供loading样式,无需在每个 app -> index.html单独引入
  10. */
  11. async function viteInjectAppLoadingPlugin(
  12. isBuild: boolean,
  13. env: Record<string, any> = {},
  14. loadingTemplate = 'loading.html',
  15. ): Promise<PluginOption | undefined> {
  16. const loadingHtml = await getLoadingRawByHtmlTemplate(loadingTemplate);
  17. const { version } = await readPackageJSON(process.cwd());
  18. const envRaw = isBuild ? 'prod' : 'dev';
  19. const cacheName = `'${env.VITE_APP_NAMESPACE}-${version}-${envRaw}-preferences-theme'`;
  20. // 获取缓存的主题
  21. // 保证黑暗主题下,刷新页面时,loading也是黑暗主题
  22. const injectScript = `
  23. <script data-app-loading="inject-js">
  24. var theme = localStorage.getItem(${cacheName});
  25. document.documentElement.classList.toggle('dark', /dark/.test(theme));
  26. </script>
  27. `;
  28. if (!loadingHtml) {
  29. return;
  30. }
  31. return {
  32. enforce: 'pre',
  33. name: 'vite:inject-app-loading',
  34. transformIndexHtml: {
  35. handler(html) {
  36. const re = /<body\s*>/;
  37. html = html.replace(re, `<body>${injectScript}${loadingHtml}`);
  38. return html;
  39. },
  40. order: 'pre',
  41. },
  42. };
  43. }
  44. /**
  45. * 用于获取loading的html模板
  46. */
  47. async function getLoadingRawByHtmlTemplate(loadingTemplate: string) {
  48. // 支持在app内自定义loading模板,模版参考default-loading.html即可
  49. let appLoadingPath = join(process.cwd(), loadingTemplate);
  50. if (!fs.existsSync(appLoadingPath)) {
  51. const __dirname = fileURLToPath(new URL('.', import.meta.url));
  52. appLoadingPath = join(__dirname, './default-loading.html');
  53. }
  54. return await fsp.readFile(appLoadingPath, 'utf8');
  55. }
  56. export { viteInjectAppLoadingPlugin };