mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-12 19:25:10 +00:00
99 lines
2.3 KiB
JavaScript
99 lines
2.3 KiB
JavaScript
const path = require('path');
|
|
const sander = require('sander');
|
|
const app = require('express')();
|
|
const cheerio = require('cheerio');
|
|
const fetch = require('node-fetch');
|
|
const URL = require('url-parse');
|
|
const generate_asset_cache = require('./generate_asset_cache.js');
|
|
const sapper = require('../index.js');
|
|
|
|
const { PORT = 3000, OUTPUT_DIR = 'dist' } = process.env;
|
|
const { dest } = require('../config.js');
|
|
|
|
const origin = `http://localhost:${PORT}`;
|
|
|
|
function read_json(file) {
|
|
return JSON.parse(sander.readFileSync(file, { encoding: 'utf-8' }));
|
|
}
|
|
|
|
module.exports = function() {
|
|
// Prep output directory
|
|
sander.rimrafSync(OUTPUT_DIR);
|
|
|
|
const { service_worker } = generate_asset_cache(
|
|
read_json(path.join(dest, 'stats.client.json')),
|
|
read_json(path.join(dest, 'stats.server.json'))
|
|
);
|
|
|
|
sander.copydirSync('assets').to(OUTPUT_DIR);
|
|
sander.copydirSync(dest, 'client').to(OUTPUT_DIR, 'client');
|
|
sander.writeFileSync(OUTPUT_DIR, 'service-worker.js', service_worker);
|
|
|
|
// Intercept server route fetches
|
|
function save(res) {
|
|
res = res.clone();
|
|
|
|
return res.text().then(body => {
|
|
const { pathname } = new URL(res.url);
|
|
let dest = OUTPUT_DIR + pathname;
|
|
|
|
const type = res.headers.get('Content-Type');
|
|
if (type.startsWith('text/html')) dest += '/index.html';
|
|
|
|
sander.writeFileSync(dest, body);
|
|
|
|
return body;
|
|
});
|
|
}
|
|
|
|
global.fetch = (url, opts) => {
|
|
if (url[0] === '/') {
|
|
url = `http://localhost:${PORT}${url}`;
|
|
|
|
return fetch(url, opts)
|
|
.then(r => {
|
|
save(r);
|
|
return r;
|
|
});
|
|
}
|
|
|
|
return fetch(url, opts);
|
|
};
|
|
|
|
app.use(sapper());
|
|
const server = app.listen(PORT);
|
|
|
|
const seen = new Set();
|
|
|
|
function handle(url) {
|
|
if (url.origin !== origin) return;
|
|
|
|
if (seen.has(url.pathname)) return;
|
|
seen.add(url.pathname);
|
|
|
|
return fetch(url.href)
|
|
.then(r => {
|
|
save(r);
|
|
return r.text();
|
|
})
|
|
.then(body => {
|
|
const $ = cheerio.load(body);
|
|
const hrefs = [];
|
|
|
|
$('a[href]').each((i, $a) => {
|
|
hrefs.push($a.attribs.href);
|
|
});
|
|
|
|
return hrefs.reduce((promise, href) => {
|
|
return promise.then(() => handle(new URL(href, url.href)));
|
|
}, Promise.resolve());
|
|
})
|
|
.catch(err => {
|
|
console.error(`Error rendering ${url.pathname}: ${err.message}`);
|
|
});
|
|
}
|
|
|
|
return handle(new URL(origin)) // TODO all static routes
|
|
.then(() => server.close());
|
|
};
|