swaf/src/components/FrontendToolsComponent.ts

82 lines
2.6 KiB
TypeScript

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<void> {
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<void> {
for (const assetPreCompiler of this.assetPreCompilers) {
await assetPreCompiler.stop();
}
}
public async initRoutes(router: Router): Promise<void> {
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<void> {
for (const viewEngine of this.assetPreCompilers) {
await viewEngine.preCompileAll(watch);
}
await this.assetCompiler.compile(watch);
if (watch) {
this.hookPreCompilers();
}
}
}