diff --git a/runtime/src/app/app.ts b/runtime/src/app/app.ts index f9e8cdc67..61f96bc22 100644 --- a/runtime/src/app/app.ts +++ b/runtime/src/app/app.ts @@ -1,6 +1,6 @@ import { writable } from 'svelte/store'; import App from '@sapper/internal/App.svelte'; -import { root_preload, ErrorComponent, ignore, components, routes } from '@sapper/internal/manifest-client'; +import { root_comp, ErrorComponent, ignore, components, routes } from '@sapper/internal/manifest-client'; import { Target, ScrollPosition, @@ -297,6 +297,7 @@ export async function hydrate_target(target: Target): Promise<{ }; if (!root_preloaded) { + const root_preload = root_comp.preload || (() => {}); root_preloaded = initial_data.preloaded[0] || root_preload.call(preload_context, { host: page.host, path: page.path, diff --git a/runtime/src/server/middleware/get_page_handler.ts b/runtime/src/server/middleware/get_page_handler.ts index c39e96c0c..86a7e13bf 100644 --- a/runtime/src/server/middleware/get_page_handler.ts +++ b/runtime/src/server/middleware/get_page_handler.ts @@ -154,14 +154,13 @@ export function get_page_handler( let params; try { - const root_preloaded = manifest.root_preload - ? manifest.root_preload.call(preload_context, { + const root_preload = manifest.root_comp.preload || (() => {}); + const root_preloaded = root_preload.call(preload_context, { host: req.headers.host, path: req.path, query: req.query, params: {} - }, session) - : {}; + }, session); match = error ? null : page.pattern.exec(req.path); @@ -174,8 +173,8 @@ export function get_page_handler( // the deepest level is used below, to initialise the store params = part.params ? part.params(match) : {}; - return part.preload - ? part.preload.call(preload_context, { + return part.component.preload + ? part.component.preload.call(preload_context, { host: req.headers.host, path: req.path, query: req.query, @@ -257,7 +256,7 @@ export function get_page_handler( if (!part) continue; props[`level${l++}`] = { - component: part.component, + component: part.component.default, props: preloaded[i + 1] || {}, segment: segments[i] }; diff --git a/runtime/src/server/middleware/types.ts b/runtime/src/server/middleware/types.ts index bcc088918..40aa68549 100644 --- a/runtime/src/server/middleware/types.ts +++ b/runtime/src/server/middleware/types.ts @@ -10,17 +10,18 @@ export type Page = { pattern: RegExp; parts: Array<{ name: string; - component: Component; + component: { + default: Component; + preload?: (data: any) => any | Promise; + }, params?: (match: RegExpMatchArray) => Record; - preload?: (data: any) => any | Promise; }> }; export type Manifest = { server_routes: ServerRoute[]; pages: Page[]; - root: Component; - root_preload?: (data: any) => any | Promise; + root_comp: Component; error: Component; } diff --git a/src/core/create_app.ts b/src/core/create_app.ts index 850eb66c0..22320b7e2 100644 --- a/src/core/create_app.ts +++ b/src/core/create_app.ts @@ -136,8 +136,9 @@ function generate_client_manifest( return ` // This file is generated by Sapper — do not edit it! - export { default as Root } from '${stringify(get_file(path_to_routes, manifest_data.root), false)}'; - export { preload as root_preload } from '${manifest_data.root.has_preload ? stringify(get_file(path_to_routes, manifest_data.root), false) : './shared'}'; + // webpack does not support export * as root_comp yet so do a two line import/export + import * as root_comp from '${stringify(get_file(path_to_routes, manifest_data.root), false)}'; + export { root_comp }; export { default as ErrorComponent } from '${stringify(get_file(path_to_routes, manifest_data.error), false)}'; export const ignore = [${server_routes_to_ignore.map(route => route.pattern).join(', ')}]; @@ -166,8 +167,8 @@ function generate_server_manifest( manifest_data.server_routes.map((route, i) => `import * as route_${i} from ${stringify(posixify(`${path_to_routes}/${route.file}`))};`), manifest_data.components.map((component, i) => - `import component_${i}${component.has_preload ? `, { preload as preload_${i} }` : ''} from ${stringify(get_file(path_to_routes, component))};`), - `import root${manifest_data.root.has_preload ? `, { preload as root_preload }` : ''} from ${stringify(get_file(path_to_routes, manifest_data.root))};`, + `import * as component_${i} from ${stringify(get_file(path_to_routes, component))};`), + `import * as root_comp from ${stringify(get_file(path_to_routes, manifest_data.root))};`, `import error from ${stringify(get_file(path_to_routes, manifest_data.error))};` ); @@ -211,8 +212,7 @@ function generate_server_manifest( const props = [ `name: "${part.component.name}"`, `file: ${stringify(part.component.file)}`, - `component: component_${component_lookup[part.component.name]}`, - part.component.has_preload && `preload: preload_${component_lookup[part.component.name]}` + `component: component_${component_lookup[part.component.name]}` ].filter(Boolean); if (part.params.length > 0) { @@ -226,8 +226,7 @@ function generate_server_manifest( }`).join(',\n\n\t\t\t\t')} ], - root, - root_preload${manifest_data.root.has_preload ? '' : `: () => {}`}, + root_comp, error }; diff --git a/src/core/create_manifest_data.ts b/src/core/create_manifest_data.ts index b33e7a40c..3d720bd3b 100644 --- a/src/core/create_manifest_data.ts +++ b/src/core/create_manifest_data.ts @@ -1,6 +1,5 @@ import * as fs from 'fs'; import * as path from 'path'; -import svelte from 'svelte/compiler'; import { Page, PageComponent, ServerRoute, ManifestData } from '../interfaces'; import { posixify, reserved_words } from '../utils'; @@ -13,19 +12,6 @@ export default function create_manifest_data(cwd: string, extensions: string = ' throw new Error(`As of Sapper 0.21, the routes/ directory should become src/routes/`); } - function has_preload(file: string) { - const source = fs.readFileSync(path.join(cwd, file), 'utf-8'); - - if (/preload/.test(source)) { - try { - const { vars } = svelte.compile(source.replace(/]*>[^]*?<\/style>/g, ''), { generate: false }); - return vars.some((variable: any) => variable.module && variable.export_name === 'preload'); - } catch (err) {} - } - - return false; - } - function find_layout(file_name: string, component_name: string, dir: string = '') { const ext = component_extensions.find((ext) => fs.existsSync(path.join(cwd, dir, `${file_name}${ext}`))); const file = posixify(path.join(dir, `${file_name}${ext}`)) @@ -33,8 +19,7 @@ export default function create_manifest_data(cwd: string, extensions: string = ' return ext ? { name: component_name, - file: file, - has_preload: has_preload(file) + file: file } : null; } @@ -47,16 +32,14 @@ export default function create_manifest_data(cwd: string, extensions: string = ' default: true, type: 'layout', name: '_default_layout', - file: null, - has_preload: false + file: null }; const default_error: PageComponent = { default: true, type: 'error', name: '_default_error', - file: null, - has_preload: false + file: null }; function walk( @@ -161,8 +144,7 @@ export default function create_manifest_data(cwd: string, extensions: string = ' else if (item.is_page) { const component = { name: get_slug(item.file), - file: item.file, - has_preload: has_preload(item.file) + file: item.file }; components.push(component); diff --git a/src/interfaces.ts b/src/interfaces.ts index f768100b8..942a0b80a 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -30,7 +30,6 @@ export type PageComponent = { type?: string; name: string; file: string; - has_preload: boolean; }; export type Page = { diff --git a/test/unit/create_manifest_data/test.ts b/test/unit/create_manifest_data/test.ts index 804a61be1..4e8d8f3af 100644 --- a/test/unit/create_manifest_data/test.ts +++ b/test/unit/create_manifest_data/test.ts @@ -6,10 +6,10 @@ describe('manifest_data', () => { it('creates routes', () => { const { components, pages, server_routes } = create_manifest_data(path.join(__dirname, 'samples/basic')); - const index = { name: 'index', file: 'index.html', has_preload: false }; - const about = { name: 'about', file: 'about.html', has_preload: false }; - const blog = { name: 'blog', file: 'blog/index.html', has_preload: false }; - const blog_$slug = { name: 'blog_$slug', file: 'blog/[slug].html', has_preload: false }; + const index = { name: 'index', file: 'index.html' }; + const about = { name: 'about', file: 'about.html' }; + const blog = { name: 'blog', file: 'blog/index.html' }; + const blog_$slug = { name: 'blog_$slug', file: 'blog/[slug].html' }; assert.deepEqual(components, [ index, @@ -79,7 +79,7 @@ describe('manifest_data', () => { // had to remove ? and " because windows // const quote = { name: '$34', file: '".html' }; - const hash = { name: '$35', has_preload: false, file: '#.html' }; + const hash = { name: '$35', file: '#.html' }; // const question_mark = { name: '$63', file: '?.html' }; assert.deepEqual(components, [ @@ -206,10 +206,10 @@ describe('manifest_data', () => { it('works with custom extensions' , () => { const { components, pages, server_routes } = create_manifest_data(path.join(__dirname, 'samples/custom-extension'), '.jazz .beebop .funk .html'); - const index = { name: 'index', file: 'index.funk', has_preload: false }; - const about = { name: 'about', file: 'about.jazz', has_preload: false }; - const blog = { name: 'blog', file: 'blog/index.html', has_preload: false }; - const blog_$slug = { name: 'blog_$slug', file: 'blog/[slug].beebop', has_preload: false }; + const index = { name: 'index', file: 'index.funk' }; + const about = { name: 'about', file: 'about.jazz' }; + const blog = { name: 'blog', file: 'blog/index.html' }; + const blog_$slug = { name: 'blog_$slug', file: 'blog/[slug].beebop' }; assert.deepEqual(components, [ index,