index.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import fs from "node:fs/promises";
  2. import {constants} from "node:fs";
  3. import path from "path";
  4. import htmlMinifier from "html-minifier-terser";
  5. import esbuild from "esbuild";
  6. const srcRoot = path.join(import.meta.dirname, "src");
  7. const main = (options)=> {
  8. fs.mkdir(path.join(import.meta.dirname, ".build"), {recursive: true});
  9. readFiles(srcRoot);
  10. }
  11. const readFiles = async (dir)=>{
  12. const files = await fs.readdir(dir, {withFileTypes: true});
  13. for(let i = 0; i < files.length; i++){
  14. let curDir = path.join(dir, files[i].name);
  15. if(files[i].isDirectory()) {
  16. readFiles(curDir);
  17. }
  18. }
  19. parse(dir);
  20. }
  21. const parse = async (dir)=>{
  22. const htmlFile = path.join(dir, "index.html");
  23. const cssFile = path.join(dir, "index.css");
  24. const jsFile = path.join(dir, "index.js");
  25. const buildFiles = [];
  26. const checkFiles = [
  27. fs.readFile(htmlFile, "utf-8"),
  28. fs.access(cssFile, constants.F_OK),
  29. fs.access(jsFile, constants.F_OK)
  30. ];
  31. let [html, isCss, isJs] = await Promise.allSettled(checkFiles);
  32. if(html.status !== "fulfilled") return;
  33. isCss = isCss.status === "fulfilled";
  34. isJs = isJs.status === "fulfilled";
  35. if(isCss) buildFiles.push(cssFile);
  36. if(isJs) buildFiles.push(jsFile);
  37. html = await htmlMinifier.minify(html.value, {
  38. collapseBooleanAttributes: true,
  39. collapseInlineTagWhitespace: true,
  40. collapseWhitespace: true,
  41. conservativeCollapse: true,
  42. decodeEntities: true,
  43. noNewlinesBeforeTagClose: true,
  44. removeComments: true
  45. });
  46. const esbuildProm = await esbuild.build({
  47. entryPoints: buildFiles,
  48. bundle: true,
  49. minify: true,
  50. write: false,
  51. outdir: dir
  52. });
  53. if(isCss && isJs){
  54. html = insert(html, esbuildProm.outputFiles[0].text, "css");
  55. html = insert(html, esbuildProm.outputFiles[1].text, "js");
  56. }else if(isCss){
  57. html = insert(html, esbuildProm.outputFiles[0].text, "css");
  58. }else if(isJs){
  59. html = insert(html, esbuildProm.outputFiles[0].text, "js");
  60. }
  61. const writeFile = `${dir.replace("/src", "/.build")}/index.html`;
  62. console.log(writeFile);
  63. console.log(html);
  64. fs.writeFile(writeFile, html);
  65. }
  66. const insert = (html, insertString, type)=>{
  67. let locationIndex, openTag, closeTag;
  68. switch(type){
  69. case "css":
  70. locationIndex = html.indexOf("</head>");
  71. openTag = "<style>"
  72. closeTag = "</style>"
  73. break;
  74. case "js":
  75. locationIndex = html.indexOf("</body>");
  76. openTag = "<script>";
  77. closeTag = "</script>"
  78. break;
  79. }
  80. return `${html.slice(0, locationIndex)}${openTag}${insertString}${closeTag}${html.slice(locationIndex)}`;
  81. }
  82. main();