mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-19 13:55:21 +00:00
vastly better logging
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"mri": "^1.1.0",
|
"mri": "^1.1.0",
|
||||||
"node-fetch": "^1.7.3",
|
"node-fetch": "^1.7.3",
|
||||||
|
"pretty-ms": "^3.1.0",
|
||||||
"relative": "^3.0.2",
|
"relative": "^3.0.2",
|
||||||
"require-relative": "^0.8.7",
|
"require-relative": "^0.8.7",
|
||||||
"rimraf": "^2.6.2",
|
"rimraf": "^2.6.2",
|
||||||
@@ -39,7 +40,8 @@
|
|||||||
"source-map-support": "^0.5.3",
|
"source-map-support": "^0.5.3",
|
||||||
"tslib": "^1.8.1",
|
"tslib": "^1.8.1",
|
||||||
"url-parse": "^1.2.0",
|
"url-parse": "^1.2.0",
|
||||||
"walk-sync": "^0.3.2"
|
"walk-sync": "^0.3.2",
|
||||||
|
"webpack-format-messages": "^1.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@std/esm": "^0.19.7",
|
"@std/esm": "^0.19.7",
|
||||||
@@ -55,6 +57,7 @@
|
|||||||
"nightmare": "^2.10.0",
|
"nightmare": "^2.10.0",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
"rollup": "^0.53.0",
|
"rollup": "^0.53.0",
|
||||||
|
"rollup-plugin-commonjs": "^8.3.0",
|
||||||
"rollup-plugin-json": "^2.3.0",
|
"rollup-plugin-json": "^2.3.0",
|
||||||
"rollup-plugin-string": "^2.0.2",
|
"rollup-plugin-string": "^2.0.2",
|
||||||
"rollup-plugin-typescript": "^0.8.1",
|
"rollup-plugin-typescript": "^0.8.1",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import typescript from 'rollup-plugin-typescript';
|
import typescript from 'rollup-plugin-typescript';
|
||||||
import string from 'rollup-plugin-string';
|
import string from 'rollup-plugin-string';
|
||||||
import json from 'rollup-plugin-json';
|
import json from 'rollup-plugin-json';
|
||||||
|
import commonjs from 'rollup-plugin-commonjs';
|
||||||
import pkg from './package.json';
|
import pkg from './package.json';
|
||||||
|
|
||||||
const external = [].concat(
|
const external = [].concat(
|
||||||
@@ -18,6 +19,7 @@ const plugins = [
|
|||||||
include: '**/*.md'
|
include: '**/*.md'
|
||||||
}),
|
}),
|
||||||
json(),
|
json(),
|
||||||
|
commonjs(),
|
||||||
typescript({
|
typescript({
|
||||||
typescript: require('typescript')
|
typescript: require('typescript')
|
||||||
})
|
})
|
||||||
|
|||||||
206
src/cli/dev.ts
206
src/cli/dev.ts
@@ -6,6 +6,8 @@ import * as child_process from 'child_process';
|
|||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
import rimraf from 'rimraf';
|
import rimraf from 'rimraf';
|
||||||
|
import format_messages from 'webpack-format-messages';
|
||||||
|
import prettyMs from 'pretty-ms';
|
||||||
import { wait_for_port } from './utils';
|
import { wait_for_port } from './utils';
|
||||||
import { dest } from '../config';
|
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 'sapper/core.js';
|
||||||
@@ -69,13 +71,12 @@ function create_hot_update_server(port: number, interval = 10000) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function dev() {
|
export default async function dev() {
|
||||||
const dir = dest();
|
process.env.NODE_ENV = 'development';
|
||||||
|
|
||||||
|
const dir = dest();
|
||||||
rimraf.sync(dir);
|
rimraf.sync(dir);
|
||||||
mkdirp.sync(dir);
|
mkdirp.sync(dir);
|
||||||
|
|
||||||
const chokidar = require('chokidar');
|
|
||||||
|
|
||||||
// initial build
|
// initial build
|
||||||
const dev_port = await require('get-port')(10000);
|
const dev_port = await require('get-port')(10000);
|
||||||
|
|
||||||
@@ -84,20 +85,6 @@ export default async function dev() {
|
|||||||
|
|
||||||
const hot_update_server = create_hot_update_server(dev_port);
|
const hot_update_server = create_hot_update_server(dev_port);
|
||||||
|
|
||||||
// TODO watch the configs themselves?
|
|
||||||
const compilers = create_compilers();
|
|
||||||
|
|
||||||
function watch_files(pattern: string, events: string[], callback: () => void) {
|
|
||||||
const watcher = chokidar.watch(pattern, {
|
|
||||||
persistent: true,
|
|
||||||
ignoreInitial: true
|
|
||||||
});
|
|
||||||
|
|
||||||
events.forEach(event => {
|
|
||||||
watcher.on(event, callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
watch_files('routes/**/*', ['add', 'unlink'], () => {
|
watch_files('routes/**/*', ['add', 'unlink'], () => {
|
||||||
const routes = create_routes();
|
const routes = create_routes();
|
||||||
create_app({ routes, dev_port });
|
create_app({ routes, dev_port });
|
||||||
@@ -116,31 +103,106 @@ export default async function dev() {
|
|||||||
client: deferred()
|
client: deferred()
|
||||||
};
|
};
|
||||||
|
|
||||||
const times = {
|
let restarting = false;
|
||||||
client_start: Date.now(),
|
let build = {
|
||||||
server_start: Date.now(),
|
unique_warnings: new Set(),
|
||||||
serviceworker_start: Date.now()
|
unique_errors: new Set()
|
||||||
};
|
};
|
||||||
|
|
||||||
compilers.server.plugin('invalid', () => {
|
function restart_build(filename) {
|
||||||
times.server_start = Date.now();
|
if (restarting) return;
|
||||||
// TODO print message
|
|
||||||
deferreds.server = deferred();
|
|
||||||
});
|
|
||||||
|
|
||||||
compilers.server.watch({}, (err: Error, stats: any) => {
|
restarting = true;
|
||||||
if (err) {
|
build = {
|
||||||
console.error(chalk.red(err.message));
|
unique_warnings: new Set(),
|
||||||
} else if (stats.hasErrors()) {
|
unique_errors: new Set()
|
||||||
// print errors. TODO notify client
|
};
|
||||||
stats.toJson().errors.forEach((error: Error) => {
|
|
||||||
console.error(error); // TODO make this look nice
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log(`built server in ${Date.now() - times.server_start}ms`); // TODO prettify
|
|
||||||
|
|
||||||
const server_info = stats.toJson();
|
process.nextTick(() => {
|
||||||
fs.writeFileSync(path.join(dir, 'server_info.json'), JSON.stringify(server_info, null, ' '));
|
restarting = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`\n${chalk.bold.cyan(path.relative(process.cwd(), filename))} changed. rebuilding...`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO watch the configs themselves?
|
||||||
|
const compilers = create_compilers();
|
||||||
|
|
||||||
|
function watch(compiler: any, { name, invalid = noop, error = noop, result }: {
|
||||||
|
name: string,
|
||||||
|
invalid?: (filename: string) => void;
|
||||||
|
error?: (error: Error) => void;
|
||||||
|
result: (stats: any) => void;
|
||||||
|
}) {
|
||||||
|
compiler.plugin('invalid', (filename: string) => {
|
||||||
|
invalid(filename);
|
||||||
|
});
|
||||||
|
|
||||||
|
compiler.watch({}, (err: Error, stats: any) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(chalk.red(`✗ ${name}`));
|
||||||
|
console.error(chalk.red(err.message));
|
||||||
|
error(err);
|
||||||
|
} else {
|
||||||
|
const messages = format_messages(stats);
|
||||||
|
const info = stats.toJson();
|
||||||
|
|
||||||
|
if (messages.errors.length > 0) {
|
||||||
|
console.log(chalk.bold.red(`✗ ${name}`));
|
||||||
|
|
||||||
|
const filtered = messages.errors.filter((message: string) => {
|
||||||
|
return !build.unique_errors.has(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
filtered.forEach((message: string) => {
|
||||||
|
build.unique_errors.add(message);
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
const 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(chalk.bold.yellow(`• ${name}`));
|
||||||
|
|
||||||
|
const filtered = messages.warnings.filter((message: string) => {
|
||||||
|
return !build.unique_warnings.has(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
filtered.forEach((message: string) => {
|
||||||
|
build.unique_warnings.add(message);
|
||||||
|
console.log(`${message}\n`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const hidden = messages.warnings.length - filtered.length;
|
||||||
|
if (hidden > 0) {
|
||||||
|
console.log(`${hidden} duplicate ${hidden === 1 ? 'warning' : 'warnings'} hidden\n`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`${chalk.bold.green(`✔ ${name}`)} ${chalk.grey(`(${prettyMs(info.time)})`)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
result(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(compilers.server, {
|
||||||
|
name: 'server',
|
||||||
|
|
||||||
|
invalid: filename => {
|
||||||
|
restart_build(filename);
|
||||||
|
// TODO print message
|
||||||
|
deferreds.server = deferred();
|
||||||
|
},
|
||||||
|
|
||||||
|
result: info => {
|
||||||
|
// TODO log compile errors/warnings
|
||||||
|
|
||||||
|
fs.writeFileSync(path.join(dir, 'server_info.json'), JSON.stringify(info, null, ' '));
|
||||||
|
|
||||||
deferreds.client.promise.then(() => {
|
deferreds.client.promise.then(() => {
|
||||||
function restart() {
|
function restart() {
|
||||||
@@ -162,32 +224,23 @@ export default async function dev() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
compilers.client.plugin('invalid', (filename: string) => {
|
watch(compilers.client, {
|
||||||
times.client_start = Date.now();
|
name: 'client',
|
||||||
|
|
||||||
deferreds.client = deferred();
|
invalid: filename => {
|
||||||
|
restart_build(filename);
|
||||||
|
deferreds.client = deferred();
|
||||||
|
|
||||||
// TODO we should delete old assets. due to a webpack bug
|
// TODO we should delete old assets. due to a webpack bug
|
||||||
// i don't even begin to comprehend, this is apparently
|
// i don't even begin to comprehend, this is apparently
|
||||||
// quite difficult
|
// quite difficult
|
||||||
});
|
},
|
||||||
|
|
||||||
compilers.client.watch({}, (err: Error, stats: any) => {
|
result: info => {
|
||||||
if (err) {
|
fs.writeFileSync(path.join(dir, 'client_info.json'), JSON.stringify(info, null, ' '));
|
||||||
console.error(chalk.red(err.message));
|
|
||||||
} else if (stats.hasErrors()) {
|
|
||||||
// print errors. TODO notify client
|
|
||||||
stats.toJson().errors.forEach((error: Error) => {
|
|
||||||
console.error(error); // TODO make this look nice
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log(`built client in ${Date.now() - times.client_start}ms`); // TODO prettify
|
|
||||||
|
|
||||||
const client_info = stats.toJson();
|
|
||||||
fs.writeFileSync(path.join(dir, 'client_info.json'), JSON.stringify(client_info, null, ' '));
|
|
||||||
deferreds.client.fulfil();
|
deferreds.client.fulfil();
|
||||||
|
|
||||||
const client_files = client_info.assets.map((chunk: { name: string }) => `/client/${chunk.name}`);
|
const client_files = info.assets.map((chunk: { name: string }) => `/client/${chunk.name}`);
|
||||||
|
|
||||||
deferreds.server.promise.then(() => {
|
deferreds.server.promise.then(() => {
|
||||||
hot_update_server.send({
|
hot_update_server.send({
|
||||||
@@ -208,27 +261,28 @@ export default async function dev() {
|
|||||||
? function() {
|
? function() {
|
||||||
watch_serviceworker = noop;
|
watch_serviceworker = noop;
|
||||||
|
|
||||||
compilers.serviceworker.plugin('invalid', (filename: string) => {
|
watch(compilers.serviceworker, {
|
||||||
times.serviceworker_start = Date.now();
|
name: 'service worker',
|
||||||
});
|
|
||||||
|
|
||||||
compilers.serviceworker.watch({}, (err: Error, stats: any) => {
|
result: info => {
|
||||||
if (err) {
|
fs.writeFileSync(path.join(dir, 'serviceworker_info.json'), JSON.stringify(info, null, ' '));
|
||||||
// TODO notify client
|
|
||||||
} else if (stats.hasErrors()) {
|
|
||||||
// print errors. TODO notify client
|
|
||||||
stats.toJson().errors.forEach((error: Error) => {
|
|
||||||
console.error(error); // TODO make this look nice
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log(`built service worker in ${Date.now() - times.serviceworker_start}ms`); // TODO prettify
|
|
||||||
|
|
||||||
const serviceworker_info = stats.toJson();
|
|
||||||
fs.writeFileSync(path.join(dir, 'serviceworker_info.json'), JSON.stringify(serviceworker_info, null, ' '));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
: noop;
|
: noop;
|
||||||
}
|
}
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
|
|
||||||
|
function watch_files(pattern: string, events: string[], callback: () => void) {
|
||||||
|
const chokidar = require('chokidar');
|
||||||
|
|
||||||
|
const watcher = chokidar.watch(pattern, {
|
||||||
|
persistent: true,
|
||||||
|
ignoreInitial: true
|
||||||
|
});
|
||||||
|
|
||||||
|
events.forEach(event => {
|
||||||
|
watcher.on(event, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user