views: delete target file or re-precompile on file remove

This commit is contained in:
Alice Gaudon 2021-05-13 14:11:10 +02:00
parent c1c7b8920d
commit fac59e12d6
3 changed files with 39 additions and 20 deletions

View File

@ -1,5 +1,5 @@
import chokidar, {FSWatcher} from "chokidar";
import {existsSync, mkdirSync} from "fs";
import {existsSync, mkdirSync, promises as fs} from "fs";
import path from "path";
import {logger} from "../Logger.js";
@ -121,19 +121,11 @@ export default abstract class AssetPreCompiler {
this.watcher.on('add', (file) => {
this.onNewFile(file)
.then(() => this.preCompile(this.toCanonicalName(file), true))
.then(() => {
return this.afterPreCompile(true);
})
.catch(err => logger.error(err));
});
this.watcher.on('change', (file) => {
(this.onFileChange ? this.onFileChange(file) : Promise.resolve())
.then(() => this.preCompile(this.toCanonicalName(file), true))
.then(() => {
return this.afterPreCompile(true);
})
this.onFileChange(file)
.catch(err => logger.error(err));
});
@ -144,13 +136,34 @@ export default abstract class AssetPreCompiler {
});
}
public async onNewFile(_file: string): Promise<void> {
public async onNewFile(file: string): Promise<void> {
logger.silly('a', file);
const canonicalName = this.toCanonicalName(file);
await this.preCompile(canonicalName, true);
await this.afterPreCompile(true);
await this.inputChangeHandler?.(false);
}
public onFileChange?(file: string): Promise<void>;
public async onFileChange(file: string): Promise<void> {
logger.silly('c', file);
const canonicalName = this.toCanonicalName(file);
await this.preCompile(canonicalName, true);
await this.afterPreCompile(true);
}
public async onFileRemove(file: string): Promise<void> {
logger.silly('r', file);
const canonicalName = this.toCanonicalName(file);
const replacementSourceFile = await this.resolveFileFromCanonicalName(canonicalName);
if (replacementSourceFile) {
await this.preCompile(canonicalName, true);
await this.afterPreCompile(true);
} else {
const targetFile = path.resolve(this.targetDir, canonicalName);
await fs.rm(targetFile);
}
public async onFileRemove(_file: string): Promise<void> {
await this.inputChangeHandler?.(true);
}
@ -172,7 +185,7 @@ export default abstract class AssetPreCompiler {
return canonicalViewName;
}
protected async resolveFileFromCanonicalName(canonicalName: string): Promise<string> {
protected async resolveFileFromCanonicalName(canonicalName: string): Promise<string | null> {
for (const viewPath of this.assetPaths) {
const tryPath = path.join(viewPath, canonicalName);
if (await doesFileExist(tryPath)) {
@ -180,6 +193,12 @@ export default abstract class AssetPreCompiler {
}
}
throw new Error('View not found from canonical name ' + canonicalName);
return null;
}
protected async resolveFileFromCanonicalNameOrFail(canonicalName: string): Promise<string> {
const file = await this.resolveFileFromCanonicalName(canonicalName);
if (file) return file;
else throw new Error('View not found from canonical name ' + canonicalName);
}
}

View File

@ -22,7 +22,7 @@ export default class CopyAssetPreCompiler extends AssetPreCompiler {
}
public async preCompile(canonicalName: string): Promise<void> {
const inputFile = await this.resolveFileFromCanonicalName(canonicalName);
const inputFile = await this.resolveFileFromCanonicalNameOrFail(canonicalName);
const outputFile = path.join(this.actualTargetDir, canonicalName);
logger.info('Copying', inputFile, '->', outputFile);
await fs.mkdir(path.dirname(outputFile), {recursive: true});

View File

@ -41,6 +41,7 @@ export default class SvelteViewEngine extends ViewEngine {
public async onFileChange(file: string): Promise<void> {
delete this.preprocessingCache[this.toCanonicalName(file)];
await super.onFileChange(file);
}
public async onFileRemove(file: string): Promise<void> {
@ -62,7 +63,7 @@ export default class SvelteViewEngine extends ViewEngine {
const view = await this.fileCache.get(actualFile, !config.get<boolean>('view.cache'));
// Root template
const templateFile = await this.resolveFileFromCanonicalName('layouts/svelte_layout.html');
const templateFile = await this.resolveFileFromCanonicalNameOrFail('layouts/svelte_layout.html');
const rawOutput = await this.fileCache.get(templateFile, !config.get<boolean>('view.cache'));
// Pre-compiled parts
@ -95,10 +96,9 @@ export default class SvelteViewEngine extends ViewEngine {
}
public async preCompile(canonicalName: string, alsoCompileDependents: boolean): Promise<void> {
const file = await this.resolveFileFromCanonicalName(canonicalName);
const intermediateFile = path.join(this.targetDir, canonicalName);
logger.info(canonicalName + ' > ', 'Pre-compiling', file, '->', intermediateFile);
logger.info(canonicalName + ' > ', 'Pre-compiling', canonicalName, '->', intermediateFile);
const allBackendCalls: string[] = [];
@ -157,7 +157,7 @@ export default class SvelteViewEngine extends ViewEngine {
return this.preprocessingCache[canonicalName];
}
const file = await this.resolveFileFromCanonicalName(canonicalName);
const file = await this.resolveFileFromCanonicalNameOrFail(canonicalName);
logger.info(canonicalName + ' > ', `Preprocessing ${file}`);
// mkdir output file dir