Skip to content

Instantly share code, notes, and snippets.

@jcayzac
Last active August 2, 2021 07:46
Show Gist options
  • Save jcayzac/5b70026244acc3477499dbc2131c1903 to your computer and use it in GitHub Desktop.
Save jcayzac/5b70026244acc3477499dbc2131c1903 to your computer and use it in GitHub Desktop.
<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}

Loading a remote SVX into a route

/* 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