diff options
Diffstat (limited to 'src/dev.ts')
-rw-r--r-- | src/dev.ts | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/dev.ts b/src/dev.ts new file mode 100644 index 000000000..a90f4c839 --- /dev/null +++ b/src/dev.ts @@ -0,0 +1,92 @@ +import type { MagicConfig } from './@types/magicthing'; +import { loadConfiguration, startServer as startSnowpackServer } from 'snowpack'; +import { existsSync, promises as fsPromises } from 'fs'; +import http from 'http'; +import { createRequire } from 'module'; + +const { readFile } = fsPromises; + +const require = createRequire(import.meta.url); + +const hostname = '127.0.0.1'; +const port = 3000; + +export default async function(magicConfig: MagicConfig) { + const { projectRoot, hmxRoot } = magicConfig; + + const internalPath = new URL('./frontend/', import.meta.url); + const snowpackConfigPath = new URL('./snowpack.config.js', projectRoot); + + // Workaround for SKY-251 + const hmxPlugOptions: {resolve?: (s: string) => string } = {}; + if(existsSync(new URL('./package-lock.json', projectRoot))) { + const pkgLockStr = await readFile(new URL('./package-lock.json', projectRoot), 'utf-8'); + const pkgLock = JSON.parse(pkgLockStr); + hmxPlugOptions.resolve = (pkgName: string) => { + const ver = pkgLock.dependencies[pkgName].version; + return `/_snowpack/pkg/${pkgName}.v${ver}.js`; + }; + } + + const config = await loadConfiguration({ + root: projectRoot.pathname, + mount: { + [hmxRoot.pathname]: '/_hmx', + [internalPath.pathname]: '/__hmx_internal__' + }, + plugins: [ + ['hmx-v2/snowpack-plugin', hmxPlugOptions] + ], + //exclude: [`${internalPath.pathname}**/*`], + devOptions: {open: 'none', output: 'stream'}, + packageOptions: { + knownEntrypoints: ['preact-render-to-string'], + external: ['@vue/server-renderer'] + } + }, snowpackConfigPath.pathname); + const snowpack = await startSnowpackServer({config, lockfile: null}); + const runtime = snowpack.getServerRuntime(); + + const server = http.createServer(async (req, res) => { + const fullurl = new URL(req.url || '/', 'https://example.org/'); + const reqPath = decodeURI(fullurl.pathname); + const selectedPage = (reqPath.substr(1) || 'index'); + console.log(reqPath, selectedPage); + + const selectedPageLoc = new URL(`./pages/${selectedPage}.hmx`, hmxRoot); + const selectedPageMdLoc = new URL(`./pages/${selectedPage}.md`, hmxRoot); + const selectedPageUrl = `/_hmx/pages/${selectedPage}.js`; + + // Non-hmx pages + if (!existsSync(selectedPageLoc) && !existsSync(selectedPageMdLoc)) { + try { + const result = await snowpack.loadUrl(reqPath); + if(result.contentType) { + res.setHeader('Content-Type', result.contentType); + } + res.write(result.contents); + res.end(); + } catch(err) { + console.log('Not found', reqPath); + res.statusCode = 404; + res.setHeader('Content-Type', 'text/plain'); + res.end('Not Found'); + } + return; + } + + try { + const mod = await runtime.importModule(selectedPageUrl); + const html = await mod.exports.default(); + res.statusCode = 200; + res.setHeader('Content-Type', 'text/html; charset=utf-8'); + res.end(html); + } catch (err) { + console.log(err); + } + }); + + server.listen(port, hostname, () => { + console.log(`Server running at http://${hostname}:${port}/`); + }); +}
\ No newline at end of file |