const http = require('http'); const webpack = require('webpack'); const wdm = require('webpack-dev-middleware'); const whm = require('webpack-hot-middleware'); const debug = require('debug')('truss:persea'); const {webpackConfig} = require('./webpack.config'); const backendHostname = process.env.PERSEA_BACKHOST || 'persea'; const backendPort = process.env.PERSEA_BACKPORT || 8004; const frontendHostname = process.env.PERSEA_FRONTHOST || 'localhost'; exports.Responder = class Responder { constructor() { const httpServer = this.server = http.createServer(); httpServer.on('listening', () => { const address = this.address = httpServer.address(); const config = webpackConfig(); for (const i in config.entry) { config.entry[i].unshift(`webpack-hot-middleware/client?path=http://${ frontendHostname}:${address.port }/__webpack_hmr`); } const compiler = webpack(config); this.dm = wdm(compiler, { headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS", "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization" }, stats: { chunkModules: true, colors: true, context: process.cwd(), }, }); this.hm = whm(compiler, { path: '/__webpack_hmr', }); debug(`HTTP listening on ${JSON.stringify(address)}...`); }); httpServer.on('request', (req, res) => { this.dm(req, res, (error) => { if (error) { return console.error(error); } this.hm(req, res, (error) => { if (error) { return console.error(error); } }); }); }); httpServer.on('error', console.error); httpServer.on('close', () => httpServer.removeAllListeners()); } start() { this.server.listen(backendPort); } respond({payload: {headers, url}}) { // forward to internal HTTP return new Promise((resolve, reject) => { const options = { headers, backendHostname, path: url, port: this.address.port, }; const client = http.get(options); client.on('response', (res) => { let data = ''; res.setEncoding('utf8'); res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { resolve({ html: data, headers: res.headers }); }); }); client.on('error', reject); }); } stop() { this.server.close(); } }