diff --git a/src/api/export.ts b/src/api/export.ts index 482ba51..6129eaf 100644 --- a/src/api/export.ts +++ b/src/api/export.ts @@ -94,7 +94,9 @@ async function _export({ const is_html = type === 'text/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); } @@ -113,7 +115,10 @@ async function _export({ }); 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; seen.add(pathname); @@ -138,7 +143,7 @@ async function _export({ const range = ~~(r.status / 100); if (range === 2) { - if (type === 'text/html') { + if (type === 'text/html' && pathname !== '/service-worker-index.html') { const urls: URL[] = []; const cleaned = clean_html(body); @@ -181,6 +186,7 @@ async function _export({ return ports.wait(port) .then(() => handle(root)) + .then(() => handle(resolve(root.href, 'service-worker-index.html'))) .then(() => proc.kill()) .catch(err => { proc.kill(); diff --git a/src/core/create_manifests.ts b/src/core/create_manifests.ts index 3ff7a95..ebe4cf4 100644 --- a/src/core/create_manifests.ts +++ b/src/core/create_manifests.ts @@ -45,17 +45,15 @@ export function create_serviceworker_manifest({ manifest_data, output, client_fi client_files: string[]; static_files: string; }) { - let files: string[]; + let files: string[] = ['/service-worker-index.html']; if (fs.existsSync(static_files)) { - files = walk(static_files); + files = files.concat(walk(static_files)); } else { // TODO remove in a future version if (fs.existsSync('assets')) { throw new Error(`As of Sapper 0.21, the assets/ directory should become static/`); } - - files = []; } let code = ` diff --git a/templates/src/server/middleware/get_page_handler.ts b/templates/src/server/middleware/get_page_handler.ts index 802ee0f..67405ba 100644 --- a/templates/src/server/middleware/get_page_handler.ts +++ b/templates/src/server/middleware/get_page_handler.ts @@ -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) { + const isSWIndexHtml = req.path === '/service-worker-index.html'; const build_info: { bundler: 'rollup' | 'webpack', shimport: string | null, @@ -47,7 +48,7 @@ export function get_page_handler( // preload main.js and current route // 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]; - if (!error) { + if (!error && !isSWIndexHtml) { page.parts.forEach(part => { if (!part) return; @@ -145,17 +146,22 @@ export function get_page_handler( match = error ? null : page.pattern.exec(req.path); - preloaded = await Promise.all([root_preloaded].concat(page.parts.map(part => { - if (!part) return null; + let toPreload = [root_preloaded]; + if (!isSWIndexHtml) { + toPreload = toPreload.concat(page.parts.map(part => { + if (!part) return null; - return part.component.preload - ? part.component.preload.call(preload_context, { - path: req.path, - query: req.query, - params: part.params ? part.params(match) : {} - }) - : {}; - }))); + return part.component.preload + ? part.component.preload.call(preload_context, { + path: req.path, + query: req.query, + params: part.params ? part.params(match) : {} + }) + : {}; + })) + } + + preloaded = await Promise.all(toPreload); } catch (err) { preload_error = { statusCode: 500, message: err }; preloaded = []; // appease TypeScript @@ -204,23 +210,29 @@ export function get_page_handler( }); let level = data.child; - for (let i = 0; i < page.parts.length; i += 1) { - const part = page.parts[i]; - if (!part) continue; + if (isSWIndexHtml) { + level.props = Object.assign({}, props, { + 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, { - component: part.component, - props: Object.assign({}, props, { - params: get_params(match) - }, preloaded[i + 1]) - }); + Object.assign(level, { + component: part.component, + props: Object.assign({}, props, { + params: get_params(match) + }, preloaded[i + 1]) + }); - level.props.child = { - segment: segments[i + 1] - }; - level = level.props.child; + level.props.child = { + segment: segments[i + 1] + }; + level = level.props.child; + } } 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) { 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))) { for (const page of pages) { if (page.pattern.test(req.path)) { diff --git a/test/apps/export/test.ts b/test/apps/export/test.ts index 9bb8339..897bc5f 100644 --- a/test/apps/export/test.ts +++ b/test/apps/export/test.ts @@ -30,6 +30,7 @@ describe('export', function() { 'blog/index.html', 'global.css', 'index.html', + 'service-worker-index.html', 'service-worker.js' ]); }); diff --git a/test/apps/with-basepath/test.ts b/test/apps/with-basepath/test.ts index 93bbcbf..5741d1b 100644 --- a/test/apps/with-basepath/test.ts +++ b/test/apps/with-basepath/test.ts @@ -56,6 +56,7 @@ describe('with-basepath', function() { assert.deepEqual(non_client_assets, [ 'custom-basepath/global.css', 'custom-basepath/index.html', + 'custom-basepath/service-worker-index.html', 'custom-basepath/service-worker.js' ]); });