updateHtml.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { readFileSync, writeFileSync, existsSync } from 'fs-extra';
  2. import viteConfig, { htmlConfig } from '../../vite.config';
  3. import { getCwdPath, successConsole, errorConsole } from '../utils';
  4. import { GLOB_CONFIG_FILE_NAME } from '../constant';
  5. import { hmScript } from './hm';
  6. import HtmlMinifier from 'html-minifier';
  7. const pkg = require('../../package.json');
  8. const { title, addHm, cdnConf, useCdn, minify } = htmlConfig;
  9. function injectTitle(html: string, htmlTitle: string) {
  10. if (/<\/title>/.test(html)) {
  11. return html.replace(/<\/title>/, `${htmlTitle}</title>`);
  12. }
  13. return html;
  14. }
  15. function injectConfigScript(html: string) {
  16. const tag = `\t\t<script src='${viteConfig.base || './'}${GLOB_CONFIG_FILE_NAME}?v=${
  17. pkg.version
  18. }-${new Date().getTime()}'></script>`;
  19. if (/<\/head>/.test(html)) {
  20. return html.replace(/<\/head>/, `${tag}\n\t\t</head>`);
  21. }
  22. return html;
  23. }
  24. function injectHmScript(html: string) {
  25. if (/<head>/.test(html)) {
  26. return html.replace(/<head>/, `<head>\n${hmScript}`);
  27. }
  28. return html;
  29. }
  30. function injectCdnCss(html: string) {
  31. if (!cdnConf) return html;
  32. const { css } = cdnConf;
  33. if (!css || css.length === 0) return html;
  34. let cdnCssTag = '';
  35. for (const cssLink of css) {
  36. cdnCssTag += `<link rel="stylesheet" href="${cssLink}">`;
  37. }
  38. if (/<\/head>/.test(html)) {
  39. return html.replace(/<\/head>/, `${cdnCssTag}\n\t\t</head>`);
  40. }
  41. return html;
  42. }
  43. function injectCdnjs(html: string) {
  44. if (!cdnConf) return html;
  45. const { js } = cdnConf;
  46. if (!js || js.length === 0) return html;
  47. let cdnJsTag = '';
  48. for (const src of js) {
  49. // TODO
  50. // <script type="importmap">
  51. // { "imports": {
  52. // "vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0/vue.esm-browser.js",
  53. // "vue-router": "https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.0-alpha.13/vue-router.esm.js",
  54. // "vuex": "https://cdnjs.cloudflare.com/ajax/libs/vuex/4.0.0-beta.2/vuex.esm-browser.js"
  55. // } }
  56. // </script>
  57. cdnJsTag += `\t<script type="text/javascript" src="${src}"></script>\n`;
  58. }
  59. if (/<\/body>/.test(html)) {
  60. return html.replace(/<\/body>/, `${cdnJsTag}\n</body>`);
  61. }
  62. return html;
  63. }
  64. export async function runUpdateHtml() {
  65. const outDir = viteConfig.outDir || 'dist';
  66. const indexPath = getCwdPath(outDir, 'index.html');
  67. if (!existsSync(`${indexPath}`)) {
  68. return;
  69. }
  70. try {
  71. let processedHtml = '';
  72. const rawHtml = readFileSync(indexPath, 'utf-8');
  73. processedHtml = rawHtml;
  74. processedHtml = injectTitle(processedHtml, title);
  75. processedHtml = injectConfigScript(processedHtml);
  76. if (addHm) {
  77. processedHtml = injectHmScript(processedHtml);
  78. }
  79. if (useCdn) {
  80. processedHtml = injectCdnCss(processedHtml);
  81. processedHtml = injectCdnjs(processedHtml);
  82. }
  83. if (minify) {
  84. const { enable, ...miniOpt } = minify;
  85. processedHtml = HtmlMinifier.minify(processedHtml, miniOpt);
  86. }
  87. writeFileSync(indexPath, processedHtml);
  88. successConsole('Update Html Successfully!');
  89. } catch (error) {
  90. errorConsole('Update Html Error\n' + error);
  91. }
  92. }