From 6da5502000ea8af5a55bed9a42ddb15f4aacca89 Mon Sep 17 00:00:00 2001 From: lingbopro Date: Sun, 15 Dec 2024 20:14:29 +0800 Subject: [PATCH] chore: add server script --- dev/scripts/lib/consts.mjs | 28 +++++++++++++ dev/scripts/lib/server.mjs | 82 ++++++++++++++++++++++++++++++++++++++ dev/scripts/script.mjs | 2 + package.json | 2 + 4 files changed, 114 insertions(+) create mode 100644 dev/scripts/lib/consts.mjs create mode 100644 dev/scripts/lib/server.mjs diff --git a/dev/scripts/lib/consts.mjs b/dev/scripts/lib/consts.mjs new file mode 100644 index 0000000..d867049 --- /dev/null +++ b/dev/scripts/lib/consts.mjs @@ -0,0 +1,28 @@ +export const MIMETypes = { + apng: 'image/apng', + avif: 'image/avif', + bin: 'application/octet-stream', + css: 'text/css', + csv: 'text/csv', + htm: 'text/html', + html: 'text/html', + ico: 'image/vnd.microsoft.icon', + jpeg: 'image/jpeg', + jpg: 'image/jpeg', + js: 'text/javascript', + json: 'application/json', + mjs: 'text/javascript', + otf: 'font/otf', + png: 'image/png', + sh: 'application/x-sh', + svg: 'image/svg+xml', + tar: 'application/x-tar', + ttf: 'font/ttf', + txt: 'text/plain', + webp: 'image/webp', + woff: 'font/woff', + woff2: 'font/woff2', + xhtml: 'application/xhtml+xml', + xml: 'application/xml', + zip: 'application/zip', +}; diff --git a/dev/scripts/lib/server.mjs b/dev/scripts/lib/server.mjs new file mode 100644 index 0000000..9fd36ac --- /dev/null +++ b/dev/scripts/lib/server.mjs @@ -0,0 +1,82 @@ +import fs from 'fs'; +import { fileURLToPath } from 'node:url'; +import path from 'path'; +import http from 'http'; +import { debug, log, logError, logSuccess, isSubDir } from './utils.mjs'; +import { main as watch, cleanup as watchCleanup } from './watch.mjs'; +import { MIMETypes } from './consts.mjs'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const root = path.resolve(__dirname, '../../..'); + +const port = 5114; +let server; + +export async function main(options) { + log('starting server...'); + server = http.createServer(async (req, res) => { + debug(`Got request: ${req.method} '${req.url}'`); + const url = '.' + req.url; + const filePath = path.join(root, url); + const extension = path.extname(filePath).slice(1); + if (req.method === 'GET') { + if (req.url === '/') { + res.writeHead(302, { Location: '/demos/index.html' }); + res.end(); + return; + } + if (!fs.existsSync(filePath)) { + res.writeHead(404); + res.end(`Cannot ${req.method} ${req.url}: Not Found`); + return; + } + if (!(await fs.promises.lstat(filePath)).isFile()) { + res.writeHead(404); + res.end(`Cannot ${req.method} ${req.url}: Is not a file`); + return; + } + const mimeType = MIMETypes[extension] || 'text/plain'; + res.setHeader('Content-Type', mimeType); + res.setHeader('X-Real-File-Path', filePath); + fs.createReadStream(filePath).pipe(res); + return; + } else { + res.writeHead(405); + res.end(`Cannot ${req.method} ${req.url}: Method Not Allowed`); + return; + } + }); + server.listen(port); + logSuccess(`server listening on port ${port}`); + log('Starting watch...'); + await watch(options); +} +export async function execute(options) { + const startTime = new Date(); + try { + await main(options); + } catch (error) { + logError('an uncaught exception was encountered'); + logError('details:'); + console.error(error); + } + logSuccess(`done in ${(new Date() - startTime) / 1000}s`); +} +export async function cleanup(options) { + server.close(); + logSuccess('server stopped'); + await watchCleanup(options); +} + +export const docs = ` +Usage: server [options] + +Options: + (the following options are being passed to 'watch' script) + --no-finally-clean Do not clean up temp directory after build + --no-min-bundle Do not generate minified bundle + + Examples: + $ pnpm scripts server`; diff --git a/dev/scripts/script.mjs b/dev/scripts/script.mjs index ba23da7..7f50e9e 100644 --- a/dev/scripts/script.mjs +++ b/dev/scripts/script.mjs @@ -5,10 +5,12 @@ import { debug, log, logError, logSuccess } from './lib/utils.mjs'; import * as buildScript from './lib/build.mjs'; import * as watchScript from './lib/watch.mjs'; +import * as serverScript from './lib/server.mjs'; const scripts = { build: buildScript, watch: watchScript, + server: serverScript, }; const argv = process.argv.slice(2); diff --git a/package.json b/package.json index d4f5466..a2a8fd5 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,10 @@ }, "scripts": { "build": "node dev/scripts/script.mjs build", + "dev": "node dev/scripts/script.mjs server --no-min-bundle", "prepare": "husky", "script": "node dev/scripts/script.mjs", + "serve": "node dev/scripts/script.mjs server", "watch": "node dev/scripts/script.mjs watch", "watch:dev": "node dev/scripts/script.mjs watch --no-min-bundle" },