1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
import type { AstroConfig } from './@types/astro';
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 (astroConfig: AstroConfig) {
const { projectRoot, hmxRoot } = astroConfig;
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 snowpackConfig = await loadConfiguration(
{
root: projectRoot.pathname,
mount: {
[hmxRoot.pathname]: '/_hmx',
[internalPath.pathname]: '/__hmx_internal__',
},
plugins: [['astro/snowpack-plugin', hmxPlugOptions]],
devOptions: {
open: 'none',
output: 'stream',
port: 0,
},
packageOptions: {
knownEntrypoints: ['preact-render-to-string'],
external: ['@vue/server-renderer'],
},
},
snowpackConfigPath.pathname
);
const snowpack = await startSnowpackServer({
config: snowpackConfig,
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}/`);
});
}
|