mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-19 22:05:20 +00:00
Merge pull request #378 from sveltejs/export-timeout
export should fail on timeouts
This commit is contained in:
@@ -10,7 +10,14 @@ import minify_html from './utils/minify_html';
|
|||||||
import Deferred from './utils/Deferred';
|
import Deferred from './utils/Deferred';
|
||||||
import * as events from './interfaces';
|
import * as events from './interfaces';
|
||||||
|
|
||||||
export function exporter(opts: {}) {
|
type Opts = {
|
||||||
|
build: string,
|
||||||
|
dest: string,
|
||||||
|
basepath: string,
|
||||||
|
timeout: number | false
|
||||||
|
};
|
||||||
|
|
||||||
|
export function exporter(opts: Opts) {
|
||||||
const emitter = new EventEmitter();
|
const emitter = new EventEmitter();
|
||||||
|
|
||||||
execute(emitter, opts).then(
|
execute(emitter, opts).then(
|
||||||
@@ -27,42 +34,38 @@ export function exporter(opts: {}) {
|
|||||||
return emitter;
|
return emitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function execute(emitter: EventEmitter, {
|
async function execute(emitter: EventEmitter, opts: Opts) {
|
||||||
build = 'build',
|
const export_dir = path.join(opts.dest, opts.basepath);
|
||||||
dest = 'export',
|
|
||||||
basepath = ''
|
|
||||||
} = {}) {
|
|
||||||
const export_dir = path.join(dest, basepath);
|
|
||||||
|
|
||||||
// Prep output directory
|
// Prep output directory
|
||||||
sander.rimrafSync(export_dir);
|
sander.rimrafSync(export_dir);
|
||||||
|
|
||||||
sander.copydirSync('assets').to(export_dir);
|
sander.copydirSync('assets').to(export_dir);
|
||||||
sander.copydirSync(build, 'client').to(export_dir, 'client');
|
sander.copydirSync(opts.build, 'client').to(export_dir, 'client');
|
||||||
|
|
||||||
if (sander.existsSync(build, 'service-worker.js')) {
|
if (sander.existsSync(opts.build, 'service-worker.js')) {
|
||||||
sander.copyFileSync(build, 'service-worker.js').to(export_dir, 'service-worker.js');
|
sander.copyFileSync(opts.build, 'service-worker.js').to(export_dir, 'service-worker.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sander.existsSync(build, 'service-worker.js.map')) {
|
if (sander.existsSync(opts.build, 'service-worker.js.map')) {
|
||||||
sander.copyFileSync(build, 'service-worker.js.map').to(export_dir, 'service-worker.js.map');
|
sander.copyFileSync(opts.build, 'service-worker.js.map').to(export_dir, 'service-worker.js.map');
|
||||||
}
|
}
|
||||||
|
|
||||||
const port = await ports.find(3000);
|
const port = await ports.find(3000);
|
||||||
|
|
||||||
const origin = `http://localhost:${port}`;
|
const origin = `http://localhost:${port}`;
|
||||||
const root = new URL(basepath || '', origin);
|
const root = new URL(opts.basepath || '', origin);
|
||||||
|
|
||||||
emitter.emit('info', {
|
emitter.emit('info', {
|
||||||
message: `Crawling ${root.href}`
|
message: `Crawling ${root.href}`
|
||||||
});
|
});
|
||||||
|
|
||||||
const proc = child_process.fork(path.resolve(`${build}/server.js`), [], {
|
const proc = child_process.fork(path.resolve(`${opts.build}/server.js`), [], {
|
||||||
cwd: process.cwd(),
|
cwd: process.cwd(),
|
||||||
env: Object.assign({
|
env: Object.assign({
|
||||||
PORT: port,
|
PORT: port,
|
||||||
NODE_ENV: 'production',
|
NODE_ENV: 'production',
|
||||||
SAPPER_DEST: build,
|
SAPPER_DEST: opts.build,
|
||||||
SAPPER_EXPORT: 'true'
|
SAPPER_EXPORT: 'true'
|
||||||
}, process.env)
|
}, process.env)
|
||||||
});
|
});
|
||||||
@@ -117,7 +120,18 @@ async function execute(emitter: EventEmitter, {
|
|||||||
|
|
||||||
const deferred = get_deferred(pathname);
|
const deferred = get_deferred(pathname);
|
||||||
|
|
||||||
const r = await fetch(url.href);
|
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),
|
||||||
|
timeout_deferred.promise
|
||||||
|
]);
|
||||||
|
|
||||||
|
clearTimeout(timeout); // prevent it hanging at the end
|
||||||
|
|
||||||
const range = ~~(r.status / 100);
|
const range = ~~(r.status / 100);
|
||||||
|
|
||||||
if (range === 2) {
|
if (range === 2) {
|
||||||
@@ -152,11 +166,12 @@ async function execute(emitter: EventEmitter, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ports.wait(port)
|
return ports.wait(port)
|
||||||
.then(() => {
|
.then(() => handle(root))
|
||||||
// TODO all static routes
|
.then(() => proc.kill())
|
||||||
return handle(root);
|
.catch(err => {
|
||||||
})
|
proc.kill();
|
||||||
.then(() => proc.kill());
|
throw err;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_href(attrs: string) {
|
function get_href(attrs: string) {
|
||||||
|
|||||||
10
src/cli.ts
10
src/cli.ts
@@ -65,7 +65,13 @@ prog.command('export [dest]')
|
|||||||
.option('--build', '(Re)build app before exporting', true)
|
.option('--build', '(Re)build app before exporting', true)
|
||||||
.option('--build-dir', 'Specify a custom temporary build directory', '.sapper/prod')
|
.option('--build-dir', 'Specify a custom temporary build directory', '.sapper/prod')
|
||||||
.option('--basepath', 'Specify a base path')
|
.option('--basepath', 'Specify a base path')
|
||||||
.action(async (dest = 'export', opts: { build: boolean, 'build-dir': string, basepath?: string }) => {
|
.option('--timeout', 'Milliseconds to wait for a page (--no-timeout to disable)', 5000)
|
||||||
|
.action(async (dest = 'export', opts: {
|
||||||
|
build: boolean,
|
||||||
|
'build-dir': string,
|
||||||
|
basepath?: string,
|
||||||
|
timeout: number | false
|
||||||
|
}) => {
|
||||||
process.env.NODE_ENV = 'production';
|
process.env.NODE_ENV = 'production';
|
||||||
process.env.SAPPER_DEST = opts['build-dir'];
|
process.env.SAPPER_DEST = opts['build-dir'];
|
||||||
|
|
||||||
@@ -83,7 +89,7 @@ prog.command('export [dest]')
|
|||||||
await exporter(dest, opts);
|
await exporter(dest, opts);
|
||||||
console.error(`\n> Finished in ${elapsed(start)}. Type ${colors.bold.cyan(`npx serve ${dest}`)} to run the app.`);
|
console.error(`\n> Finished in ${elapsed(start)}. Type ${colors.bold.cyan(`npx serve ${dest}`)} to run the app.`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err ? err.details || err.stack || err.message || err : 'Unknown error');
|
console.error(colors.bold.red(`> ${err.message}`));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,13 +8,20 @@ function left_pad(str: string, len: number) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function exporter(export_dir: string, { basepath = '' }) {
|
export function exporter(export_dir: string, {
|
||||||
|
basepath = '',
|
||||||
|
timeout
|
||||||
|
}: {
|
||||||
|
basepath: string,
|
||||||
|
timeout: number | false
|
||||||
|
}) {
|
||||||
return new Promise((fulfil, reject) => {
|
return new Promise((fulfil, reject) => {
|
||||||
try {
|
try {
|
||||||
const emitter = _exporter({
|
const emitter = _exporter({
|
||||||
build: locations.dest(),
|
build: locations.dest(),
|
||||||
dest: export_dir,
|
dest: export_dir,
|
||||||
basepath
|
basepath,
|
||||||
|
timeout
|
||||||
});
|
});
|
||||||
|
|
||||||
emitter.on('file', event => {
|
emitter.on('file', event => {
|
||||||
|
|||||||
Reference in New Issue
Block a user