mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-12 03:05:12 +00:00
Merge pull request #393 from sveltejs/gh-392
handle non-Sapper responses when exporting
This commit is contained in:
@@ -54,7 +54,9 @@ async function execute(emitter: EventEmitter, opts: Opts) {
|
||||
const port = await ports.find(3000);
|
||||
|
||||
const origin = `http://localhost:${port}`;
|
||||
const root = new URL(opts.basepath || '', origin);
|
||||
let basepath = opts.basepath || '/';
|
||||
if (!basepath.endsWith('/')) basepath += '/';
|
||||
let root = new URL(basepath, origin);
|
||||
|
||||
emitter.emit('info', {
|
||||
message: `Crawling ${root.href}`
|
||||
@@ -72,29 +74,15 @@ async function execute(emitter: EventEmitter, opts: Opts) {
|
||||
|
||||
const seen = new Set();
|
||||
const saved = new Set();
|
||||
const deferreds = new Map();
|
||||
|
||||
function get_deferred(pathname: string) {
|
||||
pathname = pathname.replace(root.pathname, '');
|
||||
|
||||
if (!deferreds.has(pathname)) {
|
||||
deferreds.set(pathname, new Deferred());
|
||||
}
|
||||
|
||||
return deferreds.get(pathname);
|
||||
}
|
||||
|
||||
proc.on('message', message => {
|
||||
if (!message.__sapper__ || message.event !== 'file') return;
|
||||
|
||||
const pathname = new URL(message.url, origin).pathname;
|
||||
function save(url: string, status: number, type: string, body: string) {
|
||||
const pathname = new URL(url, origin).pathname;
|
||||
let file = pathname.slice(1);
|
||||
let { body } = message;
|
||||
|
||||
if (saved.has(file)) return;
|
||||
saved.add(file);
|
||||
|
||||
const is_html = message.type === 'text/html';
|
||||
const is_html = type === 'text/html';
|
||||
|
||||
if (is_html) {
|
||||
file = file === '' ? 'index.html' : `${file}/index.html`;
|
||||
@@ -104,12 +92,15 @@ async function execute(emitter: EventEmitter, opts: Opts) {
|
||||
emitter.emit('file', <events.FileEvent>{
|
||||
file,
|
||||
size: body.length,
|
||||
status: message.status
|
||||
status
|
||||
});
|
||||
|
||||
sander.writeFileSync(export_dir, file, body);
|
||||
}
|
||||
|
||||
get_deferred(pathname).fulfil();
|
||||
proc.on('message', message => {
|
||||
if (!message.__sapper__ || message.event !== 'file') return;
|
||||
save(message.url, message.status, message.type, message.body);
|
||||
});
|
||||
|
||||
async function handle(url: URL) {
|
||||
@@ -118,25 +109,27 @@ async function execute(emitter: EventEmitter, opts: Opts) {
|
||||
if (seen.has(pathname)) return;
|
||||
seen.add(pathname);
|
||||
|
||||
const deferred = get_deferred(pathname);
|
||||
|
||||
const timeout_deferred = new Deferred();
|
||||
const timeout = setTimeout(() => {
|
||||
timeout_deferred.reject(new Error(`Timed out waiting for ${url.href}`));
|
||||
}, opts.timeout);
|
||||
|
||||
const r = await Promise.race([
|
||||
fetch(url.href),
|
||||
fetch(url.href, {
|
||||
redirect: 'manual'
|
||||
}),
|
||||
timeout_deferred.promise
|
||||
]);
|
||||
|
||||
clearTimeout(timeout); // prevent it hanging at the end
|
||||
|
||||
let type = r.headers.get('Content-Type');
|
||||
let body = await r.text();
|
||||
|
||||
const range = ~~(r.status / 100);
|
||||
|
||||
if (range === 2) {
|
||||
if (r.headers.get('Content-Type') === 'text/html') {
|
||||
const body = await r.text();
|
||||
if (type === 'text/html') {
|
||||
const urls: URL[] = [];
|
||||
|
||||
const cleaned = clean_html(body);
|
||||
@@ -162,7 +155,16 @@ async function execute(emitter: EventEmitter, opts: Opts) {
|
||||
}
|
||||
}
|
||||
|
||||
await deferred.promise;
|
||||
if (range === 3) {
|
||||
const location = r.headers.get('Location');
|
||||
|
||||
type = 'text/html';
|
||||
body = `<script>window.location.href = "${location}"</script>`;
|
||||
|
||||
await handle(new URL(location, root));
|
||||
}
|
||||
|
||||
save(pathname, r.status, type, body);
|
||||
}
|
||||
|
||||
return ports.wait(port)
|
||||
|
||||
@@ -414,18 +414,6 @@ function get_page_handler(
|
||||
res.setHeader('Location', location);
|
||||
res.end();
|
||||
|
||||
if (process.send) {
|
||||
process.send({
|
||||
__sapper__: true,
|
||||
event: 'file',
|
||||
url: req.url,
|
||||
method: req.method,
|
||||
status: redirect.statusCode,
|
||||
type: 'text/html',
|
||||
body: `<script>window.location.href = "${location}"</script>`
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -512,18 +500,6 @@ function get_page_handler(
|
||||
|
||||
res.statusCode = status;
|
||||
res.end(body);
|
||||
|
||||
if (process.send) {
|
||||
process.send({
|
||||
__sapper__: true,
|
||||
event: 'file',
|
||||
url: req.url,
|
||||
method: req.method,
|
||||
status,
|
||||
type: 'text/html',
|
||||
body
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
if (error) {
|
||||
// we encountered an error while rendering the error page — oops
|
||||
|
||||
@@ -108,6 +108,13 @@ const middlewares = [
|
||||
}),
|
||||
];
|
||||
|
||||
app.get(`${BASEPATH}/non-sapper-redirect-from`, (req, res) => {
|
||||
res.writeHead(301, {
|
||||
Location: `${BASEPATH}/non-sapper-redirect-to`
|
||||
});
|
||||
res.end();
|
||||
});
|
||||
|
||||
if (BASEPATH) {
|
||||
app.use(BASEPATH, ...middlewares);
|
||||
} else {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<a href='.'>home</a>
|
||||
<a href='about'>about</a>
|
||||
<a href='slow-preload'>slow preload</a>
|
||||
<a href='non-sapper-redirect-from'>redirect</a>
|
||||
<a href='redirect-from'>redirect</a>
|
||||
<a href='redirect-root'>redirect (root)</a>
|
||||
<a href='blog/nope'>broken link</a>
|
||||
|
||||
1
test/app/routes/non-sapper-redirect-to.html
Normal file
1
test/app/routes/non-sapper-redirect-to.html
Normal file
@@ -0,0 +1 @@
|
||||
<h1>redirected</h1>
|
||||
@@ -2,9 +2,7 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const assert = require('assert');
|
||||
const Nightmare = require('nightmare');
|
||||
const serve = require('serve-static');
|
||||
const walkSync = require('walk-sync');
|
||||
const fetch = require('node-fetch');
|
||||
const rimraf = require('rimraf');
|
||||
const ports = require('port-authority');
|
||||
|
||||
@@ -83,6 +81,11 @@ function testExport({ basepath = '' }) {
|
||||
'about/index.html',
|
||||
'slow-preload/index.html',
|
||||
|
||||
'redirect-from/index.html',
|
||||
'redirect-to/index.html',
|
||||
'non-sapper-redirect-from/index.html',
|
||||
'non-sapper-redirect-to/index.html',
|
||||
|
||||
'blog/index.html',
|
||||
'blog/a-very-long-post/index.html',
|
||||
'blog/how-can-i-get-involved/index.html',
|
||||
|
||||
Reference in New Issue
Block a user