Last active
August 2, 2021 07:46
-
-
Save jcayzac/5b70026244acc3477499dbc2131c1903 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script context="module" lang="ts"> | |
import type { Load } from '@sveltejs/kit' | |
export const load: Load = async ({ page, fetch }) => { | |
const response = await fetch(`/article-${page.params.slug}`) | |
const content = await response.json() | |
return { | |
props: { | |
content: content, | |
}, | |
} | |
} | |
</script> | |
<script> | |
export let content | |
</script> | |
<svelte:head> | |
{@html content.head} | |
</svelte:head> | |
{@html content.html} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable unicorn/filename-case */ | |
/* eslint-disable unicorn/prefer-node-protocol */ | |
/* eslint-disable unicorn/prefer-module */ | |
import { dev } from '$app/env' | |
import type { RequestHandler } from '@sveltejs/kit' | |
import { promises, readFileSync } from 'fs' | |
import { createRequire } from 'module' | |
import { preprocess, compile } from 'svelte/compiler' | |
import ts from 'typescript' | |
const { readFile } = promises | |
const dynamicImportDefault = new Function( | |
`url`, | |
`return import(url + '?t=' + Date.now()).then(m => m.default)`, | |
) | |
const BASE_PATH = process.cwd() | |
const BUILD_DESTINATION = `${BASE_PATH}/build/app.js` | |
const SVELTE_CONFIG_PATH = `${BASE_PATH}/svelte.config.js` | |
const TYPESCRIPT_CONFIG_PATH = `${BASE_PATH}/tsconfig.json` | |
const TYPESCRIPT_CONFIG = ts.readConfigFile(TYPESCRIPT_CONFIG_PATH, ts.sys.readFile).config | |
const TYPESCRIPT_COMPILER_OPTIONS = (() => { | |
const config = Object.assign({}, TYPESCRIPT_CONFIG) | |
config.include = [] | |
config.files = [] | |
const { options } = ts.parseJsonConfigFileContent( | |
config, | |
ts.sys, | |
BASE_PATH, | |
{ sourceMap: false }, | |
TYPESCRIPT_CONFIG_PATH, | |
) | |
return options | |
})() | |
const compileSource = (source, filename) => { | |
const compiled = compile(source, { | |
format: 'cjs', | |
generate: 'ssr', | |
hydratable: false, | |
filename, | |
}).js.code.replace(/"\$lib\//g, `"${BASE_PATH}/src/lib/`) | |
console.info(`COMPILED[${filename}]:\n${compiled}`) | |
return compiled | |
} | |
export const get: RequestHandler = async request => { | |
if (!request.path.startsWith('/article-')) return | |
const path = `/articles/${request.path.slice(9)}/index.svx` | |
const filename = `${BASE_PATH}${path}` | |
const [source, svelteConfig] = await Promise.all([ | |
readFile(filename, 'utf-8'), | |
dynamicImportDefault(`file://${SVELTE_CONFIG_PATH}`), | |
]) | |
const preprocessors = svelteConfig.preprocess | |
const preprocessed = | |
preprocessors !== undefined | |
? (await preprocess(source, preprocessors, { filename })).code | |
: source | |
const compiled = compileSource(preprocessed, filename) as any as string | |
const require = createRequire(dev ? import.meta.url : BUILD_DESTINATION) | |
require.extensions['.svelte'] = (module: any, fileName) => { | |
// .svelte source code | |
const source = readFileSync(fileName, 'utf-8') | |
// transpile lang='ts' blocks | |
const transpiled = source.replace( | |
/<script([^>]+)lang=["']ts["']([^>]*)>(.*?)<\/script>/gs, | |
(m, h1, h2, source) => { | |
return ` | |
<script${h1}${h2}> | |
${ts.transpile(source, TYPESCRIPT_COMPILER_OPTIONS, fileName)} | |
</script> | |
` | |
}, | |
) | |
// compile | |
const compiled = compileSource(transpiled, fileName) | |
return module._compile(compiled, fileName) | |
} | |
const module = { | |
exports: { | |
default: undefined, | |
}, | |
require, | |
} | |
const exports = module.exports | |
eval(compiled) | |
const rendered = exports.default.render() | |
return { | |
body: rendered, | |
headers: { 'content-type': 'application/json' }, | |
status: 200, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment