Svelte view engine: also compile backend calls on SSR
Add local to determine whether render is SSR or not
This commit is contained in:
parent
b247d73fcb
commit
85b4b39dd2
@ -1,5 +1,5 @@
|
||||
import chokidar, {FSWatcher} from "chokidar";
|
||||
import {existsSync, mkdirSync,promises as fs} from "fs";
|
||||
import {existsSync, mkdirSync} from "fs";
|
||||
import path from "path";
|
||||
|
||||
import {logger} from "../Logger.js";
|
||||
|
@ -73,25 +73,7 @@ export default class SvelteViewEngine extends ViewEngine {
|
||||
css,
|
||||
] = view.split(SvelteViewEngine.getPreCompileSeparator(canonicalViewName));
|
||||
|
||||
const localMap: Record<string, unknown> = {};
|
||||
backendCalls.split('\n').forEach(code => {
|
||||
const key = code.substring(1, code.indexOf(',') >= 0 ? code.indexOf(',') - 1 : code.length - 1);
|
||||
if (code.indexOf('`[') >= 0) {
|
||||
const args = code.substring(code.indexOf('`[') + 2, code.length - 2)
|
||||
.split(/, *?/)
|
||||
.map(arg => {
|
||||
if (arg.startsWith("'")) return '"' + arg.substring(1, arg.length - 1) + '"';
|
||||
return arg;
|
||||
})
|
||||
.map(arg => Function(`"use strict";const locals = arguments[0];return (${arg});`)(locals)); // Uses named parameter locals
|
||||
|
||||
const f = locals[key];
|
||||
if (typeof f !== 'function') throw new Error(key + ' is not a function.');
|
||||
localMap[`'${key}', \`[${code.substring(code.indexOf('`[') + 2, code.length - 2)}]\``] = f.call(locals, ...args);
|
||||
} else {
|
||||
localMap[`'${key}'`] = locals[key];
|
||||
}
|
||||
});
|
||||
const localMap: Record<string, unknown> = this.compileBackendCalls(backendCalls.split('\n'), locals, false);
|
||||
const actualLocals = JSON.stringify(localMap, (key, value) => {
|
||||
return typeof value === 'function' ?
|
||||
value.toString() :
|
||||
@ -128,7 +110,7 @@ export default class SvelteViewEngine extends ViewEngine {
|
||||
allBackendCalls.push(...backendCalls);
|
||||
|
||||
// Server Side Render (initial HTML and CSS, no-js)
|
||||
const ssr = await this.compileSsr(canonicalName, intermediateFile, code);
|
||||
const ssr = await this.compileSsr(canonicalName, intermediateFile, code, allBackendCalls);
|
||||
|
||||
const separator = SvelteViewEngine.getPreCompileSeparator(canonicalName);
|
||||
const finalCode = [
|
||||
@ -279,7 +261,7 @@ export default class SvelteViewEngine extends ViewEngine {
|
||||
};
|
||||
}
|
||||
|
||||
private async compileSsr(canonicalName: string, file: string, code: string): Promise<{
|
||||
private async compileSsr(canonicalName: string, file: string, code: string, backendCalls: string[]): Promise<{
|
||||
head: string,
|
||||
css: CssResult,
|
||||
html: string,
|
||||
@ -297,8 +279,9 @@ export default class SvelteViewEngine extends ViewEngine {
|
||||
const localsModulePath = "../../build/ts/stores.js";
|
||||
const localsModule = await import(localsModulePath);
|
||||
const locals = ViewEngine.getGlobals();
|
||||
const localMap = this.compileBackendCalls(backendCalls, locals, true);
|
||||
localsModule.locals.set((key: string, args: string) => {
|
||||
return locals[args ?
|
||||
return localMap[args ?
|
||||
`'${key}', \`${args}\``
|
||||
: `'${key}'`];
|
||||
});
|
||||
@ -308,6 +291,35 @@ export default class SvelteViewEngine extends ViewEngine {
|
||||
clearModule.single(moduleId);
|
||||
return requireFromString(svelteSsr.js.code, moduleId).default.render();
|
||||
}
|
||||
|
||||
private compileBackendCalls(
|
||||
backendCalls: string[],
|
||||
locals: Record<string, unknown>,
|
||||
isPreRender: boolean,
|
||||
): Record<string, unknown> {
|
||||
locals = {...locals, isPreRender};
|
||||
|
||||
const localMap: Record<string, unknown> = {};
|
||||
backendCalls.forEach(code => {
|
||||
const key = code.substring(1, code.indexOf(',') >= 0 ? code.indexOf(',') - 1 : code.length - 1);
|
||||
if (code.indexOf('`[') >= 0) {
|
||||
const args = code.substring(code.indexOf('`[') + 2, code.length - 2)
|
||||
.split(/, *?/)
|
||||
.map(arg => {
|
||||
if (arg.startsWith("'")) return '"' + arg.substring(1, arg.length - 1) + '"';
|
||||
return arg;
|
||||
})
|
||||
.map(arg => Function(`"use strict";const $locals = arguments[0];return (${arg});`)(locals)); // Uses named parameter locals
|
||||
|
||||
const f = locals[key];
|
||||
if (typeof f !== 'function') throw new Error(key + ' is not a function.');
|
||||
localMap[`'${key}', \`[${code.substring(code.indexOf('`[') + 2, code.length - 2)}]\``] = f.call(locals, ...args);
|
||||
} else {
|
||||
localMap[`'${key}'`] = locals[key];
|
||||
}
|
||||
});
|
||||
return localMap;
|
||||
}
|
||||
}
|
||||
|
||||
type PreprocessingCacheEntry = {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {Express} from "express";
|
||||
|
||||
import {logger} from "../Logger.js";
|
||||
import AssetPreCompiler from "./AssetPreCompiler.js";
|
||||
|
||||
export default abstract class ViewEngine extends AssetPreCompiler {
|
||||
|
Loading…
Reference in New Issue
Block a user