summaryrefslogtreecommitdiff
path: root/src/dev.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev.ts')
-rw-r--r--src/dev.ts92
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