UNPKG

@iridium/dev-server

Version:
89 lines (72 loc) 2.53 kB
const url = require('url'); const http = require('http'); const qs = require('querystring'); const dir = process.cwd(); const fs = require('fs'); const { join, resolve } = require('path'); const chokidar = require('chokidar'); const nowDir = resolve(`${dir}/now.json`); const lambdas = {}; function requireUncached(pkg) { delete require.cache[require.resolve(pkg)]; return require(pkg); } function runner(port = 3000, watch = false) { if (!fs.existsSync(nowDir)) console.log('now.json is required') || process.exit(0); if (watch) chokidar .watch(dir, { ignored: ['**/node_modules', '**/.git'], persistent: true }) .on('change', path => { console.log(`File ${path} has been changed`); resetLambdas(); }); executeServer(port); } const resetLambdas = () => Object.keys(lambdas).forEach(key => delete lambdas[key]); async function executeServer(port = 3000) { const { routes } = require(nowDir); const server = http.createServer(async (req, res) => { const { pathname, href, query } = url.parse(req.url); const params = qs.parse(query); const route = routes.find(route => { const method = route.methods || ['GET']; if (!method.includes(req.method)) return false; return pathname.match(route.src); }); if (!route) return notFound(res); if (route.status) res.statusCode = route.status; if (route.headers) for (const header of Object.entries(route.headers)) res.setHeader(...header); const path = route.dest ? route.dest.split('.')[0] : null; const rex = new RegExp(route.src.replace(/\//gim, '\\/'), 'gmi'); const { groups } = rex.exec(pathname) || {}; const q = Object.assign({}, params, groups); req.url = `${href.split('?')[0]}?${qs.stringify(q)}`; if (!lambdas[path]) { const lambda = resolve(join(dir, `${path}.js`)); if (fs.existsSync(lambda)) lambdas[path] = requireUncached(lambda); } const fn = lambdas[path]; // redirect if (!fn && res.getHeader('Location')) { console.log('Redirect to: ', res.getHeader('Location')); return res.end(); } // not found if (!fn) { console.log('Path of request not found'); return notFound(res); } // lambda console.log('Path of request: ', path); await fn(req, res); }); server.listen(port, () => console.log(`> Local server running at port ${port}`)); } function notFound(res) { res.writeHead(200); res.end('Not found'); } module.exports = runner;