Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
Merge pull request #453 from sveltejs/gh-444
Browse files Browse the repository at this point in the history
move app logic into templates (#444)
  • Loading branch information
Rich-Harris authored Oct 1, 2018
2 parents ff24877 + 2e2b8dc commit 4d7d448
Show file tree
Hide file tree
Showing 34 changed files with 1,624 additions and 1,329 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ node_modules
cypress/screenshots
test/app/.sapper
test/app/src/manifest
__sapper__
test/app/export
test/app/build
sapper
Expand Down
1 change: 1 addition & 0 deletions index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1,013 changes: 624 additions & 389 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "sapper",
"version": "0.21.1",
"description": "Military-grade apps, engineered by Svelte",
"main": "dist/middleware.js",
"bin": {
"sapper": "./sapper"
},
Expand Down Expand Up @@ -32,6 +31,7 @@
"@types/mocha": "^5.2.5",
"@types/node": "^10.7.1",
"@types/rimraf": "^2.0.2",
"agadoo": "^1.0.1",
"cheap-watch": "^0.3.0",
"compression": "^1.7.1",
"cookie": "^0.3.1",
Expand Down
26 changes: 17 additions & 9 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,45 @@ import json from 'rollup-plugin-json';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import pkg from './package.json';
import { builtinModules } from 'module';

const external = [].concat(
Object.keys(pkg.dependencies),
Object.keys(process.binding('natives')),
'sapper/core.js'
);

export default [
{
input: `src/runtime/index.ts`,
function template(kind, external) {
return {
input: `templates/src/${kind}/index.ts`,
output: {
file: `runtime.js`,
file: `templates/dist/${kind}.js`,
format: 'es'
},
external,
plugins: [
resolve(),
commonjs(),
string({
include: '**/*.md'
}),
typescript({
typescript: require('typescript'),
target: "ES2017"
})
]
},
};
}

export default [
template('client', ['__ROOT__', '__ERROR__']),
template('server', builtinModules),

{
input: [
`src/api.ts`,
`src/cli.ts`,
`src/core.ts`,
`src/middleware.ts`,
`src/rollup.ts`,
`src/webpack.ts`
],
Expand All @@ -42,9 +53,6 @@ export default [
},
external,
plugins: [
string({
include: '**/*.md'
}),
json(),
resolve(),
commonjs(),
Expand Down
1 change: 0 additions & 1 deletion runtime/README.md

This file was deleted.

2 changes: 0 additions & 2 deletions runtime/app.js

This file was deleted.

11 changes: 4 additions & 7 deletions src/api/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@ import * as path from 'path';
import mkdirp from 'mkdirp';
import rimraf from 'rimraf';
import { EventEmitter } from 'events';
import * as codec from 'sourcemap-codec';
import hash from 'string-hash';
import minify_html from './utils/minify_html';
import { create_compilers, create_main_manifests, create_manifest_data, create_serviceworker_manifest } from '../core';
import * as events from './interfaces';
import { copy_shimport } from './utils/copy_shimport';
import { Dirs, PageComponent } from '../interfaces';
import { CompileResult } from '../core/create_compilers/interfaces';
import { Dirs } from '../interfaces';
import read_template from '../core/read_template';

type Opts = {
legacy: boolean;
bundler: string;
bundler: 'rollup' | 'webpack';
};

export function build(opts: Opts, dirs: Dirs) {
Expand Down Expand Up @@ -58,7 +55,7 @@ async function execute(emitter: EventEmitter, opts: Opts, dirs: Dirs) {
// create src/manifest/client.js and src/manifest/server.js
create_main_manifests({ bundler: opts.bundler, manifest_data });

const { client, server, serviceworker } = await create_compilers(opts.bundler, dirs);
const { client, server, serviceworker } = await create_compilers(opts.bundler);

const client_result = await client.compile();
emitter.emit('build', <events.BuildEvent>{
Expand All @@ -71,7 +68,7 @@ async function execute(emitter: EventEmitter, opts: Opts, dirs: Dirs) {

if (opts.legacy) {
process.env.SAPPER_LEGACY_BUILD = 'true';
const { client } = await create_compilers(opts.bundler, dirs);
const { client } = await create_compilers(opts.bundler);

const client_result = await client.compile();

Expand Down
6 changes: 3 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ prog.command('build [dest]')
.option('--bundler', 'Specify a bundler (rollup or webpack, blank for auto)')
.option('--legacy', 'Create separate legacy build')
.example(`build custom-dir -p 4567`)
.action(async (dest = 'build', opts: {
.action(async (dest = '__sapper__/build', opts: {
port: string,
legacy: boolean,
bundler?: string
Expand Down Expand Up @@ -80,12 +80,12 @@ prog.command('start [dir]')
prog.command('export [dest]')
.describe('Export your app as static files (if possible)')
.option('--build', '(Re)build app before exporting', true)
.option('--build-dir', 'Specify a custom temporary build directory', '.sapper/prod')
.option('--build-dir', 'Specify a custom temporary build directory', '__sapper__/build')
.option('--basepath', 'Specify a base path')
.option('--timeout', 'Milliseconds to wait for a page (--no-timeout to disable)', 5000)
.option('--legacy', 'Create separate legacy build')
.option('--bundler', 'Specify a bundler (rollup or webpack, blank for auto)')
.action(async (dest = 'export', opts: {
.action(async (dest = '__sapper__/export', opts: {
build: boolean,
legacy: boolean,
bundler?: string,
Expand Down
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ export const locations = {
src: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_SRC || 'src'),
static: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_STATIC || 'static'),
routes: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_ROUTES || 'src/routes'),
dest: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_DEST || `.sapper/${dev() ? 'dev' : 'prod'}`)
dest: () => path.resolve(process.env.SAPPER_BASE || '', process.env.SAPPER_DEST || `__sapper__/${dev() ? 'dev' : 'build'}`)
};
115 changes: 62 additions & 53 deletions src/core/create_manifests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function create_main_manifests({ bundler, manifest_data, dev_port }: {
manifest_data: ManifestData;
dev_port?: number;
}) {
const manifest_dir = path.join(locations.src(), 'manifest');
const manifest_dir = '__sapper__';
if (!fs.existsSync(manifest_dir)) fs.mkdirSync(manifest_dir);

const path_to_routes = path.relative(manifest_dir, locations.routes());
Expand Down Expand Up @@ -55,7 +55,7 @@ export function create_serviceworker_manifest({ manifest_data, client_files }: {
export const routes = [\n\t${manifest_data.pages.map((r: Page) => `{ pattern: ${r.pattern} }`).join(',\n\t')}\n];
`.replace(/^\t\t/gm, '').trim();

write_if_changed(`${locations.src()}/manifest/service-worker.js`, code);
write_if_changed(`__sapper__/service-worker.js`, code);
}

function generate_client(
Expand All @@ -64,92 +64,100 @@ function generate_client(
bundler: string,
dev_port?: number
) {
const template_file = path.resolve(__dirname, '../templates/dist/client.js');
const template = fs.readFileSync(template_file, 'utf-8');

const page_ids = new Set(manifest_data.pages.map(page =>
page.pattern.toString()));

const server_routes_to_ignore = manifest_data.server_routes.filter(route =>
!page_ids.has(route.pattern.toString()));

let code = `
// This file is generated by Sapper — do not edit it!
import root from ${stringify(get_file(path_to_routes, manifest_data.root))};
import error from ${stringify(posixify(`${path_to_routes}/_error.html`))};
const d = decodeURIComponent;
const component_indexes: Record<string, number> = {};

${manifest_data.components.map(component => {
const components = `[
${manifest_data.components.map((component, i) => {
const annotation = bundler === 'webpack'
? `/* webpackChunkName: "${component.name}" */ `
: '';
const source = get_file(path_to_routes, component);
return `const ${component.name} = {
component_indexes[component.name] = i;
return `{
js: () => import(${annotation}${stringify(source)}),
css: "__SAPPER_CSS_PLACEHOLDER:${stringify(component.file, false)}__"
};`;
}).join('\n')}
export const manifest = {
ignore: [${server_routes_to_ignore.map(route => route.pattern).join(', ')}],
pages: [
${manifest_data.pages.map(page => `{
// ${page.parts[page.parts.length - 1].component.file}
pattern: ${page.pattern},
parts: [
${page.parts.map(part => {
if (part === null) return 'null';
if (part.params.length > 0) {
const props = part.params.map((param, i) => `${param}: d(match[${i + 1}])`);
return `{ component: ${part.component.name}, params: match => ({ ${props.join(', ')} }) }`;
}
return `{ component: ${part.component.name} }`;
}).join(',\n\t\t\t\t\t\t')}
]
}`).join(',\n\n\t\t\t\t')}
],
root,
error
};
}`;
}).join(',\n\t\t')}
]`.replace(/^\t/gm, '').trim();

let needs_decode = false;

let pages = `[
${manifest_data.pages.map(page => `{
// ${page.parts[page.parts.length - 1].component.file}
pattern: ${page.pattern},
parts: [
${page.parts.map(part => {
if (part === null) return 'null';
if (part.params.length > 0) {
needs_decode = true;
const props = part.params.map((param, i) => `${param}: d(match[${i + 1}])`);
return `{ i: ${component_indexes[part.component.name]}, params: match => ({ ${props.join(', ')} }) }`;
}
return `{ i: ${component_indexes[part.component.name]} }`;
}).join(',\n\t\t\t\t')}
]
}`).join(',\n\n\t\t')}
]`.replace(/^\t/gm, '').trim();

if (needs_decode) {
pages = `(d => ${pages})(decodeURIComponent)`
}

// this is included for legacy reasons
export const routes = {};`.replace(/^\t\t/gm, '').trim();
let footer = '';

if (dev()) {
const sapper_dev_client = posixify(
path.resolve(__dirname, '../sapper-dev-client.js')
);

code += `
footer = `
import(${stringify(sapper_dev_client)}).then(client => {
client.connect(${dev_port});
});`.replace(/^\t{3}/gm, '');
}

return code;
return `// This file is generated by Sapper — do not edit it!\n` + template
.replace('__ROOT__', stringify(get_file(path_to_routes, manifest_data.root), false))
.replace('__ERROR__', stringify(posixify(`${path_to_routes}/_error.html`), false))
.replace('__IGNORE__', `[${server_routes_to_ignore.map(route => route.pattern).join(', ')}]`)
.replace('__COMPONENTS__', components)
.replace('__PAGES__', pages) +
footer;
}

function generate_server(
manifest_data: ManifestData,
path_to_routes: string
) {
const template_file = path.resolve(__dirname, '../templates/dist/server.js');
const template = fs.readFileSync(template_file, 'utf-8');

const imports = [].concat(
manifest_data.server_routes.map(route =>
`import * as ${route.name} from ${stringify(posixify(`${path_to_routes}/${route.file}`))};`),
`import * as __${route.name} from ${stringify(posixify(`${path_to_routes}/${route.file}`))};`),
manifest_data.components.map(component =>
`import ${component.name} from ${stringify(get_file(path_to_routes, component))};`),
`import __${component.name} from ${stringify(get_file(path_to_routes, component))};`),
`import root from ${stringify(get_file(path_to_routes, manifest_data.root))};`,
`import error from ${stringify(posixify(`${path_to_routes}/_error.html`))};`
);

let code = `
// This file is generated by Sapper — do not edit it!
${imports.join('\n')}
const d = decodeURIComponent;
Expand All @@ -159,7 +167,7 @@ function generate_server(
${manifest_data.server_routes.map(route => `{
// ${route.file}
pattern: ${route.pattern},
handlers: ${route.name},
handlers: __${route.name},
params: ${route.params.length > 0
? `match => ({ ${route.params.map((param, i) => `${param}: d(match[${i + 1}])`).join(', ')} })`
: `() => ({})`}
Expand All @@ -177,7 +185,7 @@ function generate_server(
const props = [
`name: "${part.component.name}"`,
`file: ${stringify(part.component.file)}`,
`component: ${part.component.name}`
`component: __${part.component.name}`
];
if (part.params.length > 0) {
Expand All @@ -194,12 +202,13 @@ function generate_server(
root,
error
};
// this is included for legacy reasons
export const routes = {};`.replace(/^\t\t/gm, '').trim();
};`.replace(/^\t\t/gm, '').trim();

return code;
return `// This file is generated by Sapper — do not edit it!\n` + template
.replace('__BUILD__DIR__', JSON.stringify(locations.dest()))
.replace('__SRC__DIR__', JSON.stringify(locations.src()))
.replace('__DEV__', dev() ? 'true' : 'false')
.replace(/const manifest = __MANIFEST__;/, code);
}

function get_file(path_to_routes: string, component: PageComponent) {
Expand Down
Loading

0 comments on commit 4d7d448

Please sign in to comment.