index.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import fs from "node:fs/promises";
  2. import path from "path";
  3. import {constants} from "node:fs";
  4. import parseComponent from "./parseComponent.js";
  5. export default async (express, options)=>{
  6. let opts = {
  7. production: true,
  8. routesDir: "routes",
  9. assetsDir: "assets",
  10. assetsRoute: "/assets"
  11. };
  12. Object.assign(opts, options)
  13. let app = express();
  14. console.time("Build time");
  15. await fs.rm(path.join(process.cwd(), ".build/"), {recursive: true, force: true});
  16. let root = path.join(process.cwd(), opts.routesDir);
  17. await addRoute(root, root, app, opts);
  18. app.use(opts.assetsRoute, express.static(opts.assetsDir));
  19. console.timeEnd("Build time");
  20. return app;
  21. }
  22. const addRoute = async (dir, root, app, opts)=>{
  23. const files = await fs.readdir(dir, {withFileTypes: true});
  24. const indexFile = await findIndexFile(dir);
  25. if(!indexFile) return;
  26. let route = dir.replace(root, "");
  27. route = route === "" ? "/" : route;
  28. if(opts.production){
  29. const bundle = await parseComponent(indexFile);
  30. const bundleLocation = dir.replace(opts.routesDir, ".build");
  31. const htmlPath = path.join(bundleLocation, "index.html");
  32. await fs.mkdir(bundleLocation, {recursive: true});
  33. await fs.writeFile(htmlPath, bundle);
  34. app.get(route, async (req, res)=>{res.sendFile(htmlPath, {dotfiles: "allow"})});
  35. }else{
  36. app.get(route, async (req, res)=>{res.send(await parseComponent(indexFile))});
  37. }
  38. fs.rm(path.join(dir, "tmp/"), {recursive: true, force: true});
  39. for(let i = 0; i < files.length; i++){
  40. const curDir = path.join(dir, files[i].name);
  41. if(files[i].isDirectory()) {
  42. await addRoute(curDir, root, app, opts);
  43. }
  44. }
  45. }
  46. const findIndexFile = async (dir)=>{
  47. const neovanPath = path.join(dir, "index.neovan");
  48. const htmlPath = path.join(dir, "index.html");
  49. const [neovan, html] = await Promise.allSettled([
  50. fs.access(path.join(dir, "index.neovan"), constants.F_OK),
  51. fs.access(path.join(dir, "index.html"), constants.F_OK)
  52. ]);
  53. if(neovan.status === "fulfilled") return neovanPath;
  54. if(html.status === "fulfilled") return htmlPath;
  55. return null;
  56. }