Skip to content

Commit

Permalink
Final (I think) stepping stone PR towards #519/#626 (#893)
Browse files Browse the repository at this point in the history
* create separate _load_error method

* make error component available to renderer

* include root layout in route manifests

* note to self

* allow unspecified adapter

* gah whoops

* smarter chunking

* fix chunking

* update tests
  • Loading branch information
Rich Harris committed Apr 5, 2021
1 parent 567e5e2 commit ccb8825
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 112 deletions.
1 change: 1 addition & 0 deletions packages/kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
},
"devDependencies": {
"@rollup/plugin-replace": "^2.4.1",
"@sveltejs/kit": "workspace:*",
"@types/amphtml-validator": "^1.0.1",
"@types/mime": "^2.0.3",
"@types/node": "^14.14.33",
Expand Down
19 changes: 11 additions & 8 deletions packages/kit/src/core/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,18 @@ async function build_client({

/** @type {Record<string, string>} */
const input = {
start: path.resolve(cwd, client_entry_file),
layout: path.resolve(cwd, manifest.layout),
error: path.resolve(cwd, manifest.error)
start: path.resolve(cwd, client_entry_file)
};

// This step is optional — Vite/Rollup will create the necessary chunks
// for everything regardless — but it means that entry chunks reflect
// their location in the source code, which is helpful for debugging
manifest.components.forEach((file) => {
const resolved = path.resolve(cwd, file);
const relative = path.relative(config.kit.files.routes, resolved);
input[path.join('pages', relative)] = resolved;

const name = relative.startsWith('..') ? path.basename(file) : path.join('pages', relative);
input[name] = resolved;
});

/** @type {any} */
Expand Down Expand Up @@ -152,7 +155,7 @@ async function build_client({

/** @type {ClientManifest} */
const client_manifest = JSON.parse(fs.readFileSync(client_manifest_file, 'utf-8'));
fs.unlinkSync(client_manifest_file);
fs.renameSync(client_manifest_file, `${output_dir}/manifest.json`); // inspectable but not shipped

return client_manifest;
}
Expand Down Expand Up @@ -200,6 +203,7 @@ async function build_server(
function find_deps(file, js_deps, css_deps) {
const chunk = client_manifest[file];

if (js_deps.has(chunk.file)) return;
js_deps.add(chunk.file);

if (chunk.css) {
Expand All @@ -214,8 +218,7 @@ async function build_server(
/** @type {Record<string, { entry: string, css: string[], js: string[], styles: string[] }>} */
const metadata_lookup = {};

// TODO include layout and error in manifest.components
[manifest.layout, manifest.error, ...manifest.components].forEach((file) => {
manifest.components.forEach((file) => {
const js_deps = new Set();
const css_deps = new Set();

Expand Down Expand Up @@ -305,7 +308,7 @@ async function build_server(
const hooks = get_hooks(user_hooks);
const module_lookup = {
${[manifest.layout, manifest.error, ...manifest.components].map(file => `${s(file)}: () => import(${s(app_relative(file))})`)}
${manifest.components.map(file => `${s(file)}: () => import(${s(app_relative(file))})`)}
};
const metadata_lookup = ${s(metadata_lookup)};
Expand Down
30 changes: 9 additions & 21 deletions packages/kit/src/core/create_app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,25 +89,22 @@ function generate_client_manifest(manifest_data, base) {
.filter(Boolean)
.join(', ');
return `// ${route.parts[route.parts.length - 1]}\n\t[${tuple}]`;
return `// ${route.parts[route.parts.length - 1]}\n\t\t[${tuple}]`;
} else {
return `// ${route.file}\n\t[${route.pattern}]`;
return `// ${route.file}\n\t\t[${route.pattern}]`;
}
})
.join(',\n\n\t')}
.join(',\n\n\t\t')}
]`.replace(/^\t/gm, '');

return trim(`
import * as layout from ${s(get_path(manifest_data.layout))};
const components = ${components};
const d = decodeURIComponent;
const empty = () => ({});
export const routes = ${routes};
export { layout };
export const fallback = [components[0](), components[1]()];
`);
}

Expand All @@ -133,9 +130,11 @@ function generate_app(manifest_data, base) {

let pyramid = `<svelte:component this={components[${l}]} {...(props_${l} || {})}/>`;

while (l-- > 1) {
while (l--) {
pyramid = `
<svelte:component this={components[${l}]} {...(props_${l} || {})}>
<svelte:component this={components[${l}]} {...(props_${l} || {})}${
l === 1 ? ' {status} {error}' : '' // TODO this is awkward
}>
{#if components[${l + 1}]}
${pyramid.replace(/\n/g, '\n\t\t\t\t\t')}
{/if}
Expand All @@ -145,13 +144,10 @@ function generate_app(manifest_data, base) {
.trim();
}

const error_file = path.relative(base, manifest_data.error);

return trim(`
<!-- This file is generated by @sveltejs/kit — do not edit it! -->
<script>
import { setContext, afterUpdate, onMount } from 'svelte';
import ErrorComponent from ${s(error_file)};
// error handling
export let status = undefined;
Expand All @@ -164,8 +160,6 @@ function generate_app(manifest_data, base) {
export let components;
${levels.map((l) => `export let props_${l} = null;`).join('\n\t\t\t')}
const Layout = components[0];
setContext('__svelte__', stores);
$: stores.page.set(page);
Expand All @@ -188,13 +182,7 @@ function generate_app(manifest_data, base) {
});
</script>
<Layout {...(props_0 || {})}>
{#if error}
<ErrorComponent {status} {error}/>
{:else}
${pyramid.replace(/\n/g, '\n\t\t\t\t')}
{/if}
</Layout>
${pyramid.replace(/\n/g, '\n\t\t')}
{#if mounted}
<div id="svelte-announcer" aria-live="assertive" aria-atomic="true">
Expand Down
4 changes: 3 additions & 1 deletion packages/kit/src/core/create_manifest_data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@ export default function create_manifest_data({ config, output, cwd = process.cwd
const layout = find_layout('$layout', base) || default_layout;
const error = find_layout('$error', base) || default_error;

walk(config.kit.files.routes, [], [], []);
components.push(layout, error);

walk(config.kit.files.routes, [], [], [layout]);

const assets_dir = config.kit.files.assets;

Expand Down
62 changes: 34 additions & 28 deletions packages/kit/src/core/create_manifest_data/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ const create = (dir, extensions = ['.svelte']) => {
appDir: '_app'
}
},
cwd
cwd,
output: cwd
});
};

const layout = 'components/layout.svelte';
const error = 'components/error.svelte';

test('creates routes', () => {
const { components, routes } = create('samples/basic');

Expand All @@ -36,21 +40,21 @@ test('creates routes', () => {
const blog = 'samples/basic/blog/index.svelte';
const blog_$slug = 'samples/basic/blog/[slug].svelte';

assert.equal(components, [index, about, blog, blog_$slug]);
assert.equal(components, [layout, error, index, about, blog, blog_$slug]);

assert.equal(routes, [
{
type: 'page',
pattern: /^\/$/,
params: [],
parts: [index]
parts: [layout, index]
},

{
type: 'page',
pattern: /^\/about\/?$/,
params: [],
parts: [about]
parts: [layout, about]
},

{
Expand All @@ -64,7 +68,7 @@ test('creates routes', () => {
type: 'page',
pattern: /^\/blog\/?$/,
params: [],
parts: [blog]
parts: [layout, blog]
},

{
Expand All @@ -78,7 +82,7 @@ test('creates routes', () => {
type: 'page',
pattern: /^\/blog\/([^/]+?)\/?$/,
params: ['slug'],
parts: [blog_$slug]
parts: [layout, blog_$slug]
}
]);
});
Expand All @@ -92,21 +96,21 @@ test('creates routes with layout', () => {
const foo = 'samples/basic-layout/foo/index.svelte';

assert.equal(layout, $layout);
assert.equal(components, [index, foo_$layout, foo]);
assert.equal(components, [layout, error, index, foo_$layout, foo]);

assert.equal(routes, [
{
type: 'page',
pattern: /^\/$/,
params: [],
parts: [index]
parts: [layout, index]
},

{
type: 'page',
pattern: /^\/foo\/?$/,
params: [],
parts: [foo_$layout, foo]
parts: [layout, foo_$layout, foo]
}
]);
});
Expand All @@ -121,6 +125,8 @@ test('encodes invalid characters', () => {
// const question_mark = 'samples/encoding/?.svelte';

assert.equal(components, [
layout,
error,
// quote,
hash
// question_mark
Expand All @@ -142,22 +148,22 @@ test('sorts routes correctly', () => {
assert.equal(
routes.map((p) => (p.type === 'page' ? p.parts : p.file)),
[
['samples/sorting/index.svelte'],
['samples/sorting/about.svelte'],
['samples/sorting/post/index.svelte'],
['samples/sorting/post/bar.svelte'],
['samples/sorting/post/foo.svelte'],
[layout, 'samples/sorting/index.svelte'],
[layout, 'samples/sorting/about.svelte'],
[layout, 'samples/sorting/post/index.svelte'],
[layout, 'samples/sorting/post/bar.svelte'],
[layout, 'samples/sorting/post/foo.svelte'],
'samples/sorting/post/f[zz].ts',
['samples/sorting/post/f[xx].svelte'],
['samples/sorting/post/f[yy].svelte'],
['samples/sorting/post/[id].svelte'],
[layout, 'samples/sorting/post/f[xx].svelte'],
[layout, 'samples/sorting/post/f[yy].svelte'],
[layout, 'samples/sorting/post/[id].svelte'],
'samples/sorting/[endpoint].js',
['samples/sorting/[wildcard].svelte'],
['samples/sorting/[...rest]/deep/[...deep_rest]/xyz.svelte'],
['samples/sorting/[...rest]/deep/[...deep_rest]/index.svelte'],
['samples/sorting/[...rest]/deep/index.svelte'],
['samples/sorting/[...rest]/abc.svelte'],
['samples/sorting/[...rest]/index.svelte']
[layout, 'samples/sorting/[wildcard].svelte'],
[layout, 'samples/sorting/[...rest]/deep/[...deep_rest]/xyz.svelte'],
[layout, 'samples/sorting/[...rest]/deep/[...deep_rest]/index.svelte'],
[layout, 'samples/sorting/[...rest]/deep/index.svelte'],
[layout, 'samples/sorting/[...rest]/abc.svelte'],
[layout, 'samples/sorting/[...rest]/index.svelte']
]
);
});
Expand Down Expand Up @@ -241,21 +247,21 @@ test('works with custom extensions', () => {
const blog = 'samples/custom-extension/blog/index.svelte';
const blog_$slug = 'samples/custom-extension/blog/[slug].beebop';

assert.equal(components, [index, about, blog, blog_$slug]);
assert.equal(components, [layout, error, index, about, blog, blog_$slug]);

assert.equal(routes, [
{
type: 'page',
pattern: /^\/$/,
params: [],
parts: [index]
parts: [layout, index]
},

{
type: 'page',
pattern: /^\/about\/?$/,
params: [],
parts: [about]
parts: [layout, about]
},

{
Expand All @@ -269,7 +275,7 @@ test('works with custom extensions', () => {
type: 'page',
pattern: /^\/blog\/?$/,
params: [],
parts: [blog]
parts: [layout, blog]
},

{
Expand All @@ -283,7 +289,7 @@ test('works with custom extensions', () => {
type: 'page',
pattern: /^\/blog\/([^/]+?)\/?$/,
params: ['slug'],
parts: [blog_$slug]
parts: [layout, blog_$slug]
}
]);
});
Expand Down
3 changes: 0 additions & 3 deletions packages/kit/src/core/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,6 @@ class Watcher extends EventEmitter {
},
manifest: this.manifest,
load_component: async (id) => {
// if (id === 'layout') id = this.manifest.layout;
// if (id === 'error') id = this.manifest.error;

const url = path.resolve(this.cwd, id);

const module = /** @type {SSRComponent} */ (await this.vite.ssrLoadModule(url));
Expand Down
4 changes: 2 additions & 2 deletions packages/kit/src/core/load_config/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ test('fills in defaults', () => {
compilerOptions: null,
extensions: ['.svelte'],
kit: {
adapter: [null],
adapter: null,
amp: false,
appDir: '_app',
files: {
Expand Down Expand Up @@ -93,7 +93,7 @@ test('fills in partial blanks', () => {
compilerOptions: null,
extensions: ['.svelte'],
kit: {
adapter: [null],
adapter: null,
amp: false,
appDir: '_app',
files: {
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/core/load_config/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const options = {
children: {
adapter: {
type: 'leaf',
default: [null],
default: null,
validate: (option, keypath) => {
if (typeof option !== 'object' || !option.adapt) {
let message = `${keypath} should be an object with an "adapt" method`;
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/core/load_config/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test('load default config', async () => {
compilerOptions: null,
extensions: ['.svelte'],
kit: {
adapter: [null],
adapter: null,
amp: false,
appDir: '_app',
files: {
Expand Down
Loading

0 comments on commit ccb8825

Please sign in to comment.