UNPKG

@compositor/gen

Version:

Compositor JSX static site generator

100 lines (83 loc) 2.46 kB
const fs = require('fs') const http = require('http') const url = require('url') const path = require('path') const React = require('react') const chokidar = require('chokidar') const portfinder = require('portfinder') const WebSocket = require('ws') const getData = require('./getData') const render = require('./render') const getPages = async (dirname, opts) => { const data = await getData(dirname, opts) const pages = await render(data, opts) return pages } const start = async (dirname, opts) => { if (opts.port) { portfinder.basePort = parseInt(opts.port) } const port = await portfinder.getPortPromise() portfinder.basePort = port + 2 const socketPort = await portfinder.getPortPromise() let socket let pages = await getPages(dirname, opts) const watcher = chokidar.watch(dirname, { depth: 1, ignoreInitial: true, ignored: '!*.(jsx|md|json)' }) const socketServer = new WebSocket.Server({ port: socketPort }) socketServer.on('connection', res => { socket = res }) const update = async () => { if (!socket) return pages = await getPages(dirname, opts) socket.send(JSON.stringify({ reload: true })) } watcher.on('change', async filename => { if (!socket) return const base = path.basename(filename) const ext = path.extname(base) if (!/\.(jsx|md|json)$/.test(ext)) return // todo: handle this per file update() }) const app = http.createServer((req, res) => { const { pathname } = url.parse(req.url) const filepath = path.join(dirname, pathname) // serve local images and files if (fs.existsSync(filepath) && fs.statSync(filepath).isFile()) { fs.createReadStream(filepath).pipe(res) return } const name = pathname === '/' ? 'index' : pathname.replace(/^\//, '').replace(/\/$/, '') const page = pages.find(page => page.name === name) if (!page) { res.write('page not found: ' + pathname) res.end() return } res.write(page.html) res.write(script(socketPort)) res.end() }) try { const server = await app.listen(port) return server } catch (err) { console.log(err) throw err } } const script = (port) => `<script type='text/javascript'> const socket = new WebSocket('ws://localhost:${port}') socket.onmessage = msg => { const data = JSON.parse(msg.data) if (data.reload) { window.location.reload() } } </script>` module.exports = start