const Bluebird = require('bluebird'); const FS = Bluebird.promisifyAll(require('fs')); const OS = require('os'); const Express = require('express'); const Compression = require('compression'); const SpiderDetector = require('spider-detector') const DNSCache = require('dnscache'); const CrossFetch = require('cross-fetch'); const ReactDOMServer = require('react-dom/server'); const FrontEnd = require('./client/front-end'); const NginxCache = require('./nginx-cache'); // enable DNS caching let dnsCache = DNSCache({ enable: true, ttl: 300, cachesize: 100 }); const perPage = 10; const serverPort = 80; const wordpressHost = process.env.WORDPRESS_HOST; const nginxHost = process.env.NGINX_HOST; let wordpressIP; dnsCache.lookup(wordpressHost, (err, result) => { if (!err) { wordpressIP = `::ffff:${result}`; } }); let app = Express(); app.set('json spaces', 2); app.use(Compression()) app.use(SpiderDetector.middleware()); app.use(`/`, Express.static(`${__dirname}/www`)); app.get('/.mtime', handleTimestampRequest); app.get('/json/*', handleJSONRequest); app.get(`/*`, handlePageRequest); app.purge(`/*`, handlePurgeRequest); app.use(handleError); app.listen(serverPort); let pageDependencies = {}; async function handleJSONRequest(req, res, next) { try { let path = `/wp-json/${req.url.substr(6)}`; let url = `http://${wordpressHost}${path}`; let sres = await CrossFetch(url); let text = await sres.text(); res.send(text); } catch (err) { next(err); } } function handleTimestampRequest(req, res, next) { try { let now = new Date; let ts = now.toISOString(); res.type('text').send(ts); } catch (err) { next(err); } } async function handlePageRequest(req, res, next) { try { let host = `http://${nginxHost}`; let path = req.url; let noScript = (req.query.js === '0') let target = (req.isSpider() || noScript) ? 'seo' : 'hydrate'; let sourceURLs = []; // create a fetch() that remembers the URLs used let fetch = (url, options) => { console.log(`Fetching: ${url}`); if (url.startsWith(host)) { var relURL = url.substr(host.length); sourceURLs.push(relURL); } return CrossFetch(url, options); }; let options = { host, path, target, fetch }; let rootNode = await FrontEnd.render(options); let appHTML = ReactDOMServer.renderToString(rootNode); let indexHTMLPath = `${__dirname}/client/index.html`; let html = await replaceHTMLComment(indexHTMLPath, 'REACT', appHTML); if (target === 'hydrate') { // add