mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-15 12:24:47 +00:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3531cc587d | ||
|
|
562a91fa57 | ||
|
|
93128a0156 | ||
|
|
d7a2132966 | ||
|
|
56ac1aea9d | ||
|
|
37a9fb62e2 | ||
|
|
a70e88b1f4 | ||
|
|
6f9ce9ce85 | ||
|
|
b13cc6f39a | ||
|
|
2758382c68 | ||
|
|
dd7f1ff99c | ||
|
|
45142cd037 | ||
|
|
ceb1caf1de | ||
|
|
7e263a3076 | ||
|
|
ec88d4a430 | ||
|
|
909ea72108 | ||
|
|
cd09d75d99 | ||
|
|
0e3abe489a | ||
|
|
a5d141d2f1 | ||
|
|
87eae6164b | ||
|
|
97e00f5a9c | ||
|
|
bd55558b5e | ||
|
|
25dc4b3a4c | ||
|
|
72c27b78a3 | ||
|
|
25809ec409 | ||
|
|
3220c522d7 | ||
|
|
d5d25f1d30 | ||
|
|
7ccd6ba329 | ||
|
|
35c30ae2c5 |
31
CHANGELOG.md
31
CHANGELOG.md
@@ -1,5 +1,36 @@
|
|||||||
# sapper changelog
|
# sapper changelog
|
||||||
|
|
||||||
|
## 0.10.7
|
||||||
|
|
||||||
|
* Allow routes to have a leading `.` ([#243](https://github.com/sveltejs/sapper/pull/243))
|
||||||
|
* Only encode necessary characters in routes ([#234](https://github.com/sveltejs/sapper/pull/234))
|
||||||
|
* Preserve existing `process.env` when exporting ([#245](https://github.com/sveltejs/sapper/pull/245))
|
||||||
|
|
||||||
|
## 0.10.6
|
||||||
|
|
||||||
|
* Fix error reporting in `sapper start`
|
||||||
|
|
||||||
|
## 0.10.5
|
||||||
|
|
||||||
|
* Fix missing service worker ([#231](https://github.com/sveltejs/sapper/pull/231))
|
||||||
|
|
||||||
|
## 0.10.4
|
||||||
|
|
||||||
|
* Upgrade chokidar, this time with a fix ([#227](https://github.com/sveltejs/sapper/pull/227))
|
||||||
|
|
||||||
|
## 0.10.3
|
||||||
|
|
||||||
|
* Downgrade chokidar ([#212](https://github.com/sveltejs/sapper/issues/212))
|
||||||
|
|
||||||
|
## 0.10.2
|
||||||
|
|
||||||
|
* Attach `store` to error pages
|
||||||
|
* Fix sorting edge case ([#215](https://github.com/sveltejs/sapper/pull/215))
|
||||||
|
|
||||||
|
## 0.10.1
|
||||||
|
|
||||||
|
* Fix server-side `fetch` paths ([#207](https://github.com/sveltejs/sapper/pull/207))
|
||||||
|
|
||||||
## 0.10.0
|
## 0.10.0
|
||||||
|
|
||||||
* Support mounting on a path (this requires `app/template.html` to include `%sapper.base%`) ([#180](https://github.com/sveltejs/sapper/issues/180))
|
* Support mounting on a path (this requires `app/template.html` to include `%sapper.base%`) ([#180](https://github.com/sveltejs/sapper/issues/180))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sapper",
|
"name": "sapper",
|
||||||
"version": "0.10.0",
|
"version": "0.10.7",
|
||||||
"description": "Military-grade apps, engineered by Svelte",
|
"description": "Military-grade apps, engineered by Svelte",
|
||||||
"main": "dist/middleware.ts.js",
|
"main": "dist/middleware.ts.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cheerio": "^1.0.0-rc.2",
|
"cheerio": "^1.0.0-rc.2",
|
||||||
"chokidar": "^2.0.2",
|
"chokidar": "^2.0.3",
|
||||||
"clorox": "^1.0.3",
|
"clorox": "^1.0.3",
|
||||||
"cookie": "^0.3.1",
|
"cookie": "^0.3.1",
|
||||||
"devalue": "^1.0.1",
|
"devalue": "^1.0.1",
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ export async function dev(opts: { port: number, open: boolean }) {
|
|||||||
|
|
||||||
const hot_update_server = create_hot_update_server(dev_port);
|
const hot_update_server = create_hot_update_server(dev_port);
|
||||||
|
|
||||||
watch_files(`${locations.routes()}/**/*`, ['add', 'unlink'], () => {
|
watch_files(locations.routes(), ['add', 'unlink'], () => {
|
||||||
const routes = create_routes();
|
const routes = create_routes();
|
||||||
create_main_manifests({ routes, dev_port });
|
create_main_manifests({ routes, dev_port });
|
||||||
});
|
});
|
||||||
@@ -311,7 +311,8 @@ function watch_files(pattern: string, events: string[], callback: () => void) {
|
|||||||
|
|
||||||
const watcher = chokidar.watch(pattern, {
|
const watcher = chokidar.watch(pattern, {
|
||||||
persistent: true,
|
persistent: true,
|
||||||
ignoreInitial: true
|
ignoreInitial: true,
|
||||||
|
disableGlobbing: true
|
||||||
});
|
});
|
||||||
|
|
||||||
events.forEach(event => {
|
events.forEach(event => {
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ export async function exporter(export_dir: string, { basepath = '' }) {
|
|||||||
|
|
||||||
const proc = child_process.fork(path.resolve(`${build_dir}/server.js`), [], {
|
const proc = child_process.fork(path.resolve(`${build_dir}/server.js`), [], {
|
||||||
cwd: process.cwd(),
|
cwd: process.cwd(),
|
||||||
env: {
|
env: Object.assign({
|
||||||
PORT: port,
|
PORT: port,
|
||||||
NODE_ENV: 'production',
|
NODE_ENV: 'production',
|
||||||
SAPPER_DEST: build_dir,
|
SAPPER_DEST: build_dir,
|
||||||
SAPPER_EXPORT: 'true'
|
SAPPER_EXPORT: 'true'
|
||||||
}
|
}, process.env)
|
||||||
});
|
});
|
||||||
|
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
@@ -103,4 +103,4 @@ export async function exporter(export_dir: string, { basepath = '' }) {
|
|||||||
return ports.wait(port)
|
return ports.wait(port)
|
||||||
.then(() => handle(new URL(`/${basepath}`, origin))) // TODO all static routes
|
.then(() => handle(new URL(`/${basepath}`, origin))) // TODO all static routes
|
||||||
.then(() => proc.kill());
|
.then(() => proc.kill());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ export async function start(dir: string, opts: { port: number, open: boolean })
|
|||||||
const server = path.resolve(dir, 'server.js');
|
const server = path.resolve(dir, 'server.js');
|
||||||
|
|
||||||
if (!fs.existsSync(server)) {
|
if (!fs.existsSync(server)) {
|
||||||
console.log(clorox.bold.red(`> ${dir}/server.js does not exist — type ${clorox.bold.cyan(dir === 'build' ? `npx sapper build` : `npx sapper build ${dir}`)} to create it`));
|
console.log(`${clorox.bold.red(`> ${dir}/server.js does not exist — type ${clorox.bold.cyan(dir === 'build' ? `npx sapper build` : `npx sapper build ${dir}`)} to create it`)}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port) {
|
if (port) {
|
||||||
if (!await ports.check(port)) {
|
if (!await ports.check(port)) {
|
||||||
console.log(clorox.bold.red(`> Port ${port} is unavailable`));
|
console.log(`${clorox.bold.red(`> Port ${port} is unavailable`)}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import glob from 'glob';
|
|||||||
import { locations } from '../config';
|
import { locations } from '../config';
|
||||||
import { Route } from '../interfaces';
|
import { Route } from '../interfaces';
|
||||||
|
|
||||||
export default function create_routes({ files } = { files: glob.sync('**/*.*', { cwd: locations.routes(), nodir: true }) }) {
|
export default function create_routes({ files } = { files: glob.sync('**/*.*', { cwd: locations.routes(), dot: true, nodir: true }) }) {
|
||||||
const routes: Route[] = files
|
const routes: Route[] = files
|
||||||
.map((file: string) => {
|
.map((file: string) => {
|
||||||
if (/(^|\/|\\)_/.test(file)) return;
|
if (/(^|\/|\\)_/.test(file)) return;
|
||||||
@@ -33,7 +33,7 @@ export default function create_routes({ files } = { files: glob.sync('**/*.*', {
|
|||||||
let i = parts.length;
|
let i = parts.length;
|
||||||
let nested = true;
|
let nested = true;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
const part = encodeURIComponent(parts[i].normalize()).replace(/%5B/g, '[').replace(/%5D/g, ']');
|
const part = encodeURI(parts[i].normalize()).replace(/\?/g, '%3F').replace(/#/g, '%23').replace(/%5B/g, '[').replace(/%5D/g, ']');
|
||||||
const dynamic = ~part.indexOf('[');
|
const dynamic = ~part.indexOf('[');
|
||||||
|
|
||||||
if (dynamic) {
|
if (dynamic) {
|
||||||
@@ -102,7 +102,10 @@ export default function create_routes({ files } = { files: glob.sync('**/*.*', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!a_sub_part.dynamic && a_sub_part.content !== b_sub_part.content) {
|
if (!a_sub_part.dynamic && a_sub_part.content !== b_sub_part.content) {
|
||||||
return b_sub_part.content.length - a_sub_part.content.length;
|
return (
|
||||||
|
(b_sub_part.content.length - a_sub_part.content.length) ||
|
||||||
|
(a_sub_part.content < b_sub_part.content ? -1 : 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ function get_route_handler(chunks: Record<string, string>, routes: RouteObject[]
|
|||||||
error = { statusCode, message };
|
error = { statusCode, message };
|
||||||
},
|
},
|
||||||
fetch: (url: string, opts?: any) => {
|
fetch: (url: string, opts?: any) => {
|
||||||
const parsed = new URL(url, `http://127.0.0.1:${process.env.PORT}${req.baseUrl}${req.path}`);
|
const parsed = new URL(url, `http://127.0.0.1:${process.env.PORT}${req.baseUrl ? req.baseUrl + '/' :''}`);
|
||||||
|
|
||||||
if (opts) {
|
if (opts) {
|
||||||
opts = Object.assign({}, opts);
|
opts = Object.assign({}, opts);
|
||||||
@@ -245,11 +245,11 @@ function get_route_handler(chunks: Record<string, string>, routes: RouteObject[]
|
|||||||
`baseUrl: "${req.baseUrl}"`,
|
`baseUrl: "${req.baseUrl}"`,
|
||||||
serialized.preloaded && `preloaded: ${serialized.preloaded}`,
|
serialized.preloaded && `preloaded: ${serialized.preloaded}`,
|
||||||
serialized.store && `store: ${serialized.store}`
|
serialized.store && `store: ${serialized.store}`
|
||||||
].filter(Boolean).join(',')}}`
|
].filter(Boolean).join(',')}};`;
|
||||||
|
|
||||||
const has_service_worker = fs.existsSync(path.join(locations.dest(), 'service-worker.js'));
|
const has_service_worker = fs.existsSync(path.join(locations.dest(), 'service-worker.js'));
|
||||||
if (has_service_worker) {
|
if (has_service_worker) {
|
||||||
`if ('serviceWorker' in navigator) navigator.serviceWorker.register('${req.baseUrl}/service-worker.js')`
|
inline_script += `if ('serviceWorker' in navigator) navigator.serviceWorker.register('${req.baseUrl}/service-worker.js');`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = template()
|
const page = template()
|
||||||
@@ -356,6 +356,8 @@ function get_route_handler(chunks: Record<string, string>, routes: RouteObject[]
|
|||||||
const rendered = route ? route.module.render({
|
const rendered = route ? route.module.render({
|
||||||
status: statusCode,
|
status: statusCode,
|
||||||
error
|
error
|
||||||
|
}, {
|
||||||
|
store: store_getter && store_getter(req)
|
||||||
}) : { head: '', css: null, html: title };
|
}) : { head: '', css: null, html: title };
|
||||||
|
|
||||||
const { head, css, html } = rendered;
|
const { head, css, html } = rendered;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
preload({ query }) {
|
preload({ query }) {
|
||||||
console.log(`here ${this.fetch}`);
|
|
||||||
return this.fetch(`credentials/test.json`, {
|
return this.fetch(`credentials/test.json`, {
|
||||||
credentials: query.creds
|
credentials: query.creds
|
||||||
}).then(r => r.json());
|
}).then(r => r.json());
|
||||||
|
|||||||
@@ -559,6 +559,12 @@ function run({ mode, basepath = '' }) {
|
|||||||
assert.equal(title, 'woohoo!');
|
assert.equal(title, 'woohoo!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('includes service worker', () => {
|
||||||
|
return nightmare.goto(base).page.html().then(html => {
|
||||||
|
assert.ok(html.indexOf('service-worker.js') !== -1);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('headers', () => {
|
describe('headers', () => {
|
||||||
|
|||||||
@@ -2,6 +2,25 @@ const assert = require('assert');
|
|||||||
const { create_routes } = require('../../dist/core.ts.js');
|
const { create_routes } = require('../../dist/core.ts.js');
|
||||||
|
|
||||||
describe('create_routes', () => {
|
describe('create_routes', () => {
|
||||||
|
it('encodes caharcters not allowed in path', () => {
|
||||||
|
const routes = create_routes({
|
||||||
|
files: [
|
||||||
|
'"',
|
||||||
|
'#',
|
||||||
|
'?'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
routes.map(r => r.pattern),
|
||||||
|
[
|
||||||
|
/^\/%22\/?$/,
|
||||||
|
/^\/%23\/?$/,
|
||||||
|
/^\/%3F\/?$/
|
||||||
|
]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('sorts routes correctly', () => {
|
it('sorts routes correctly', () => {
|
||||||
const routes = create_routes({
|
const routes = create_routes({
|
||||||
files: ['index.html', 'about.html', 'post/f[xx].html', '[wildcard].html', 'post/foo.html', 'post/[id].html', 'post/bar.html', 'post/[id].json.js']
|
files: ['index.html', 'about.html', 'post/f[xx].html', '[wildcard].html', 'post/foo.html', 'post/[id].html', 'post/bar.html', 'post/[id].json.js']
|
||||||
@@ -12,8 +31,8 @@ describe('create_routes', () => {
|
|||||||
[
|
[
|
||||||
'index.html',
|
'index.html',
|
||||||
'about.html',
|
'about.html',
|
||||||
'post/foo.html',
|
|
||||||
'post/bar.html',
|
'post/bar.html',
|
||||||
|
'post/foo.html',
|
||||||
'post/f[xx].html',
|
'post/f[xx].html',
|
||||||
'post/[id].json.js',
|
'post/[id].json.js',
|
||||||
'post/[id].html',
|
'post/[id].html',
|
||||||
@@ -23,7 +42,7 @@ describe('create_routes', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('prefers index page to nested route', () => {
|
it('prefers index page to nested route', () => {
|
||||||
const routes = create_routes({
|
let routes = create_routes({
|
||||||
files: [
|
files: [
|
||||||
'api/examples/[slug].js',
|
'api/examples/[slug].js',
|
||||||
'api/examples/index.js',
|
'api/examples/index.js',
|
||||||
@@ -55,6 +74,45 @@ describe('create_routes', () => {
|
|||||||
'api/gists/[id].js',
|
'api/gists/[id].js',
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
routes = create_routes({
|
||||||
|
files: [
|
||||||
|
'4xx.html',
|
||||||
|
'5xx.html',
|
||||||
|
'api/blog/[slug].js',
|
||||||
|
'api/blog/index.js',
|
||||||
|
'api/guide/contents.js',
|
||||||
|
'api/guide/index.js',
|
||||||
|
'blog/[slug].html',
|
||||||
|
'blog/index.html',
|
||||||
|
'blog/rss.xml.js',
|
||||||
|
'gist/[id].js',
|
||||||
|
'gist/create.js',
|
||||||
|
'guide/index.html',
|
||||||
|
'index.html',
|
||||||
|
'repl/index.html'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
routes.map(r => r.file),
|
||||||
|
[
|
||||||
|
'4xx.html',
|
||||||
|
'5xx.html',
|
||||||
|
'index.html',
|
||||||
|
'guide/index.html',
|
||||||
|
'blog/index.html',
|
||||||
|
'blog/rss.xml.js',
|
||||||
|
'blog/[slug].html',
|
||||||
|
'gist/create.js',
|
||||||
|
'gist/[id].js',
|
||||||
|
'repl/index.html',
|
||||||
|
'api/guide/index.js',
|
||||||
|
'api/guide/contents.js',
|
||||||
|
'api/blog/index.js',
|
||||||
|
'api/blog/[slug].js',
|
||||||
|
]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('generates params', () => {
|
it('generates params', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user