Skip to content

Commit c02fe86

Browse files
benmccanntrmcnvn
authored andcommitted
TypeScript support: preload detection at runtime (sveltejs#1344)
1 parent f70983c commit c02fe86

File tree

7 files changed

+33
-52
lines changed

7 files changed

+33
-52
lines changed

runtime/src/app/app.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { writable } from 'svelte/store';
22
import App from '@sapper/internal/App.svelte';
3-
import { root_preload, ErrorComponent, ignore, components, routes } from '@sapper/internal/manifest-client';
3+
import { root_comp, ErrorComponent, ignore, components, routes } from '@sapper/internal/manifest-client';
44
import {
55
Target,
66
ScrollPosition,
@@ -297,6 +297,7 @@ export async function hydrate_target(target: Target): Promise<{
297297
};
298298

299299
if (!root_preloaded) {
300+
const root_preload = root_comp.preload || (() => {});
300301
root_preloaded = initial_data.preloaded[0] || root_preload.call(preload_context, {
301302
host: page.host,
302303
path: page.path,

runtime/src/server/middleware/get_page_handler.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,13 @@ export function get_page_handler(
174174
let params;
175175

176176
try {
177-
const root_preloaded = manifest.root_preload
178-
? manifest.root_preload.call(preload_context, {
177+
const root_preload = manifest.root_comp.preload || (() => {});
178+
const root_preloaded = root_preload.call(preload_context, {
179179
host: req.headers.host,
180180
path: req.path,
181181
query: req.query,
182182
params: {}
183-
}, session)
184-
: {};
183+
}, session);
185184

186185
match = error ? null : page.pattern.exec(req.path);
187186

@@ -194,8 +193,8 @@ export function get_page_handler(
194193
// the deepest level is used below, to initialise the store
195194
params = part.params ? part.params(match) : {};
196195

197-
return part.preload
198-
? part.preload.call(preload_context, {
196+
return part.component.preload
197+
? part.component.preload.call(preload_context, {
199198
host: req.headers.host,
200199
path: req.path,
201200
query: req.query,
@@ -277,7 +276,7 @@ export function get_page_handler(
277276
if (!part) continue;
278277

279278
props[`level${l++}`] = {
280-
component: part.component,
279+
component: part.component.default,
281280
props: preloaded[i + 1] || {},
282281
segment: segments[i]
283282
};

runtime/src/server/middleware/types.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@ export type Page = {
1010
pattern: RegExp;
1111
parts: Array<{
1212
name: string;
13-
component: Component;
13+
component: {
14+
default: Component;
15+
preload?: (data: any) => any | Promise<any>;
16+
},
1417
params?: (match: RegExpMatchArray) => Record<string, string>;
15-
preload?: (data: any) => any | Promise<any>;
1618
}>
1719
};
1820

1921
export type Manifest = {
2022
server_routes: ServerRoute[];
2123
pages: Page[];
22-
root: Component;
23-
root_preload?: (data: any) => any | Promise<any>;
24+
root_comp: Component;
2425
error: Component;
2526
}
2627

src/core/create_app.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,9 @@ function generate_client_manifest(
136136

137137
return `
138138
// This file is generated by Sapper — do not edit it!
139-
export { default as Root } from '${stringify(get_file(path_to_routes, manifest_data.root), false)}';
140-
export { preload as root_preload } from '${manifest_data.root.has_preload ? stringify(get_file(path_to_routes, manifest_data.root), false) : './shared'}';
139+
// webpack does not support export * as root_comp yet so do a two line import/export
140+
import * as root_comp from '${stringify(get_file(path_to_routes, manifest_data.root), false)}';
141+
export { root_comp };
141142
export { default as ErrorComponent } from '${stringify(get_file(path_to_routes, manifest_data.error), false)}';
142143
143144
export const ignore = [${server_routes_to_ignore.map(route => route.pattern).join(', ')}];
@@ -166,8 +167,8 @@ function generate_server_manifest(
166167
manifest_data.server_routes.map((route, i) =>
167168
`import * as route_${i} from ${stringify(posixify(`${path_to_routes}/${route.file}`))};`),
168169
manifest_data.components.map((component, i) =>
169-
`import component_${i}${component.has_preload ? `, { preload as preload_${i} }` : ''} from ${stringify(get_file(path_to_routes, component))};`),
170-
`import root${manifest_data.root.has_preload ? `, { preload as root_preload }` : ''} from ${stringify(get_file(path_to_routes, manifest_data.root))};`,
170+
`import * as component_${i} from ${stringify(get_file(path_to_routes, component))};`),
171+
`import * as root_comp from ${stringify(get_file(path_to_routes, manifest_data.root))};`,
171172
`import error from ${stringify(get_file(path_to_routes, manifest_data.error))};`
172173
);
173174

@@ -211,8 +212,7 @@ function generate_server_manifest(
211212
const props = [
212213
`name: "${part.component.name}"`,
213214
`file: ${stringify(part.component.file)}`,
214-
`component: component_${component_lookup[part.component.name]}`,
215-
part.component.has_preload && `preload: preload_${component_lookup[part.component.name]}`
215+
`component: component_${component_lookup[part.component.name]}`
216216
].filter(Boolean);
217217
218218
if (part.params.length > 0) {
@@ -226,8 +226,7 @@ function generate_server_manifest(
226226
}`).join(',\n\n\t\t\t\t')}
227227
],
228228
229-
root,
230-
root_preload${manifest_data.root.has_preload ? '' : `: () => {}`},
229+
root_comp,
231230
error
232231
};
233232

src/core/create_manifest_data.ts

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as fs from 'fs';
22
import * as path from 'path';
3-
import svelte from 'svelte/compiler';
43
import { Page, PageComponent, ServerRoute, ManifestData } from '../interfaces';
54
import { posixify, reserved_words } from '../utils';
65

@@ -13,28 +12,14 @@ export default function create_manifest_data(cwd: string, extensions: string = '
1312
throw new Error(`As of Sapper 0.21, the routes/ directory should become src/routes/`);
1413
}
1514

16-
function has_preload(file: string) {
17-
const source = fs.readFileSync(path.join(cwd, file), 'utf-8');
18-
19-
if (/preload/.test(source)) {
20-
try {
21-
const { vars } = svelte.compile(source.replace(/<style\b[^>]*>[^]*?<\/style>/g, ''), { generate: false });
22-
return vars.some((variable: any) => variable.module && variable.export_name === 'preload');
23-
} catch (err) {}
24-
}
25-
26-
return false;
27-
}
28-
2915
function find_layout(file_name: string, component_name: string, dir: string = '') {
3016
const ext = component_extensions.find((ext) => fs.existsSync(path.join(cwd, dir, `${file_name}${ext}`)));
3117
const file = posixify(path.join(dir, `${file_name}${ext}`))
3218

3319
return ext
3420
? {
3521
name: component_name,
36-
file: file,
37-
has_preload: has_preload(file)
22+
file: file
3823
}
3924
: null;
4025
}
@@ -47,16 +32,14 @@ export default function create_manifest_data(cwd: string, extensions: string = '
4732
default: true,
4833
type: 'layout',
4934
name: '_default_layout',
50-
file: null,
51-
has_preload: false
35+
file: null
5236
};
5337

5438
const default_error: PageComponent = {
5539
default: true,
5640
type: 'error',
5741
name: '_default_error',
58-
file: null,
59-
has_preload: false
42+
file: null
6043
};
6144

6245
function walk(
@@ -161,8 +144,7 @@ export default function create_manifest_data(cwd: string, extensions: string = '
161144
else if (item.is_page) {
162145
const component = {
163146
name: get_slug(item.file),
164-
file: item.file,
165-
has_preload: has_preload(item.file)
147+
file: item.file
166148
};
167149

168150
components.push(component);

src/interfaces.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ export type PageComponent = {
3030
type?: string;
3131
name: string;
3232
file: string;
33-
has_preload: boolean;
3433
};
3534

3635
export type Page = {

test/unit/create_manifest_data/test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ describe('manifest_data', () => {
66
it('creates routes', () => {
77
const { components, pages, server_routes } = create_manifest_data(path.join(__dirname, 'samples/basic'));
88

9-
const index = { name: 'index', file: 'index.html', has_preload: false };
10-
const about = { name: 'about', file: 'about.html', has_preload: false };
11-
const blog = { name: 'blog', file: 'blog/index.html', has_preload: false };
12-
const blog_$slug = { name: 'blog_$slug', file: 'blog/[slug].html', has_preload: false };
9+
const index = { name: 'index', file: 'index.html' };
10+
const about = { name: 'about', file: 'about.html' };
11+
const blog = { name: 'blog', file: 'blog/index.html' };
12+
const blog_$slug = { name: 'blog_$slug', file: 'blog/[slug].html' };
1313

1414
assert.deepEqual(components, [
1515
index,
@@ -79,7 +79,7 @@ describe('manifest_data', () => {
7979
// had to remove ? and " because windows
8080

8181
// const quote = { name: '$34', file: '".html' };
82-
const hash = { name: '$35', has_preload: false, file: '#.html' };
82+
const hash = { name: '$35', file: '#.html' };
8383
// const question_mark = { name: '$63', file: '?.html' };
8484

8585
assert.deepEqual(components, [
@@ -206,10 +206,10 @@ describe('manifest_data', () => {
206206
it('works with custom extensions' , () => {
207207
const { components, pages, server_routes } = create_manifest_data(path.join(__dirname, 'samples/custom-extension'), '.jazz .beebop .funk .html');
208208

209-
const index = { name: 'index', file: 'index.funk', has_preload: false };
210-
const about = { name: 'about', file: 'about.jazz', has_preload: false };
211-
const blog = { name: 'blog', file: 'blog/index.html', has_preload: false };
212-
const blog_$slug = { name: 'blog_$slug', file: 'blog/[slug].beebop', has_preload: false };
209+
const index = { name: 'index', file: 'index.funk' };
210+
const about = { name: 'about', file: 'about.jazz' };
211+
const blog = { name: 'blog', file: 'blog/index.html' };
212+
const blog_$slug = { name: 'blog_$slug', file: 'blog/[slug].beebop' };
213213

214214
assert.deepEqual(components, [
215215
index,

0 commit comments

Comments
 (0)