import {Express, Router} from "express"; import ApplicationComponent from "../ApplicationComponent.js"; import AssetCompiler from "../frontend/AssetCompiler.js"; import AssetPreCompiler from "../frontend/AssetPreCompiler.js"; import ViewEngine from "../frontend/ViewEngine.js"; import LazyLocalsCoreComponent from "./core/LazyLocalsCoreComponent.js"; export default class FrontendToolsComponent extends ApplicationComponent { private readonly publicDir: string; private readonly assetPreCompilers: AssetPreCompiler[]; public constructor( private readonly assetCompiler: AssetCompiler, ...assetPreCompilers: AssetPreCompiler[] ) { super(); this.assetPreCompilers = assetPreCompilers; this.publicDir = this.assetCompiler.targetDir; for (const assetPreCompiler of this.assetPreCompilers) { if (assetPreCompiler.isPublic()) { this.assetCompiler.addExtension(assetPreCompiler.getExtension()); } } } public async start(app: Express): Promise { this.hookPreCompilers(); // Setup express view engine let main = true; for (const assetPreCompiler of this.assetPreCompilers) { if (assetPreCompiler instanceof ViewEngine) { assetPreCompiler.setup(app, main, this.getApp().as(LazyLocalsCoreComponent)); main = false; } } } public async stop(): Promise { for (const assetPreCompiler of this.assetPreCompilers) { await assetPreCompiler.stop(); } } public async initRoutes(router: Router): Promise { router.use((req, res, next) => { // Request context locals res.locals.url = req.url; res.locals.params = req.params; res.locals.query = req.query; res.locals.body = req.body; next(); }); } public hookPreCompilers(): void { for (const assetPreCompiler of this.assetPreCompilers) { assetPreCompiler.onPreCompile(async watch => { await this.assetCompiler.compile(watch); }); assetPreCompiler.onInputChange(async restart => { await this.assetCompiler.stopWatching(restart); }); } } public async preCompileViews(watch: boolean): Promise { for (const viewEngine of this.assetPreCompilers) { await viewEngine.preCompileAll(watch); } await this.assetCompiler.compile(watch); if (watch) { this.hookPreCompilers(); } } }