update manifest generation

This commit is contained in:
Rich Harris
2018-07-16 11:21:24 -04:00
parent 624f17364c
commit 969430716f
3 changed files with 98 additions and 65 deletions

View File

@@ -3,10 +3,10 @@ import * as path from 'path';
import * as glob from 'glob';
import { posixify, write_if_changed } from './utils';
import { dev, locations } from '../config';
import { Route } from '../interfaces';
import { Page, PageComponent, ServerRoute } from '../interfaces';
export function create_main_manifests({ routes, dev_port }: {
routes: Route[];
routes: { components: PageComponent[], pages: Page[], server_routes: ServerRoute[] };
dev_port?: number;
}) {
const path_to_routes = path.relative(`${locations.app()}/manifest`, locations.routes());
@@ -19,7 +19,7 @@ export function create_main_manifests({ routes, dev_port }: {
}
export function create_serviceworker_manifest({ routes, client_files }: {
routes: Route[];
routes: { components: PageComponent[], pages: Page[], server_routes: ServerRoute[] };
client_files: string[];
}) {
const assets = glob.sync('**', { cwd: 'assets', nodir: true });
@@ -32,37 +32,61 @@ export function create_serviceworker_manifest({ routes, client_files }: {
export const shell = [\n\t${client_files.map((x: string) => `"${x}"`).join(',\n\t')}\n];
export const routes = [\n\t${routes.pages.filter(r => r.id !== '_error').map((r: Route) => `{ pattern: ${r.pattern} }`).join(',\n\t')}\n];
export const routes = [\n\t${routes.pages.map((r: Page) => `{ pattern: ${r.pattern} }`).join(',\n\t')}\n];
`.replace(/^\t\t/gm, '').trim();
write_if_changed(`${locations.app()}/manifest/service-worker.js`, code);
}
function generate_client(routes: Route[], path_to_routes: string, dev_port?: number) {
const page_ids = new Set(routes.pages.map(page => page.id));
const server_routes_to_ignore = routes.server_routes.filter(route => !page_ids.has(route.id));
function right_pad(str: string, len: number) {
while (str.length < len) str += ' ';
return str;
}
const pages = routes.pages.filter(page => page.id !== '_error');
const error_route = routes.pages.find(page => page.id === '_error');
function generate_client(
routes: { components: PageComponent[], pages: Page[], server_routes: ServerRoute[] },
path_to_routes: string,
dev_port?: number
) {
const page_ids = new Set(routes.pages.map(page =>
page.pattern.toString()));
const server_routes_to_ignore = routes.server_routes.filter(route =>
!page_ids.has(route.pattern.toString()));
const len = Math.max(...routes.components.map(c => c.name.length));
let code = `
// This file is generated by Sapper — do not edit it!
import root from '${posixify(`${path_to_routes}/index.html`)}';
${routes.components.map(component =>
`const ${right_pad(component.name, len)} = () => import('${posixify(`${path_to_routes}/${component.file}`)}');`)
.join('\n')}
export const routes = {
ignore: [${server_routes_to_ignore.map(route => route.pattern).join(', ')}],
root,
pages: [
${pages.map(page => {
const file = posixify(`${path_to_routes}/${page.file}`);
${routes.pages.map(page => `{
// ${page.parts[page.parts.length - 1].component.file}
pattern: ${page.pattern},
parts: [
${page.parts.map(part => {
if (part.params.length > 0) {
const props = part.params.map((param, i) => `${param}: match[${i + 1}]`);
return `{ component: ${part.component.name}, params: match => ({ ${props.join(', ')} }) }`;
}
const params = page.params.length === 0
? '{}'
: `{ ${page.params.map((part, i) => `${part}: match[${i + 1}]`).join(', ')} }`;
return `{ pattern: ${page.pattern}, params: ${page.params.length > 0 ? `match` : `()`} => (${params}), load: () => import(/* webpackChunkName: "${page.id}" */ '${file}') }`;
}).join(',\n\t\t\t\t')}
return `{ component: ${part.component.name} }`;
}).join(',\n\t\t\t\t\t\t')}
]
}`).join(',\n\n\t\t\t\t')}
],
error: () => import(/* webpackChunkName: '_error' */ '${posixify(`${path_to_routes}/${error_route.file}`)}')
error: () => import(/* webpackChunkName: '_error' */ '${posixify(`${path_to_routes}/_error.html`)}')
};`.replace(/^\t\t/gm, '').trim();
if (dev()) {
@@ -82,16 +106,17 @@ function generate_client(routes: Route[], path_to_routes: string, dev_port?: num
return code;
}
function generate_server(routes: Route[], path_to_routes: string) {
const pages = routes.pages.filter(page => page.id !== '_error');
const error_route = routes.pages.find(page => page.id === '_error');
function generate_server(
routes: { components: PageComponent[], pages: Page[], server_routes: ServerRoute[] },
path_to_routes: string
) {
const imports = [].concat(
routes.server_routes.map(route =>
`import * as route_${route.id} from '${posixify(`${path_to_routes}/${route.file}`)}';`),
pages.map(page =>
`import page_${page.id} from '${posixify(`${path_to_routes}/${page.file}`)}';`),
`import error from '${posixify(`${path_to_routes}/${error_route.file}`)}';`
`import * as ${route.name} from '${posixify(`${path_to_routes}/${route.file}`)}';`),
routes.components.map(component =>
`import ${component.name} from '${posixify(`${path_to_routes}/${component.file}`)}';`),
`import root from '${posixify(`${path_to_routes}/index.html`)}';`,
`import error from '${posixify(`${path_to_routes}/_error.html`)}';`
);
let code = `
@@ -100,29 +125,36 @@ function generate_server(routes: Route[], path_to_routes: string) {
export const routes = {
server_routes: [
${routes.server_routes.map(route => {
const params = route.params.length === 0
? '{}'
: `{ ${route.params.map((part, i) => `${part}: match[${i + 1}]`).join(', ')} }`;
return `{ id: '${route.id}', pattern: ${route.pattern}, params: ${route.params.length > 0 ? `match` : `()`} => (${params}), handlers: route_${route.id} }`;
}).join(',\n\t\t\t\t')}
${routes.server_routes.map(route => `{
// ${route.file}
pattern: ${route.pattern},
handlers: ${route.name},
params: ${route.params.length > 0
? `match => ({ ${route.params.map((param, i) => `${param}: match[${i + 1}]`).join(', ')} })`
: `() => ({})`}
}`).join(',\n\n\t\t\t\t')}
],
pages: [
${pages.map(page => {
const params = page.params.length === 0
? '{}'
: `{ ${page.params.map((part, i) => `${part}: match[${i + 1}]`).join(', ')} }`;
${routes.pages.map(page => `{
// ${page.parts[page.parts.length - 1].component.file}
pattern: ${page.pattern},
parts: [
${page.parts.map(part => {
if (part.params.length > 0) {
const props = part.params.map((param, i) => `${param}: match[${i + 1}]`);
return `{ component: ${part.component.name}, params: match => ({ ${props.join(', ')} }) }`;
}
return `{ id: '${page.id}', pattern: ${page.pattern}, params: ${page.params.length > 0 ? `match` : `()`} => (${params}), handler: page_${page.id} }`;
}).join(',\n\t\t\t\t')}
return `{ component: ${part.component.name} }`;
}).join(',\n\t\t\t\t\t\t')}
]
}`).join(',\n\n\t\t\t\t')}
],
error: {
error: true,
handler: error
}
root,
error
};`.replace(/^\t\t/gm, '').trim();
return code;

View File

@@ -1,29 +1,10 @@
import * as fs from 'fs';
import * as path from 'path';
import { locations } from '../config';
type Component = {
name: string;
file: string;
};
type Page = {
pattern: RegExp;
parts: Array<{
component: Component;
params: string[];
}>
};
type ServerRoute = {
name: string;
pattern: RegExp;
file: string;
params: string[];
};
import { Page, PageComponent, ServerRoute } from '../interfaces';
export default function create_routes(cwd = locations.routes()) {
const components: Component[] = [];
const components: PageComponent[] = [];
const pages: Page[] = [];
const server_routes: ServerRoute[] = [];
@@ -32,7 +13,7 @@ export default function create_routes(cwd = locations.routes()) {
parent_segments: Part[][],
parent_params: string[],
stack: Array<{
component: Component,
component: PageComponent,
params: string[]
}>
) {

View File

@@ -18,4 +18,24 @@ export type Template = {
export type Store = {
get: () => any;
};
export type PageComponent = {
name: string;
file: string;
};
export type Page = {
pattern: RegExp;
parts: Array<{
component: PageComponent;
params: string[];
}>
};
export type ServerRoute = {
name: string;
pattern: RegExp;
file: string;
params: string[];
};