mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-12 11:15:14 +00:00
use code-splitting etc
This commit is contained in:
12
chunk1.js
Normal file
12
chunk1.js
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
|
||||
var dev = function () { return process.env.NODE_ENV !== 'production'; };
|
||||
var src = function () { return path.resolve(process.env.SAPPER_ROUTES || 'routes'); };
|
||||
var dest = function () { return path.resolve(process.env.SAPPER_DEST || '.sapper'); };
|
||||
|
||||
exports.dev = dev;
|
||||
exports.src = src;
|
||||
exports.dest = dest;
|
||||
//# sourceMappingURL=./chunk1.js.map
|
||||
1
chunk1.js.map
Normal file
1
chunk1.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"chunk1.js","sources":["src/config.ts"],"sourcesContent":["import * as path from 'path';\n\nexport const dev = () => process.env.NODE_ENV !== 'production';\nexport const src = () => path.resolve(process.env.SAPPER_ROUTES || 'routes');\nexport const dest = () => path.resolve(process.env.SAPPER_DEST || '.sapper');\n"],"names":["path.resolve"],"mappings":";;;;IAEa,GAAG,GAAG,cAAM,OAAA,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,GAAA,CAAC;AAC/D,IAAa,GAAG,GAAG,cAAM,OAAAA,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,QAAQ,CAAC,GAAA,CAAC;AAC7E,IAAa,IAAI,GAAG,cAAM,OAAAA,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,SAAS,CAAC,GAAA;;;;;;"}
|
||||
504
cli.ts.js
Normal file
504
cli.ts.js
Normal file
@@ -0,0 +1,504 @@
|
||||
'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
|
||||
1
cli.ts.js.map
Normal file
1
cli.ts.js.map
Normal file
File diff suppressed because one or more lines are too long
229
core.ts.js
Normal file
229
core.ts.js
Normal file
@@ -0,0 +1,229 @@
|
||||
'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
|
||||
1
core.ts.js.map
Normal file
1
core.ts.js.map
Normal file
File diff suppressed because one or more lines are too long
274
middleware.ts.js
Normal file
274
middleware.ts.js
Normal file
File diff suppressed because one or more lines are too long
1
middleware.ts.js.map
Normal file
1
middleware.ts.js.map
Normal file
File diff suppressed because one or more lines are too long
11
package.json
11
package.json
@@ -4,15 +4,12 @@
|
||||
"description": "Military-grade apps, engineered by Svelte",
|
||||
"main": "middleware.js",
|
||||
"bin": {
|
||||
"sapper": "cli.js"
|
||||
"sapper": "sapper"
|
||||
},
|
||||
"files": [
|
||||
"cli.js",
|
||||
"core.js",
|
||||
"middleware.js",
|
||||
"*.js",
|
||||
"*.ts.js",
|
||||
"runtime",
|
||||
"runtime.js",
|
||||
"sapper-dev-client.js",
|
||||
"webpack"
|
||||
],
|
||||
"directories": {
|
||||
@@ -51,7 +48,7 @@
|
||||
"mocha": "^4.0.1",
|
||||
"nightmare": "^2.10.0",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"rollup": "^0.53.0",
|
||||
"rollup": "^0.56.5",
|
||||
"rollup-plugin-commonjs": "^8.3.0",
|
||||
"rollup-plugin-json": "^2.3.0",
|
||||
"rollup-plugin-string": "^2.0.2",
|
||||
|
||||
@@ -10,36 +10,39 @@ const external = [].concat(
|
||||
'sapper/core.js'
|
||||
);
|
||||
|
||||
const paths = {
|
||||
'sapper/core.js': './core.js'
|
||||
};
|
||||
|
||||
const plugins = [
|
||||
string({
|
||||
include: '**/*.md'
|
||||
}),
|
||||
json(),
|
||||
commonjs(),
|
||||
typescript({
|
||||
typescript: require('typescript')
|
||||
})
|
||||
];
|
||||
|
||||
export default [
|
||||
{ name: 'cli', banner: true },
|
||||
{ name: 'core' },
|
||||
{ name: 'middleware' },
|
||||
{ name: 'runtime', format: 'es' },
|
||||
{ name: 'webpack', file: 'webpack/config' }
|
||||
].map(obj => ({
|
||||
input: `src/${obj.name}/index.ts`,
|
||||
output: {
|
||||
file: `${obj.file || obj.name}.js`,
|
||||
format: obj.format || 'cjs',
|
||||
banner: obj.banner && '#!/usr/bin/env node',
|
||||
paths,
|
||||
sourcemap: true
|
||||
{
|
||||
input: `src/runtime/index.ts`,
|
||||
output: {
|
||||
file: `runtime.js`,
|
||||
format: 'es'
|
||||
},
|
||||
plugins: [
|
||||
typescript({
|
||||
typescript: require('typescript')
|
||||
})
|
||||
]
|
||||
},
|
||||
external,
|
||||
plugins
|
||||
}));
|
||||
|
||||
{
|
||||
input: [`src/cli.ts`, `src/core.ts`, `src/middleware.ts`, `src/webpack.ts`],
|
||||
output: {
|
||||
dir: '.',
|
||||
format: 'cjs',
|
||||
sourcemap: true
|
||||
},
|
||||
external,
|
||||
plugins: [
|
||||
string({
|
||||
include: '**/*.md'
|
||||
}),
|
||||
json(),
|
||||
commonjs(),
|
||||
typescript({
|
||||
typescript: require('typescript')
|
||||
})
|
||||
],
|
||||
experimentalCodeSplitting: true,
|
||||
experimentalDynamicImport: true
|
||||
}
|
||||
];
|
||||
@@ -4,13 +4,13 @@ import * as child_process from 'child_process';
|
||||
import sade from 'sade';
|
||||
import * as clorox from 'clorox';
|
||||
import prettyMs from 'pretty-ms';
|
||||
import help from './help.md';
|
||||
import build from './build';
|
||||
import exporter from './export';
|
||||
import dev from './dev';
|
||||
import upgrade from './upgrade';
|
||||
import help from './cli/help.md';
|
||||
import build from './cli/build';
|
||||
import exporter from './cli/export';
|
||||
import dev from './cli/dev';
|
||||
import upgrade from './cli/upgrade';
|
||||
import * as ports from 'port-authority';
|
||||
import * as pkg from '../../package.json';
|
||||
import * as pkg from '../package.json';
|
||||
|
||||
const prog = sade('sapper').version(pkg.version);
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as path from 'path';
|
||||
import * as clorox from 'clorox';
|
||||
import mkdirp from 'mkdirp';
|
||||
import rimraf from 'rimraf';
|
||||
import { create_compilers, create_app, create_routes, create_serviceworker } from 'sapper/core.js'
|
||||
import { create_compilers, create_app, create_routes, create_serviceworker } from '../core'
|
||||
import { src, dest, dev } from '../config';
|
||||
|
||||
export default async function build() {
|
||||
|
||||
@@ -10,7 +10,7 @@ import format_messages from 'webpack-format-messages';
|
||||
import prettyMs from 'pretty-ms';
|
||||
import * as ports from 'port-authority';
|
||||
import { dest } from '../config';
|
||||
import { create_compilers, create_app, create_routes, create_serviceworker } from 'sapper/core.js';
|
||||
import { create_compilers, create_app, create_routes, create_serviceworker } from '../core';
|
||||
|
||||
type Deferred = {
|
||||
promise?: Promise<any>;
|
||||
|
||||
4
src/core.ts
Normal file
4
src/core.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as create_app } from './core/create_app';
|
||||
export { default as create_serviceworker } from './core/create_serviceworker';
|
||||
export { default as create_compilers } from './core/create_compilers';
|
||||
export { default as create_routes } from './core/create_routes';
|
||||
@@ -1,4 +0,0 @@
|
||||
export { default as create_app } from './create_app';
|
||||
export { default as create_serviceworker } from './create_serviceworker';
|
||||
export { default as create_compilers } from './create_compilers';
|
||||
export { default as create_routes } from './create_routes';
|
||||
@@ -4,10 +4,10 @@ import { ClientRequest, ServerResponse } from 'http';
|
||||
import mkdirp from 'mkdirp';
|
||||
import rimraf from 'rimraf';
|
||||
import devalue from 'devalue';
|
||||
import { lookup } from './mime';
|
||||
import { create_routes, templates, create_compilers } from 'sapper/core.js';
|
||||
import { dest, dev } from '../config';
|
||||
import { Route, Template } from '../interfaces';
|
||||
import { lookup } from './middleware/mime';
|
||||
import { create_routes, templates, create_compilers } from './core/index';
|
||||
import { dest, dev } from './config';
|
||||
import { Route, Template } from './interfaces';
|
||||
import sourceMapSupport from 'source-map-support';
|
||||
|
||||
sourceMapSupport.install();
|
||||
@@ -1,4 +1,4 @@
|
||||
import { dest, dev } from '../config';
|
||||
import { dest, dev } from './config';
|
||||
|
||||
export default {
|
||||
dev: dev(),
|
||||
@@ -25,7 +25,7 @@ Nightmare.action('prefetchRoutes', function(done) {
|
||||
this.evaluate_now(() => window.prefetchRoutes(), done);
|
||||
});
|
||||
|
||||
const cli = path.resolve(__dirname, '../../cli.js');
|
||||
const cli = path.resolve(__dirname, '../../sapper');
|
||||
|
||||
describe('sapper', function() {
|
||||
process.chdir(path.resolve(__dirname, '../app'));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const assert = require('assert');
|
||||
const { create_routes } = require('../../core.js');
|
||||
const { create_routes } = require('../../core.ts.js');
|
||||
|
||||
describe('create_routes', () => {
|
||||
it('sorts routes correctly', () => {
|
||||
|
||||
2
webpack.js
Normal file
2
webpack.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// TODO write to this file, instead of webpack.ts.js
|
||||
module.exports = require('./webpack.ts.js');
|
||||
54
webpack.ts.js
Normal file
54
webpack.ts.js
Normal file
@@ -0,0 +1,54 @@
|
||||
'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
|
||||
1
webpack.ts.js.map
Normal file
1
webpack.ts.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"webpack.ts.js","sources":["src/webpack.ts"],"sourcesContent":["import { dest, dev } from './config';\n\nexport default {\n\tdev: dev(),\n\n\tclient: {\n\t\tentry: () => {\n\t\t\treturn {\n\t\t\t\tmain: './app/client'\n\t\t\t};\n\t\t},\n\n\t\toutput: () => {\n\t\t\treturn {\n\t\t\t\tpath: `${dest()}/client`,\n\t\t\t\tfilename: '[hash]/[name].js',\n\t\t\t\tchunkFilename: '[hash]/[name].[id].js',\n\t\t\t\tpublicPath: '/client/'\n\t\t\t};\n\t\t}\n\t},\n\n\tserver: {\n\t\tentry: () => {\n\t\t\treturn {\n\t\t\t\tserver: './app/server'\n\t\t\t};\n\t\t},\n\n\t\toutput: () => {\n\t\t\treturn {\n\t\t\t\tpath: dest(),\n\t\t\t\tfilename: '[name].js',\n\t\t\t\tchunkFilename: '[hash]/[name].[id].js',\n\t\t\t\tlibraryTarget: 'commonjs2'\n\t\t\t};\n\t\t}\n\t},\n\n\tserviceworker: {\n\t\tentry: () => {\n\t\t\treturn {\n\t\t\t\t'service-worker': './app/service-worker'\n\t\t\t};\n\t\t},\n\n\t\toutput: () => {\n\t\t\treturn {\n\t\t\t\tpath: dest(),\n\t\t\t\tfilename: '[name].js',\n\t\t\t\tchunkFilename: '[name].[id].[hash].js'\n\t\t\t}\n\t\t}\n\t}\n};"],"names":["dev","dest"],"mappings":";;;;AAEA,cAAe;IACd,GAAG,EAAEA,eAAG,EAAE;IAEV,MAAM,EAAE;QACP,KAAK,EAAE;YACN,OAAO;gBACN,IAAI,EAAE,cAAc;aACpB,CAAC;SACF;QAED,MAAM,EAAE;YACP,OAAO;gBACN,IAAI,EAAKC,gBAAI,EAAE,YAAS;gBACxB,QAAQ,EAAE,kBAAkB;gBAC5B,aAAa,EAAE,uBAAuB;gBACtC,UAAU,EAAE,UAAU;aACtB,CAAC;SACF;KACD;IAED,MAAM,EAAE;QACP,KAAK,EAAE;YACN,OAAO;gBACN,MAAM,EAAE,cAAc;aACtB,CAAC;SACF;QAED,MAAM,EAAE;YACP,OAAO;gBACN,IAAI,EAAEA,gBAAI,EAAE;gBACZ,QAAQ,EAAE,WAAW;gBACrB,aAAa,EAAE,uBAAuB;gBACtC,aAAa,EAAE,WAAW;aAC1B,CAAC;SACF;KACD;IAED,aAAa,EAAE;QACd,KAAK,EAAE;YACN,OAAO;gBACN,gBAAgB,EAAE,sBAAsB;aACxC,CAAC;SACF;QAED,MAAM,EAAE;YACP,OAAO;gBACN,IAAI,EAAEA,gBAAI,EAAE;gBACZ,QAAQ,EAAE,WAAW;gBACrB,aAAa,EAAE,uBAAuB;aACtC,CAAA;SACD;KACD;CACD,CAAC;;;;"}
|
||||
Reference in New Issue
Block a user