mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-11 19:04:30 +00:00
ignore some files
This commit is contained in:
15
.gitignore
vendored
15
.gitignore
vendored
@@ -1,19 +1,12 @@
|
||||
.DS_Store
|
||||
yarn.lock
|
||||
yarn-error.log
|
||||
node_modules
|
||||
cypress/screenshots
|
||||
test/app/.sapper
|
||||
test/app/app/manifest
|
||||
test/app/export
|
||||
test/app/build
|
||||
runtime.js
|
||||
runtime.js.map
|
||||
cli.js
|
||||
cli.js.map
|
||||
middleware.js
|
||||
middleware.js.map
|
||||
core.js
|
||||
core.js.map
|
||||
webpack/config.js
|
||||
webpack/config.js.map
|
||||
yarn-error.log
|
||||
*.ts.js
|
||||
*.ts.js.map
|
||||
!rollup.config.js
|
||||
504
cli.ts.js
504
cli.ts.js
@@ -1,504 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||
|
||||
var tslib_1 = require('tslib');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var clorox = require('clorox');
|
||||
var mkdirp = _interopDefault(require('mkdirp'));
|
||||
var rimraf = _interopDefault(require('rimraf'));
|
||||
var __core_ts_js = require('./core.ts.js');
|
||||
var __chunk1_js = require('./chunk1.js');
|
||||
var child_process = require('child_process');
|
||||
var sander = require('sander');
|
||||
var polka = _interopDefault(require('polka'));
|
||||
var cheerio = _interopDefault(require('cheerio'));
|
||||
var URL = _interopDefault(require('url-parse'));
|
||||
var fetch = _interopDefault(require('node-fetch'));
|
||||
var ports = require('port-authority');
|
||||
var http = require('http');
|
||||
var format_messages = _interopDefault(require('webpack-format-messages'));
|
||||
var prettyMs = _interopDefault(require('pretty-ms'));
|
||||
var sade = _interopDefault(require('sade'));
|
||||
|
||||
function build() {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var output, routes, _a, client, server, serviceworker, client_stats, server_stats, serviceworker_stats;
|
||||
return tslib_1.__generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
output = __chunk1_js.dest();
|
||||
mkdirp.sync(output);
|
||||
rimraf.sync(path.join(output, '**/*'));
|
||||
routes = __core_ts_js.create_routes();
|
||||
// create app/manifest/client.js and app/manifest/server.js
|
||||
__core_ts_js.create_app({ routes: routes, src: __chunk1_js.src, dev: __chunk1_js.dev });
|
||||
_a = __core_ts_js.create_compilers(), client = _a.client, server = _a.server, serviceworker = _a.serviceworker;
|
||||
return [4 /*yield*/, compile(client)];
|
||||
case 1:
|
||||
client_stats = _b.sent();
|
||||
console.log(clorox.inverse("\nbuilt client"));
|
||||
console.log(client_stats.toString({ colors: true }));
|
||||
fs.writeFileSync(path.join(output, 'client_info.json'), JSON.stringify(client_stats.toJson()));
|
||||
return [4 /*yield*/, compile(server)];
|
||||
case 2:
|
||||
server_stats = _b.sent();
|
||||
console.log(clorox.inverse("\nbuilt server"));
|
||||
console.log(server_stats.toString({ colors: true }));
|
||||
if (!serviceworker) return [3 /*break*/, 4];
|
||||
__core_ts_js.create_serviceworker({
|
||||
routes: routes,
|
||||
client_files: client_stats.toJson().assets.map(function (chunk) { return "/client/" + chunk.name; }),
|
||||
src: __chunk1_js.src
|
||||
});
|
||||
return [4 /*yield*/, compile(serviceworker)];
|
||||
case 3:
|
||||
serviceworker_stats = _b.sent();
|
||||
console.log(clorox.inverse("\nbuilt service worker"));
|
||||
console.log(serviceworker_stats.toString({ colors: true }));
|
||||
_b.label = 4;
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function compile(compiler) {
|
||||
return new Promise(function (fulfil, reject) {
|
||||
compiler.run(function (err, stats) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
process.exit(1);
|
||||
}
|
||||
if (stats.hasErrors()) {
|
||||
console.error(stats.toString({ colors: true }));
|
||||
reject(new Error("Encountered errors while building app"));
|
||||
}
|
||||
else {
|
||||
fulfil(stats);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var app = polka();
|
||||
function exporter(export_dir) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
function handle(url) {
|
||||
if (url.origin !== origin)
|
||||
return;
|
||||
if (seen.has(url.pathname))
|
||||
return;
|
||||
seen.add(url.pathname);
|
||||
return fetch(url.href)
|
||||
.then(function (r) {
|
||||
if (r.headers.get('Content-Type') === 'text/html') {
|
||||
return r.text().then(function (body) {
|
||||
var $ = cheerio.load(body);
|
||||
var hrefs = [];
|
||||
$('a[href]').each(function (i, $a) {
|
||||
hrefs.push($a.attribs.href);
|
||||
});
|
||||
return hrefs.reduce(function (promise, href) {
|
||||
return promise.then(function () { return handle(new URL(href, url.href)); });
|
||||
}, Promise.resolve());
|
||||
});
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
console.error("Error rendering " + url.pathname + ": " + err.message);
|
||||
});
|
||||
}
|
||||
var build_dir, port, origin, proc, seen, saved;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
build_dir = __chunk1_js.dest();
|
||||
// Prep output directory
|
||||
sander.rimrafSync(export_dir);
|
||||
sander.copydirSync('assets').to(export_dir);
|
||||
sander.copydirSync(build_dir, 'client').to(export_dir, 'client');
|
||||
if (sander.existsSync(build_dir, 'service-worker.js')) {
|
||||
sander.copyFileSync(build_dir, 'service-worker.js').to(export_dir, 'service-worker.js');
|
||||
}
|
||||
return [4 /*yield*/, ports.find(3000)];
|
||||
case 1:
|
||||
port = _a.sent();
|
||||
origin = "http://localhost:" + port;
|
||||
proc = child_process.fork(path.resolve(build_dir + "/server.js"), [], {
|
||||
cwd: process.cwd(),
|
||||
env: {
|
||||
PORT: port,
|
||||
NODE_ENV: 'production',
|
||||
SAPPER_DEST: build_dir,
|
||||
SAPPER_EXPORT: 'true'
|
||||
}
|
||||
});
|
||||
seen = new Set();
|
||||
saved = new Set();
|
||||
proc.on('message', function (message) {
|
||||
if (!message.__sapper__)
|
||||
return;
|
||||
var url = new URL(message.url, origin);
|
||||
if (saved.has(url.pathname))
|
||||
return;
|
||||
saved.add(url.pathname);
|
||||
if (message.type === 'text/html') {
|
||||
var file = export_dir + "/" + url.pathname + "/index.html";
|
||||
sander.writeFileSync(file, message.body);
|
||||
}
|
||||
else {
|
||||
var file = export_dir + "/" + url.pathname;
|
||||
sander.writeFileSync(file, message.body);
|
||||
}
|
||||
});
|
||||
return [2 /*return*/, ports.wait(port)
|
||||
.then(function () { return handle(new URL(origin)); }) // TODO all static routes
|
||||
.then(function () { return proc.kill(); })];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deferred() {
|
||||
var d = {};
|
||||
d.promise = new Promise(function (fulfil, reject) {
|
||||
d.fulfil = fulfil;
|
||||
d.reject = reject;
|
||||
});
|
||||
return d;
|
||||
}
|
||||
function create_hot_update_server(port, interval) {
|
||||
if (interval === void 0) { interval = 10000; }
|
||||
var clients = new Set();
|
||||
var server = http.createServer(function (req, res) {
|
||||
if (req.url !== '/__sapper__')
|
||||
return;
|
||||
req.socket.setKeepAlive(true);
|
||||
res.writeHead(200, {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Headers': 'Cache-Control',
|
||||
'Content-Type': 'text/event-stream;charset=utf-8',
|
||||
'Cache-Control': 'no-cache, no-transform',
|
||||
'Connection': 'keep-alive',
|
||||
// While behind nginx, event stream should not be buffered:
|
||||
// http://nginx.org/docs/http/ngx_http_proxy_module.html#proxy_buffering
|
||||
'X-Accel-Buffering': 'no'
|
||||
});
|
||||
res.write('\n');
|
||||
clients.add(res);
|
||||
req.on('close', function () {
|
||||
clients["delete"](res);
|
||||
});
|
||||
});
|
||||
server.listen(port);
|
||||
function send(data) {
|
||||
clients.forEach(function (client) {
|
||||
client.write("data: " + JSON.stringify(data) + "\n\n");
|
||||
});
|
||||
}
|
||||
setInterval(function () {
|
||||
send(null);
|
||||
}, interval);
|
||||
return { send: send };
|
||||
}
|
||||
function dev(port) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
function restart_build(filename) {
|
||||
if (restarting)
|
||||
return;
|
||||
restarting = true;
|
||||
build = {
|
||||
unique_warnings: new Set(),
|
||||
unique_errors: new Set()
|
||||
};
|
||||
process.nextTick(function () {
|
||||
restarting = false;
|
||||
});
|
||||
console.log("\n" + clorox.bold.cyan(path.relative(process.cwd(), filename)) + " changed. rebuilding...");
|
||||
}
|
||||
function watch(compiler, _a) {
|
||||
var name = _a.name, _b = _a.invalid, invalid = _b === void 0 ? noop : _b, _c = _a.error, error = _c === void 0 ? noop : _c, result = _a.result;
|
||||
compiler.hooks.invalid.tap('sapper', function (filename) {
|
||||
invalid(filename);
|
||||
});
|
||||
compiler.watch({}, function (err, stats) {
|
||||
if (err) {
|
||||
console.error(clorox.red("\u2717 " + name));
|
||||
console.error(clorox.red(err.message));
|
||||
error(err);
|
||||
}
|
||||
else {
|
||||
var messages = format_messages(stats);
|
||||
var info = stats.toJson();
|
||||
if (messages.errors.length > 0) {
|
||||
console.log(clorox.bold.red("\u2717 " + name));
|
||||
var filtered = messages.errors.filter(function (message) {
|
||||
return !build.unique_errors.has(message);
|
||||
});
|
||||
filtered.forEach(function (message) {
|
||||
build.unique_errors.add(message);
|
||||
console.log(message);
|
||||
});
|
||||
var hidden = messages.errors.length - filtered.length;
|
||||
if (hidden > 0) {
|
||||
console.log(hidden + " duplicate " + (hidden === 1 ? 'error' : 'errors') + " hidden\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (messages.warnings.length > 0) {
|
||||
console.log(clorox.bold.yellow("\u2022 " + name));
|
||||
var filtered = messages.warnings.filter(function (message) {
|
||||
return !build.unique_warnings.has(message);
|
||||
});
|
||||
filtered.forEach(function (message) {
|
||||
build.unique_warnings.add(message);
|
||||
console.log(message + "\n");
|
||||
});
|
||||
var hidden = messages.warnings.length - filtered.length;
|
||||
if (hidden > 0) {
|
||||
console.log(hidden + " duplicate " + (hidden === 1 ? 'warning' : 'warnings') + " hidden\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log(clorox.bold.green("\u2714 " + name) + " " + clorox.gray("(" + prettyMs(info.time) + ")"));
|
||||
}
|
||||
result(info);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
var dir, dev_port, routes, hot_update_server, proc, deferreds, restarting, build, compilers, watch_serviceworker;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
process.env.NODE_ENV = 'development';
|
||||
dir = __chunk1_js.dest();
|
||||
rimraf.sync(dir);
|
||||
mkdirp.sync(dir);
|
||||
return [4 /*yield*/, ports.find(10000)];
|
||||
case 1:
|
||||
dev_port = _a.sent();
|
||||
routes = __core_ts_js.create_routes();
|
||||
__core_ts_js.create_app({ routes: routes, dev_port: dev_port });
|
||||
hot_update_server = create_hot_update_server(dev_port);
|
||||
watch_files('routes/**/*', ['add', 'unlink'], function () {
|
||||
var routes = __core_ts_js.create_routes();
|
||||
__core_ts_js.create_app({ routes: routes, dev_port: dev_port });
|
||||
});
|
||||
watch_files('app/template.html', ['change'], function () {
|
||||
hot_update_server.send({
|
||||
action: 'reload'
|
||||
});
|
||||
});
|
||||
process.on('exit', function () {
|
||||
// sometimes webpack crashes, so we need to kill our children
|
||||
if (proc)
|
||||
proc.kill();
|
||||
});
|
||||
deferreds = {
|
||||
server: deferred(),
|
||||
client: deferred()
|
||||
};
|
||||
restarting = false;
|
||||
build = {
|
||||
unique_warnings: new Set(),
|
||||
unique_errors: new Set()
|
||||
};
|
||||
compilers = __core_ts_js.create_compilers();
|
||||
watch(compilers.server, {
|
||||
name: 'server',
|
||||
invalid: function (filename) {
|
||||
restart_build(filename);
|
||||
// TODO print message
|
||||
deferreds.server = deferred();
|
||||
},
|
||||
result: function (info) {
|
||||
// TODO log compile errors/warnings
|
||||
fs.writeFileSync(path.join(dir, 'server_info.json'), JSON.stringify(info, null, ' '));
|
||||
deferreds.client.promise.then(function () {
|
||||
function restart() {
|
||||
ports.wait(port).then(deferreds.server.fulfil);
|
||||
}
|
||||
if (proc) {
|
||||
proc.kill();
|
||||
proc.on('exit', restart);
|
||||
}
|
||||
else {
|
||||
restart();
|
||||
}
|
||||
proc = child_process.fork(dir + "/server.js", [], {
|
||||
cwd: process.cwd(),
|
||||
env: Object.assign({
|
||||
PORT: port
|
||||
}, process.env)
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
watch(compilers.client, {
|
||||
name: 'client',
|
||||
invalid: function (filename) {
|
||||
restart_build(filename);
|
||||
deferreds.client = deferred();
|
||||
// TODO we should delete old assets. due to a webpack bug
|
||||
// i don't even begin to comprehend, this is apparently
|
||||
// quite difficult
|
||||
},
|
||||
result: function (info) {
|
||||
fs.writeFileSync(path.join(dir, 'client_info.json'), JSON.stringify(info, null, ' '));
|
||||
deferreds.client.fulfil();
|
||||
var client_files = info.assets.map(function (chunk) { return "/client/" + chunk.name; });
|
||||
deferreds.server.promise.then(function () {
|
||||
hot_update_server.send({
|
||||
status: 'completed'
|
||||
});
|
||||
});
|
||||
__core_ts_js.create_serviceworker({
|
||||
routes: __core_ts_js.create_routes(),
|
||||
client_files: client_files
|
||||
});
|
||||
watch_serviceworker();
|
||||
}
|
||||
});
|
||||
watch_serviceworker = compilers.serviceworker
|
||||
? function () {
|
||||
watch_serviceworker = noop;
|
||||
watch(compilers.serviceworker, {
|
||||
name: 'service worker',
|
||||
result: function (info) {
|
||||
fs.writeFileSync(path.join(dir, 'serviceworker_info.json'), JSON.stringify(info, null, ' '));
|
||||
}
|
||||
});
|
||||
}
|
||||
: noop;
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function noop() { }
|
||||
function watch_files(pattern, events, callback) {
|
||||
var chokidar = require('chokidar');
|
||||
var watcher = chokidar.watch(pattern, {
|
||||
persistent: true,
|
||||
ignoreInitial: true
|
||||
});
|
||||
events.forEach(function (event) {
|
||||
watcher.on(event, callback);
|
||||
});
|
||||
}
|
||||
|
||||
var version = "0.8.4";
|
||||
|
||||
var _this = undefined;
|
||||
var prog = sade('sapper').version(version);
|
||||
prog.command('dev')
|
||||
.describe('Start a development server')
|
||||
.option('-p, --port', 'Specify a port')
|
||||
.action(function (opts) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
||||
var port;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
port = opts.port || +process.env.PORT;
|
||||
if (!port) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, ports.check(port)];
|
||||
case 1:
|
||||
if (!(_a.sent())) {
|
||||
console.log(clorox.bold.red("> Port " + port + " is unavailable"));
|
||||
return [2 /*return*/];
|
||||
}
|
||||
return [3 /*break*/, 4];
|
||||
case 2: return [4 /*yield*/, ports.find(3000)];
|
||||
case 3:
|
||||
port = _a.sent();
|
||||
_a.label = 4;
|
||||
case 4:
|
||||
dev(port);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
prog.command('build [dest]')
|
||||
.describe('Create a production-ready version of your app')
|
||||
.action(function (dest) {
|
||||
if (dest === void 0) { dest = 'build'; }
|
||||
console.log("> Building...");
|
||||
process.env.NODE_ENV = 'production';
|
||||
process.env.SAPPER_DEST = dest;
|
||||
var start = Date.now();
|
||||
build()
|
||||
.then(function () {
|
||||
var elapsed = Date.now() - start;
|
||||
console.error("\n> Finished in " + prettyMs(elapsed) + ". Type " + clorox.bold.cyan(dest === 'build' ? 'npx sapper start' : "npx sapper start " + dest) + " to run the app.");
|
||||
})["catch"](function (err) {
|
||||
console.error(err ? err.details || err.stack || err.message || err : 'Unknown error');
|
||||
});
|
||||
});
|
||||
prog.command('start [dir]')
|
||||
.describe('Start your app')
|
||||
.option('-p, --port', 'Specify a port')
|
||||
.action(function (dir, opts) {
|
||||
if (dir === void 0) { dir = 'build'; }
|
||||
return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
||||
var port, resolved, server;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
port = opts.port || +process.env.PORT;
|
||||
resolved = path.resolve(dir);
|
||||
server = path.resolve(dir, 'server.js');
|
||||
if (!fs.existsSync(server)) {
|
||||
console.log(clorox.bold.red("> " + dir + "/server.js does not exist \u2014 type " + clorox.bold.cyan(dir === 'build' ? "npx sapper build" : "npx sapper build " + dir) + " to create it"));
|
||||
return [2 /*return*/];
|
||||
}
|
||||
if (!port) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, ports.check(port)];
|
||||
case 1:
|
||||
if (!(_a.sent())) {
|
||||
console.log(clorox.bold.red("> Port " + port + " is unavailable"));
|
||||
return [2 /*return*/];
|
||||
}
|
||||
return [3 /*break*/, 4];
|
||||
case 2: return [4 /*yield*/, ports.find(3000)];
|
||||
case 3:
|
||||
port = _a.sent();
|
||||
_a.label = 4;
|
||||
case 4:
|
||||
child_process.fork(server, [], {
|
||||
cwd: process.cwd(),
|
||||
env: Object.assign({
|
||||
NODE_ENV: 'production',
|
||||
PORT: port,
|
||||
SAPPER_DEST: dir
|
||||
}, process.env)
|
||||
});
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
prog.command('export [dest]')
|
||||
.describe('Export your app as static files (if possible)')
|
||||
.action(function (dest) {
|
||||
if (dest === void 0) { dest = 'export'; }
|
||||
console.log("> Building...");
|
||||
process.env.NODE_ENV = 'production';
|
||||
process.env.SAPPER_DEST = '.sapper/.export';
|
||||
var start = Date.now();
|
||||
build()
|
||||
.then(function () {
|
||||
var elapsed = Date.now() - start;
|
||||
console.error("\n> Built in " + prettyMs(elapsed) + ". Exporting...");
|
||||
})
|
||||
.then(function () { return exporter(dest); })
|
||||
.then(function () {
|
||||
var elapsed = Date.now() - start;
|
||||
console.error("\n> Finished in " + prettyMs(elapsed) + ". Type " + clorox.bold.cyan("npx serve " + dest) + " to run the app.");
|
||||
})["catch"](function (err) {
|
||||
console.error(err ? err.details || err.stack || err.message || err : 'Unknown error');
|
||||
});
|
||||
});
|
||||
// TODO upgrade
|
||||
prog.parse(process.argv);
|
||||
//# sourceMappingURL=./cli.ts.js.map
|
||||
229
core.ts.js
229
core.ts.js
@@ -1,229 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||
|
||||
var fs = require('fs');
|
||||
var __chunk1_js = require('./chunk1.js');
|
||||
var path = require('path');
|
||||
var mkdirp = _interopDefault(require('mkdirp'));
|
||||
var glob = _interopDefault(require('glob'));
|
||||
var relative = _interopDefault(require('require-relative'));
|
||||
|
||||
function write(file, code) {
|
||||
fs.writeFileSync(file, code);
|
||||
fudge_mtime(file);
|
||||
}
|
||||
function posixify(file) {
|
||||
return file.replace(/[/\\]/g, '/');
|
||||
}
|
||||
function fudge_mtime(file) {
|
||||
// need to fudge the mtime so that webpack doesn't go doolally
|
||||
var _a = fs.statSync(file), atime = _a.atime, mtime = _a.mtime;
|
||||
fs.utimesSync(file, new Date(atime.getTime() - 999999), new Date(mtime.getTime() - 999999));
|
||||
}
|
||||
|
||||
// in dev mode, we avoid touching the fs unnecessarily
|
||||
var last_client_manifest = null;
|
||||
var last_server_manifest = null;
|
||||
function create_app(_a) {
|
||||
var routes = _a.routes, dev_port = _a.dev_port;
|
||||
mkdirp.sync('app/manifest');
|
||||
var client_manifest = generate_client(routes, dev_port);
|
||||
var server_manifest = generate_server(routes);
|
||||
if (client_manifest !== last_client_manifest) {
|
||||
write("app/manifest/client.js", client_manifest);
|
||||
last_client_manifest = client_manifest;
|
||||
}
|
||||
if (server_manifest !== last_server_manifest) {
|
||||
write("app/manifest/server.js", server_manifest);
|
||||
last_server_manifest = server_manifest;
|
||||
}
|
||||
}
|
||||
function generate_client(routes, dev_port) {
|
||||
var code = ("\n\t\t// This file is generated by Sapper \u2014 do not edit it!\n\t\texport const routes = [\n\t\t\t" + routes
|
||||
.map(function (route) {
|
||||
if (route.type !== 'page') {
|
||||
return "{ pattern: " + route.pattern + ", ignore: true }";
|
||||
}
|
||||
var file = posixify("../../routes/" + route.file);
|
||||
if (route.id === '_4xx' || route.id === '_5xx') {
|
||||
return "{ error: '" + route.id.slice(1) + "', load: () => import(/* webpackChunkName: \"" + route.id + "\" */ '" + file + "') }";
|
||||
}
|
||||
var params = route.params.length === 0
|
||||
? '{}'
|
||||
: "{ " + route.params.map(function (part, i) { return part + ": match[" + (i + 1) + "]"; }).join(', ') + " }";
|
||||
return "{ pattern: " + route.pattern + ", params: " + (route.params.length > 0 ? "match" : "()") + " => (" + params + "), load: () => import(/* webpackChunkName: \"" + route.id + "\" */ '" + file + "') }";
|
||||
})
|
||||
.join(',\n\t') + "\n\t\t];").replace(/^\t\t/gm, '').trim();
|
||||
if (__chunk1_js.dev()) {
|
||||
var sapper_dev_client = posixify(path.resolve(__dirname, 'sapper-dev-client.js'));
|
||||
code += ("\n\n\t\t\tif (module.hot) {\n\t\t\t\timport('" + sapper_dev_client + "').then(client => {\n\t\t\t\t\tclient.connect(" + dev_port + ");\n\t\t\t\t});\n\t\t\t}").replace(/^\t{3}/gm, '');
|
||||
}
|
||||
return code;
|
||||
}
|
||||
function generate_server(routes) {
|
||||
var code = ("\n\t\t// This file is generated by Sapper \u2014 do not edit it!\n\t\t" + routes
|
||||
.map(function (route) {
|
||||
var file = posixify("../../routes/" + route.file);
|
||||
return route.type === 'page'
|
||||
? "import " + route.id + " from '" + file + "';"
|
||||
: "import * as " + route.id + " from '" + file + "';";
|
||||
})
|
||||
.join('\n') + "\n\n\t\texport const routes = [\n\t\t\t" + routes
|
||||
.map(function (route) {
|
||||
var file = posixify("../../" + route.file);
|
||||
if (route.id === '_4xx' || route.id === '_5xx') {
|
||||
return "{ error: '" + route.id.slice(1) + "', module: " + route.id + " }";
|
||||
}
|
||||
var params = route.params.length === 0
|
||||
? '{}'
|
||||
: "{ " + route.params.map(function (part, i) { return part + ": match[" + (i + 1) + "]"; }).join(', ') + " }";
|
||||
return "{ id: '" + route.id + "', type: '" + route.type + "', pattern: " + route.pattern + ", params: " + (route.params.length > 0 ? "match" : "()") + " => (" + params + "), module: " + route.id + " }";
|
||||
})
|
||||
.join(',\n\t') + "\n\t\t];").replace(/^\t\t/gm, '').trim();
|
||||
return code;
|
||||
}
|
||||
|
||||
function create_serviceworker(_a) {
|
||||
var routes = _a.routes, client_files = _a.client_files;
|
||||
var assets = glob.sync('**', { cwd: 'assets', nodir: true });
|
||||
var code = ("\n\t\t// This file is generated by Sapper \u2014 do not edit it!\n\t\texport const timestamp = " + Date.now() + ";\n\n\t\texport const assets = [\n\t" + assets.map(function (x) { return "\"" + x + "\""; }).join(',\n\t') + "\n];\n\n\t\texport const shell = [\n\t" + client_files.map(function (x) { return "\"" + x + "\""; }).join(',\n\t') + "\n];\n\n\t\texport const routes = [\n\t" + routes.filter(function (r) { return r.type === 'page' && !/^_[45]xx$/.test(r.id); }).map(function (r) { return "{ pattern: " + r.pattern + " }"; }).join(',\n\t') + "\n];\n\t").replace(/^\t\t/gm, '').trim();
|
||||
write('app/manifest/service-worker.js', code);
|
||||
}
|
||||
|
||||
function create_compilers() {
|
||||
var webpack = relative('webpack', process.cwd());
|
||||
var serviceworker_config = try_require(path.resolve('webpack/service-worker.config.js'));
|
||||
return {
|
||||
client: webpack(require(path.resolve('webpack/client.config.js'))),
|
||||
server: webpack(require(path.resolve('webpack/server.config.js'))),
|
||||
serviceworker: serviceworker_config && webpack(serviceworker_config)
|
||||
};
|
||||
}
|
||||
function try_require(specifier) {
|
||||
try {
|
||||
return require(specifier);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'MODULE_NOT_FOUND')
|
||||
return null;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function create_routes(_a) {
|
||||
var files = (_a === void 0 ? { files: glob.sync('**/*.*', { cwd: __chunk1_js.src(), nodir: true }) } : _a).files;
|
||||
var routes = files
|
||||
.map(function (file) {
|
||||
if (/(^|\/|\\)_/.test(file))
|
||||
return;
|
||||
if (/]\[/.test(file)) {
|
||||
throw new Error("Invalid route " + file + " \u2014 parameters must be separated");
|
||||
}
|
||||
var base = file.replace(/\.[^/.]+$/, '');
|
||||
var parts = base.split('/'); // glob output is always posix-style
|
||||
if (parts[parts.length - 1] === 'index')
|
||||
parts.pop();
|
||||
var id = (parts.join('_').replace(/[[\]]/g, '$').replace(/^\d/, '_$&').replace(/[^a-zA-Z0-9_$]/g, '_')) || '_';
|
||||
var params = [];
|
||||
var param_pattern = /\[([^\]]+)\]/g;
|
||||
var match;
|
||||
while (match = param_pattern.exec(base)) {
|
||||
params.push(match[1]);
|
||||
}
|
||||
// TODO can we do all this with sub-parts? or does
|
||||
// nesting make that impossible?
|
||||
var pattern_string = '';
|
||||
var i = parts.length;
|
||||
var nested = true;
|
||||
while (i--) {
|
||||
var part = encodeURIComponent(parts[i].normalize()).replace(/%5B/g, '[').replace(/%5D/g, ']');
|
||||
var dynamic = ~part.indexOf('[');
|
||||
if (dynamic) {
|
||||
var matcher = part.replace(param_pattern, "([^/]+?)");
|
||||
pattern_string = nested ? "(?:\\/" + matcher + pattern_string + ")?" : "\\/" + matcher + pattern_string;
|
||||
}
|
||||
else {
|
||||
nested = false;
|
||||
pattern_string = "\\/" + part + pattern_string;
|
||||
}
|
||||
}
|
||||
var pattern = new RegExp("^" + pattern_string + "\\/?$");
|
||||
var test = function (url) { return pattern.test(url); };
|
||||
var exec = function (url) {
|
||||
var match = pattern.exec(url);
|
||||
if (!match)
|
||||
return;
|
||||
var result = {};
|
||||
params.forEach(function (param, i) {
|
||||
result[param] = match[i + 1];
|
||||
});
|
||||
return result;
|
||||
};
|
||||
return {
|
||||
id: id,
|
||||
type: path.extname(file) === '.html' ? 'page' : 'route',
|
||||
file: file,
|
||||
pattern: pattern,
|
||||
test: test,
|
||||
exec: exec,
|
||||
parts: parts,
|
||||
params: params
|
||||
};
|
||||
})
|
||||
.filter(Boolean)
|
||||
.sort(function (a, b) {
|
||||
if (a.file === '4xx.html' || a.file === '5xx.html')
|
||||
return -1;
|
||||
if (b.file === '4xx.html' || b.file === '5xx.html')
|
||||
return 1;
|
||||
var max = Math.max(a.parts.length, b.parts.length);
|
||||
for (var i = 0; i < max; i += 1) {
|
||||
var a_part = a.parts[i];
|
||||
var b_part = b.parts[i];
|
||||
if (!a_part)
|
||||
return -1;
|
||||
if (!b_part)
|
||||
return 1;
|
||||
var a_sub_parts = get_sub_parts(a_part);
|
||||
var b_sub_parts = get_sub_parts(b_part);
|
||||
var max_1 = Math.max(a_sub_parts.length, b_sub_parts.length);
|
||||
for (var i_1 = 0; i_1 < max_1; i_1 += 1) {
|
||||
var a_sub_part = a_sub_parts[i_1];
|
||||
var b_sub_part = b_sub_parts[i_1];
|
||||
if (!a_sub_part)
|
||||
return 1; // b is more specific, so goes first
|
||||
if (!b_sub_part)
|
||||
return -1;
|
||||
if (a_sub_part.dynamic !== b_sub_part.dynamic) {
|
||||
return a_sub_part.dynamic ? 1 : -1;
|
||||
}
|
||||
if (!a_sub_part.dynamic && a_sub_part.content !== b_sub_part.content) {
|
||||
return b_sub_part.content.length - a_sub_part.content.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error("The " + a.file + " and " + b.file + " routes clash");
|
||||
});
|
||||
return routes;
|
||||
}
|
||||
function get_sub_parts(part) {
|
||||
return part.split(/[\[\]]/)
|
||||
.map(function (content, i) {
|
||||
if (!content)
|
||||
return null;
|
||||
return {
|
||||
content: content,
|
||||
dynamic: i % 2 === 1
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
exports.create_app = create_app;
|
||||
exports.create_serviceworker = create_serviceworker;
|
||||
exports.create_compilers = create_compilers;
|
||||
exports.create_routes = create_routes;
|
||||
//# sourceMappingURL=./core.ts.js.map
|
||||
2
middleware.js
Normal file
2
middleware.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// TODO write to this file, instead of middleware.ts.js
|
||||
module.exports = require('./middleware.ts.js');
|
||||
274
middleware.ts.js
274
middleware.ts.js
File diff suppressed because one or more lines are too long
271
runtime.js
Normal file
271
runtime.js
Normal file
@@ -0,0 +1,271 @@
|
||||
function detach(node) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
function findAnchor(node) {
|
||||
while (node && node.nodeName.toUpperCase() !== 'A')
|
||||
node = node.parentNode; // SVG <a> elements have a lowercase name
|
||||
return node;
|
||||
}
|
||||
function which(event) {
|
||||
return event.which === null ? event.button : event.which;
|
||||
}
|
||||
function scroll_state() {
|
||||
return {
|
||||
x: window.scrollX,
|
||||
y: window.scrollY
|
||||
};
|
||||
}
|
||||
|
||||
var component;
|
||||
var target;
|
||||
var routes;
|
||||
var errors;
|
||||
var history = typeof window !== 'undefined' ? window.history : {
|
||||
pushState: function (state, title, href) { },
|
||||
replaceState: function (state, title, href) { },
|
||||
scrollRestoration: ''
|
||||
};
|
||||
var scroll_history = {};
|
||||
var uid = 1;
|
||||
var cid;
|
||||
if ('scrollRestoration' in history) {
|
||||
history.scrollRestoration = 'manual';
|
||||
}
|
||||
function select_route(url) {
|
||||
if (url.origin !== window.location.origin)
|
||||
return null;
|
||||
var _loop_1 = function (route) {
|
||||
var match = route.pattern.exec(url.pathname);
|
||||
if (match) {
|
||||
if (route.ignore)
|
||||
return { value: null };
|
||||
var params = route.params(match);
|
||||
var query_1 = {};
|
||||
if (url.search.length > 0) {
|
||||
url.search.slice(1).split('&').forEach(function (searchParam) {
|
||||
var _a = /([^=]+)=(.*)/.exec(searchParam), key = _a[1], value = _a[2];
|
||||
query_1[key] = value || true;
|
||||
});
|
||||
}
|
||||
return { value: { url: url, route: route, data: { params: params, query: query_1 } } };
|
||||
}
|
||||
};
|
||||
for (var _i = 0, routes_1 = routes; _i < routes_1.length; _i++) {
|
||||
var route = routes_1[_i];
|
||||
var state_1 = _loop_1(route);
|
||||
if (typeof state_1 === "object")
|
||||
return state_1.value;
|
||||
}
|
||||
}
|
||||
var current_token;
|
||||
function render(Component, data, scroll, token) {
|
||||
if (current_token !== token)
|
||||
return;
|
||||
if (component) {
|
||||
component.destroy();
|
||||
}
|
||||
else {
|
||||
// first load — remove SSR'd <head> contents
|
||||
var start = document.querySelector('#sapper-head-start');
|
||||
var end = document.querySelector('#sapper-head-end');
|
||||
if (start && end) {
|
||||
while (start.nextSibling !== end)
|
||||
detach(start.nextSibling);
|
||||
detach(start);
|
||||
detach(end);
|
||||
}
|
||||
}
|
||||
component = new Component({
|
||||
target: target,
|
||||
data: data,
|
||||
hydrate: !component
|
||||
});
|
||||
if (scroll) {
|
||||
window.scrollTo(scroll.x, scroll.y);
|
||||
}
|
||||
}
|
||||
function prepare_route(Component, data) {
|
||||
var redirect = null;
|
||||
var error = null;
|
||||
if (!Component.preload) {
|
||||
return { Component: Component, data: data, redirect: redirect, error: error };
|
||||
}
|
||||
if (!component && window.__SAPPER__ && window.__SAPPER__.preloaded) {
|
||||
return { Component: Component, data: Object.assign(data, window.__SAPPER__.preloaded), redirect: redirect, error: error };
|
||||
}
|
||||
return Promise.resolve(Component.preload.call({
|
||||
redirect: function (statusCode, location) {
|
||||
redirect = { statusCode: statusCode, location: location };
|
||||
},
|
||||
error: function (statusCode, message) {
|
||||
error = { statusCode: statusCode, message: message };
|
||||
}
|
||||
}, data))["catch"](function (err) {
|
||||
error = { statusCode: 500, message: err };
|
||||
}).then(function (preloaded) {
|
||||
if (error) {
|
||||
var route = error.statusCode >= 400 && error.statusCode < 500
|
||||
? errors['4xx']
|
||||
: errors['5xx'];
|
||||
return route.load().then(function (_a) {
|
||||
var Component = _a["default"];
|
||||
var err = error.message instanceof Error ? error.message : new Error(error.message);
|
||||
Object.assign(data, { status: error.statusCode, error: err });
|
||||
return { Component: Component, data: data, redirect: null };
|
||||
});
|
||||
}
|
||||
Object.assign(data, preloaded);
|
||||
return { Component: Component, data: data, redirect: redirect };
|
||||
});
|
||||
}
|
||||
function navigate(target, id) {
|
||||
if (id) {
|
||||
// popstate or initial navigation
|
||||
cid = id;
|
||||
}
|
||||
else {
|
||||
// clicked on a link. preserve scroll state
|
||||
scroll_history[cid] = scroll_state();
|
||||
id = cid = ++uid;
|
||||
scroll_history[cid] = { x: 0, y: 0 };
|
||||
}
|
||||
cid = id;
|
||||
var loaded = prefetching && prefetching.href === target.url.href ?
|
||||
prefetching.promise :
|
||||
target.route.load().then(function (mod) { return prepare_route(mod["default"], target.data); });
|
||||
prefetching = null;
|
||||
var token = current_token = {};
|
||||
return loaded.then(function (_a) {
|
||||
var Component = _a.Component, data = _a.data, redirect = _a.redirect;
|
||||
if (redirect) {
|
||||
return goto(redirect.location, { replaceState: true });
|
||||
}
|
||||
render(Component, data, scroll_history[id], token);
|
||||
});
|
||||
}
|
||||
function handle_click(event) {
|
||||
// Adapted from https://github.com/visionmedia/page.js
|
||||
// MIT license https://github.com/visionmedia/page.js#license
|
||||
if (which(event) !== 1)
|
||||
return;
|
||||
if (event.metaKey || event.ctrlKey || event.shiftKey)
|
||||
return;
|
||||
if (event.defaultPrevented)
|
||||
return;
|
||||
var a = findAnchor(event.target);
|
||||
if (!a)
|
||||
return;
|
||||
// check if link is inside an svg
|
||||
// in this case, both href and target are always inside an object
|
||||
var svg = typeof a.href === 'object' && a.href.constructor.name === 'SVGAnimatedString';
|
||||
var href = String(svg ? a.href.baseVal : a.href);
|
||||
if (href === window.location.href) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
// Ignore if tag has
|
||||
// 1. 'download' attribute
|
||||
// 2. rel='external' attribute
|
||||
if (a.hasAttribute('download') || a.getAttribute('rel') === 'external')
|
||||
return;
|
||||
// Ignore if <a> has a target
|
||||
if (svg ? a.target.baseVal : a.target)
|
||||
return;
|
||||
var url = new URL(href);
|
||||
// Don't handle hash changes
|
||||
if (url.pathname === window.location.pathname && url.search === window.location.search)
|
||||
return;
|
||||
var target = select_route(url);
|
||||
if (target) {
|
||||
navigate(target, null);
|
||||
event.preventDefault();
|
||||
history.pushState({ id: cid }, '', url.href);
|
||||
}
|
||||
}
|
||||
function handle_popstate(event) {
|
||||
scroll_history[cid] = scroll_state();
|
||||
if (event.state) {
|
||||
var url = new URL(window.location.href);
|
||||
var target_1 = select_route(url);
|
||||
navigate(target_1, event.state.id);
|
||||
}
|
||||
else {
|
||||
// hashchange
|
||||
cid = ++uid;
|
||||
history.replaceState({ id: cid }, '', window.location.href);
|
||||
}
|
||||
}
|
||||
var prefetching = null;
|
||||
function prefetch(href) {
|
||||
var selected = select_route(new URL(href));
|
||||
if (selected) {
|
||||
prefetching = {
|
||||
href: href,
|
||||
promise: selected.route.load().then(function (mod) { return prepare_route(mod["default"], selected.data); })
|
||||
};
|
||||
}
|
||||
}
|
||||
function handle_touchstart_mouseover(event) {
|
||||
var a = findAnchor(event.target);
|
||||
if (!a || a.rel !== 'prefetch')
|
||||
return;
|
||||
prefetch(a.href);
|
||||
}
|
||||
var inited;
|
||||
function init(_target, _routes) {
|
||||
target = _target;
|
||||
routes = _routes.filter(function (r) { return !r.error; });
|
||||
errors = {
|
||||
'4xx': _routes.find(function (r) { return r.error === '4xx'; }),
|
||||
'5xx': _routes.find(function (r) { return r.error === '5xx'; })
|
||||
};
|
||||
if (!inited) {
|
||||
window.addEventListener('click', handle_click);
|
||||
window.addEventListener('popstate', handle_popstate);
|
||||
// prefetch
|
||||
window.addEventListener('touchstart', handle_touchstart_mouseover);
|
||||
window.addEventListener('mouseover', handle_touchstart_mouseover);
|
||||
inited = true;
|
||||
}
|
||||
return Promise.resolve().then(function () {
|
||||
var _a = window.location, hash = _a.hash, href = _a.href;
|
||||
var deep_linked = hash && document.getElementById(hash.slice(1));
|
||||
scroll_history[uid] = deep_linked ?
|
||||
{ x: 0, y: deep_linked.getBoundingClientRect().top } :
|
||||
scroll_state();
|
||||
history.replaceState({ id: uid }, '', href);
|
||||
var target = select_route(new URL(window.location.href));
|
||||
return navigate(target, uid);
|
||||
});
|
||||
}
|
||||
function goto(href, opts) {
|
||||
if (opts === void 0) { opts = { replaceState: false }; }
|
||||
var target = select_route(new URL(href, window.location.href));
|
||||
if (target) {
|
||||
navigate(target, null);
|
||||
if (history)
|
||||
history[opts.replaceState ? 'replaceState' : 'pushState']({ id: cid }, '', href);
|
||||
}
|
||||
else {
|
||||
window.location.href = href;
|
||||
}
|
||||
}
|
||||
function prefetchRoutes(pathnames) {
|
||||
if (!routes)
|
||||
throw new Error("You must call init() first");
|
||||
return routes
|
||||
.filter(function (route) {
|
||||
if (!pathnames)
|
||||
return true;
|
||||
return pathnames.some(function (pathname) {
|
||||
return route.error
|
||||
? route.error === pathname
|
||||
: route.pattern.test(pathname);
|
||||
});
|
||||
})
|
||||
.reduce(function (promise, route) {
|
||||
return promise.then(route.load);
|
||||
}, Promise.resolve());
|
||||
}
|
||||
|
||||
export { component, prefetch, init, goto, prefetchRoutes, prefetchRoutes as preloadRoutes };
|
||||
@@ -1,54 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var __chunk1_js = require('./chunk1.js');
|
||||
|
||||
var webpack = {
|
||||
dev: __chunk1_js.dev(),
|
||||
client: {
|
||||
entry: function () {
|
||||
return {
|
||||
main: './app/client'
|
||||
};
|
||||
},
|
||||
output: function () {
|
||||
return {
|
||||
path: __chunk1_js.dest() + "/client",
|
||||
filename: '[hash]/[name].js',
|
||||
chunkFilename: '[hash]/[name].[id].js',
|
||||
publicPath: '/client/'
|
||||
};
|
||||
}
|
||||
},
|
||||
server: {
|
||||
entry: function () {
|
||||
return {
|
||||
server: './app/server'
|
||||
};
|
||||
},
|
||||
output: function () {
|
||||
return {
|
||||
path: __chunk1_js.dest(),
|
||||
filename: '[name].js',
|
||||
chunkFilename: '[hash]/[name].[id].js',
|
||||
libraryTarget: 'commonjs2'
|
||||
};
|
||||
}
|
||||
},
|
||||
serviceworker: {
|
||||
entry: function () {
|
||||
return {
|
||||
'service-worker': './app/service-worker'
|
||||
};
|
||||
},
|
||||
output: function () {
|
||||
return {
|
||||
path: __chunk1_js.dest(),
|
||||
filename: '[name].js',
|
||||
chunkFilename: '[name].[id].[hash].js'
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = webpack;
|
||||
//# sourceMappingURL=./webpack.ts.js.map
|
||||
2
webpack/config.js
Normal file
2
webpack/config.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// TODO deprecate this file in favour of sapper/webpack.js
|
||||
module.exports = require('../webpack.ts.js');
|
||||
Reference in New Issue
Block a user