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 chokidar, {FSWatcher} from "chokidar";
|
||||||
import {existsSync, mkdirSync,promises as fs} from "fs";
|
import {existsSync, mkdirSync} from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
import {logger} from "../Logger.js";
|
import {logger} from "../Logger.js";
|
||||||
|
@ -73,25 +73,7 @@ export default class SvelteViewEngine extends ViewEngine {
|
|||||||
css,
|
css,
|
||||||
] = view.split(SvelteViewEngine.getPreCompileSeparator(canonicalViewName));
|
] = view.split(SvelteViewEngine.getPreCompileSeparator(canonicalViewName));
|
||||||
|
|
||||||
const localMap: Record<string, unknown> = {};
|
const localMap: Record<string, unknown> = this.compileBackendCalls(backendCalls.split('\n'), locals, false);
|
||||||
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 actualLocals = JSON.stringify(localMap, (key, value) => {
|
const actualLocals = JSON.stringify(localMap, (key, value) => {
|
||||||
return typeof value === 'function' ?
|
return typeof value === 'function' ?
|
||||||
value.toString() :
|
value.toString() :
|
||||||
@ -128,7 +110,7 @@ export default class SvelteViewEngine extends ViewEngine {
|
|||||||
allBackendCalls.push(...backendCalls);
|
allBackendCalls.push(...backendCalls);
|
||||||
|
|
||||||
// Server Side Render (initial HTML and CSS, no-js)
|
// 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 separator = SvelteViewEngine.getPreCompileSeparator(canonicalName);
|
||||||
const finalCode = [
|
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,
|
head: string,
|
||||||
css: CssResult,
|
css: CssResult,
|
||||||
html: string,
|
html: string,
|
||||||
@ -297,8 +279,9 @@ export default class SvelteViewEngine extends ViewEngine {
|
|||||||
const localsModulePath = "../../build/ts/stores.js";
|
const localsModulePath = "../../build/ts/stores.js";
|
||||||
const localsModule = await import(localsModulePath);
|
const localsModule = await import(localsModulePath);
|
||||||
const locals = ViewEngine.getGlobals();
|
const locals = ViewEngine.getGlobals();
|
||||||
|
const localMap = this.compileBackendCalls(backendCalls, locals, true);
|
||||||
localsModule.locals.set((key: string, args: string) => {
|
localsModule.locals.set((key: string, args: string) => {
|
||||||
return locals[args ?
|
return localMap[args ?
|
||||||
`'${key}', \`${args}\``
|
`'${key}', \`${args}\``
|
||||||
: `'${key}'`];
|
: `'${key}'`];
|
||||||
});
|
});
|
||||||
@ -308,6 +291,35 @@ export default class SvelteViewEngine extends ViewEngine {
|
|||||||
clearModule.single(moduleId);
|
clearModule.single(moduleId);
|
||||||
return requireFromString(svelteSsr.js.code, moduleId).default.render();
|
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 = {
|
type PreprocessingCacheEntry = {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import {Express} from "express";
|
import {Express} from "express";
|
||||||
|
|
||||||
import {logger} from "../Logger.js";
|
|
||||||
import AssetPreCompiler from "./AssetPreCompiler.js";
|
import AssetPreCompiler from "./AssetPreCompiler.js";
|
||||||
|
|
||||||
export default abstract class ViewEngine extends AssetPreCompiler {
|
export default abstract class ViewEngine extends AssetPreCompiler {
|
||||||
|
Loading…
Reference in New Issue
Block a user