Skip to content

Commit

Permalink
namespaced kit options (#236)
Browse files Browse the repository at this point in the history
* kitOptions namespace

* kitOptions -> kit

* add validation, rename kit.paths -> kit.files

* add changeset

* fix adapt option

* lint
  • Loading branch information
Rich-Harris authored Dec 7, 2020
1 parent b04833b commit 0e45255
Show file tree
Hide file tree
Showing 15 changed files with 251 additions and 78 deletions.
6 changes: 6 additions & 0 deletions .changeset/fuzzy-ghosts-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'create-svelte': patch
'@sveltejs/kit': patch
---

Move options behind kit namespace, change paths -> kit.files
12 changes: 7 additions & 5 deletions examples/hn.svelte.dev/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module.exports = {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-netlify'
};
kit: {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-netlify'
}
};
10 changes: 6 additions & 4 deletions examples/realworld.svelte.dev/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module.exports = {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-node'
kit: {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-node'
}
};
10 changes: 6 additions & 4 deletions examples/sandbox/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module.exports = {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-node'
kit: {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-node'
}
};
10 changes: 6 additions & 4 deletions examples/svelte-kit-demo/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module.exports = {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-node'
kit: {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-node'
}
};
10 changes: 6 additions & 4 deletions packages/create-svelte/template/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module.exports = {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-node'
kit: {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: '@sveltejs/adapter-node'
}
};
17 changes: 7 additions & 10 deletions packages/kit/src/api/adapt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@ import { logger } from '../utils';
import Builder from './Builder';

export async function adapt(config) {
if (!config.adapter) {
throw new Error('No adapter specified');
}
const [adapter, options] = config.adapter;

if (typeof config.adapter !== 'string') {
// TODO
throw new Error('Adapter must be a string');
if (!adapter) {
throw new Error('No adapter specified');
}

const log = logger();

console.log(colors.bold().cyan(`\n> Using ${config.adapter}`));
console.log(colors.bold().cyan(`\n> Using ${adapter}`));

const manifest_file = resolve('.svelte/build/manifest.cjs');

Expand All @@ -29,13 +26,13 @@ export async function adapt(config) {

const builder = new Builder({
generated_files: '.svelte/build/optimized',
static_files: config.paths.static,
static_files: config.files.static,
manifest,
log
});

const adapter = relative(config.adapter);
await adapter(builder);
const fn = relative(adapter);
await fn(builder, options);

log.success('done');
}
8 changes: 4 additions & 4 deletions packages/kit/src/api/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const OPTIMIZED = `${DIR}/build/optimized`;
const s = JSON.stringify;

export async function build(config) {
const manifest = create_manifest_data(config.paths.routes);
const manifest = create_manifest_data(config.files.routes);

mkdirp(ASSETS);
await rimraf(UNOPTIMIZED);
Expand Down Expand Up @@ -76,7 +76,7 @@ export async function build(config) {

render();

const mount = `--mount.${config.paths.routes}=/_app/routes --mount.${config.paths.setup}=/_app/setup`;
const mount = `--mount.${config.files.routes}=/_app/routes --mount.${config.files.setup}=/_app/setup`;

const promises = {
transform_client: exec(`node ${snowpack_bin} build ${mount} --out=${UNOPTIMIZED}/client`).then(
Expand Down Expand Up @@ -271,14 +271,14 @@ export async function build(config) {
import * as setup from './_app/setup/index.js';
import manifest from '../../manifest.js';
const template = ({ head, body }) => ${s(fs.readFileSync(config.paths.template, 'utf-8'))
const template = ({ head, body }) => ${s(fs.readFileSync(config.files.template, 'utf-8'))
.replace('%svelte.head%', '" + head + "')
.replace('%svelte.body%', '" + body + "')};
const client = ${s(client)};
export const paths = {
static: ${s(config.paths.static)}
static: ${s(config.files.static)}
};
export function render(request, { only_prerender = false } = {}) {
Expand Down
14 changes: 7 additions & 7 deletions packages/kit/src/api/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Watcher extends EventEmitter {

async init_filewatcher() {
this.cheapwatch = new CheapWatch({
dir: this.config.paths.routes,
dir: this.config.files.routes,
filter: ({ path }) => path.split('/').every((part) => !part.startsWith('_'))
});

Expand All @@ -77,12 +77,12 @@ class Watcher extends EventEmitter {
pkg
);

this.snowpack_config.mount[resolve(this.config.paths.routes)] = {
this.snowpack_config.mount[resolve(this.config.files.routes)] = {
url: '/_app/routes',
static: false,
resolve: true
};
this.snowpack_config.mount[resolve(this.config.paths.setup)] = {
this.snowpack_config.mount[resolve(this.config.files.setup)] = {
url: '/_app/setup',
static: false,
resolve: true
Expand All @@ -99,7 +99,7 @@ class Watcher extends EventEmitter {
async init_server() {
const load = loader(this.snowpack, this.snowpack_config);

const static_handler = sirv(this.config.paths.static, {
const static_handler = sirv(this.config.files.static, {
dev: true
});

Expand All @@ -123,7 +123,7 @@ class Watcher extends EventEmitter {

if (req.url === '/favicon.ico') return;

const template = readFileSync(this.config.paths.template, 'utf-8').replace(
const template = readFileSync(this.config.files.template, 'utf-8').replace(
'</head>',
`
<script>window.HMR_WEBSOCKET_URL = \`ws://localhost:${this.snowpack_port}\`;</script>
Expand Down Expand Up @@ -163,7 +163,7 @@ class Watcher extends EventEmitter {
body
},
{
static_dir: this.config.paths.static,
static_dir: this.config.files.static,
template: ({ head, body }) =>
template.replace('%svelte.head%', () => head).replace('%svelte.body%', () => body),
manifest: this.manifest,
Expand Down Expand Up @@ -195,7 +195,7 @@ class Watcher extends EventEmitter {
}

update() {
this.manifest = create_manifest_data(this.config.paths.routes);
this.manifest = create_manifest_data(this.config.files.routes);

create_app({
manifest_data: this.manifest,
Expand Down
69 changes: 53 additions & 16 deletions packages/kit/src/api/load_config/index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,62 @@
import relative from 'require-relative';
import { bold, yellow } from 'kleur/colors';
import options from './options';

const default_config = {
target: null,
startGlobal: null, // used for testing
paths: {
static: 'static',
routes: 'src/routes',
setup: 'src/setup',
template: 'src/app.html'
function warn(msg) {
console.log(bold(yellow(msg)));
}

function validate(definition, option, keypath) {
for (const key in option) {
if (!(key in definition)) {
throw new Error(`Unexpected option ${keypath}.${key}`);
}
}
};

const merged = {};

for (const key in definition) {
const expected = definition[key];
const actual = option[key];

const child_keypath = `${keypath}.${key}`;
const has_children = expected.default && typeof expected.default === 'object' && !Array.isArray(expected.default);

if (key in option) {
if (has_children) {
if (actual && (typeof actual !== 'object' || Array.isArray(actual))) {
throw new Error(`${keypath}.${key} should be an object`);
}

merged[key] = validate(expected.default, actual, child_keypath);
} else {
merged[key] = expected.validate(actual, child_keypath);
}
} else {
merged[key] = has_children
? validate(expected.default, {}, child_keypath)
: expected.default;
}
}

return merged;
}

const expected = new Set(['compilerOptions', 'kit', 'preprocess']);

export function load_config({ cwd = process.cwd() } = {}) {
const config = relative('./svelte.config.js', cwd);
return validate_config(config);
}

return {
...default_config,
...config,
paths: {
...default_config.paths,
...config.paths
export function validate_config(config) {
for (const key in config) {
if (!expected.has(key)) {
warn(`Unexpected option ${key}${key in options ? ` (did you mean kit.${key}?)` : ''}`);
}
};
}

const { kit = {} } = config;

return validate(options, kit, 'kit');
}
65 changes: 65 additions & 0 deletions packages/kit/src/api/load_config/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { test } from 'uvu';
import * as assert from 'uvu/assert';
import { validate_config } from './index';

test('fills in defaults', () => {
const validated = validate_config({});

assert.equal(validated, {
adapter: [null],
target: null,
startGlobal: null,
files: {
assets: 'static',
routes: 'src/routes',
setup: 'src/setup',
template: 'src/app.html'
}
});
});

test('errors on invalid values', () => {
assert.throws(() => {
validate_config({
kit: {
target: 42
}
});
}, /^kit\.target should be a string, if specified$/);
});

test('errors on invalid nested values', () => {
assert.throws(() => {
validate_config({
kit: {
files: {
potato: 'blah'
}
}
});
}, /^Unexpected option kit\.files\.potato$/);
});

test('fills in partial blanks', () => {
const validated = validate_config({
kit: {
files: {
assets: 'public'
}
}
});

assert.equal(validated, {
adapter: [null],
target: null,
startGlobal: null,
files: {
assets: 'public',
routes: 'src/routes',
setup: 'src/setup',
template: 'src/app.html'
}
});
});

test.run();
Loading

0 comments on commit 0e45255

Please sign in to comment.