Merge pull request #525 from nolanlawson/nolan/sw-index-html

add service-worker-index.html
This commit is contained in:
Rich Harris
2019-02-01 05:36:08 -05:00
committed by GitHub
5 changed files with 56 additions and 32 deletions

View File

@@ -94,7 +94,9 @@ async function _export({
const is_html = type === 'text/html'; const is_html = type === 'text/html';
if (is_html) { if (is_html) {
file = file === '' ? 'index.html' : `${file}/index.html`; if (pathname !== '/service-worker-index.html') {
file = file === '' ? 'index.html' : `${file}/index.html`;
}
body = minify_html(body); body = minify_html(body);
} }
@@ -113,7 +115,10 @@ async function _export({
}); });
async function handle(url: URL) { async function handle(url: URL) {
const pathname = (url.pathname.replace(root.pathname, '') || '/'); let pathname = url.pathname;
if (pathname !== '/service-worker-index.html') {
pathname = pathname.replace(root.pathname, '') || '/'
}
if (seen.has(pathname)) return; if (seen.has(pathname)) return;
seen.add(pathname); seen.add(pathname);
@@ -138,7 +143,7 @@ async function _export({
const range = ~~(r.status / 100); const range = ~~(r.status / 100);
if (range === 2) { if (range === 2) {
if (type === 'text/html') { if (type === 'text/html' && pathname !== '/service-worker-index.html') {
const urls: URL[] = []; const urls: URL[] = [];
const cleaned = clean_html(body); const cleaned = clean_html(body);
@@ -181,6 +186,7 @@ async function _export({
return ports.wait(port) return ports.wait(port)
.then(() => handle(root)) .then(() => handle(root))
.then(() => handle(resolve(root.href, 'service-worker-index.html')))
.then(() => proc.kill()) .then(() => proc.kill())
.catch(err => { .catch(err => {
proc.kill(); proc.kill();

View File

@@ -45,17 +45,15 @@ export function create_serviceworker_manifest({ manifest_data, output, client_fi
client_files: string[]; client_files: string[];
static_files: string; static_files: string;
}) { }) {
let files: string[]; let files: string[] = ['/service-worker-index.html'];
if (fs.existsSync(static_files)) { if (fs.existsSync(static_files)) {
files = walk(static_files); files = files.concat(walk(static_files));
} else { } else {
// TODO remove in a future version // TODO remove in a future version
if (fs.existsSync('assets')) { if (fs.existsSync('assets')) {
throw new Error(`As of Sapper 0.21, the assets/ directory should become static/`); throw new Error(`As of Sapper 0.21, the assets/ directory should become static/`);
} }
files = [];
} }
let code = ` let code = `

View File

@@ -34,6 +34,7 @@ export function get_page_handler(
} }
async function handle_page(page: Page, req: Req, res: Res, status = 200, error: Error | string = null) { async function handle_page(page: Page, req: Req, res: Res, status = 200, error: Error | string = null) {
const isSWIndexHtml = req.path === '/service-worker-index.html';
const build_info: { const build_info: {
bundler: 'rollup' | 'webpack', bundler: 'rollup' | 'webpack',
shimport: string | null, shimport: string | null,
@@ -47,7 +48,7 @@ export function get_page_handler(
// preload main.js and current route // preload main.js and current route
// TODO detect other stuff we can preload? images, CSS, fonts? // TODO detect other stuff we can preload? images, CSS, fonts?
let preloaded_chunks = Array.isArray(build_info.assets.main) ? build_info.assets.main : [build_info.assets.main]; let preloaded_chunks = Array.isArray(build_info.assets.main) ? build_info.assets.main : [build_info.assets.main];
if (!error) { if (!error && !isSWIndexHtml) {
page.parts.forEach(part => { page.parts.forEach(part => {
if (!part) return; if (!part) return;
@@ -145,17 +146,22 @@ export function get_page_handler(
match = error ? null : page.pattern.exec(req.path); match = error ? null : page.pattern.exec(req.path);
preloaded = await Promise.all([root_preloaded].concat(page.parts.map(part => { let toPreload = [root_preloaded];
if (!part) return null; if (!isSWIndexHtml) {
toPreload = toPreload.concat(page.parts.map(part => {
if (!part) return null;
return part.component.preload return part.component.preload
? part.component.preload.call(preload_context, { ? part.component.preload.call(preload_context, {
path: req.path, path: req.path,
query: req.query, query: req.query,
params: part.params ? part.params(match) : {} params: part.params ? part.params(match) : {}
}) })
: {}; : {};
}))); }))
}
preloaded = await Promise.all(toPreload);
} catch (err) { } catch (err) {
preload_error = { statusCode: 500, message: err }; preload_error = { statusCode: 500, message: err };
preloaded = []; // appease TypeScript preloaded = []; // appease TypeScript
@@ -204,23 +210,29 @@ export function get_page_handler(
}); });
let level = data.child; let level = data.child;
for (let i = 0; i < page.parts.length; i += 1) { if (isSWIndexHtml) {
const part = page.parts[i]; level.props = Object.assign({}, props, {
if (!part) continue; params: {}
})
} else {
for (let i = 0; i < page.parts.length; i += 1) {
const part = page.parts[i];
if (!part) continue;
const get_params = part.params || (() => ({})); const get_params = part.params || (() => ({}));
Object.assign(level, { Object.assign(level, {
component: part.component, component: part.component,
props: Object.assign({}, props, { props: Object.assign({}, props, {
params: get_params(match) params: get_params(match)
}, preloaded[i + 1]) }, preloaded[i + 1])
}); });
level.props.child = <Props["child"]>{ level.props.child = <Props["child"]>{
segment: segments[i + 1] segment: segments[i + 1]
}; };
level = level.props.child; level = level.props.child;
}
} }
const { html, head, css } = manifest.root.render(data, { const { html, head, css } = manifest.root.render(data, {
@@ -303,6 +315,12 @@ export function get_page_handler(
return function find_route(req: Req, res: Res, next: () => void) { return function find_route(req: Req, res: Res, next: () => void) {
if (req[IGNORE]) return next(); if (req[IGNORE]) return next();
if (req.path === '/service-worker-index.html') {
const homePage = pages.find(page => page.pattern.test('/'));
handle_page(homePage, req, res);
return;
}
if (!server_routes.some(route => route.pattern.test(req.path))) { if (!server_routes.some(route => route.pattern.test(req.path))) {
for (const page of pages) { for (const page of pages) {
if (page.pattern.test(req.path)) { if (page.pattern.test(req.path)) {

View File

@@ -30,6 +30,7 @@ describe('export', function() {
'blog/index.html', 'blog/index.html',
'global.css', 'global.css',
'index.html', 'index.html',
'service-worker-index.html',
'service-worker.js' 'service-worker.js'
]); ]);
}); });

View File

@@ -56,6 +56,7 @@ describe('with-basepath', function() {
assert.deepEqual(non_client_assets, [ assert.deepEqual(non_client_assets, [
'custom-basepath/global.css', 'custom-basepath/global.css',
'custom-basepath/index.html', 'custom-basepath/index.html',
'custom-basepath/service-worker-index.html',
'custom-basepath/service-worker.js' 'custom-basepath/service-worker.js'
]); ]);
}); });