Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit e91955f

Browse files
authored
Merge pull request #158 from sveltejs/logging
vastly better logging
2 parents 0165c14 + 368e6d5 commit e91955f

File tree

4 files changed

+137
-78
lines changed

4 files changed

+137
-78
lines changed

package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"mkdirp": "^0.5.1",
3232
"mri": "^1.1.0",
3333
"node-fetch": "^1.7.3",
34+
"pretty-ms": "^3.1.0",
3435
"relative": "^3.0.2",
3536
"require-relative": "^0.8.7",
3637
"rimraf": "^2.6.2",
@@ -39,7 +40,8 @@
3940
"source-map-support": "^0.5.3",
4041
"tslib": "^1.8.1",
4142
"url-parse": "^1.2.0",
42-
"walk-sync": "^0.3.2"
43+
"walk-sync": "^0.3.2",
44+
"webpack-format-messages": "^1.0.1"
4345
},
4446
"devDependencies": {
4547
"@std/esm": "^0.19.7",
@@ -55,6 +57,7 @@
5557
"nightmare": "^2.10.0",
5658
"npm-run-all": "^4.1.2",
5759
"rollup": "^0.53.0",
60+
"rollup-plugin-commonjs": "^8.3.0",
5861
"rollup-plugin-json": "^2.3.0",
5962
"rollup-plugin-string": "^2.0.2",
6063
"rollup-plugin-typescript": "^0.8.1",

rollup.config.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import typescript from 'rollup-plugin-typescript';
22
import string from 'rollup-plugin-string';
33
import json from 'rollup-plugin-json';
4+
import commonjs from 'rollup-plugin-commonjs';
45
import pkg from './package.json';
56

67
const external = [].concat(
@@ -18,6 +19,7 @@ const plugins = [
1819
include: '**/*.md'
1920
}),
2021
json(),
22+
commonjs(),
2123
typescript({
2224
typescript: require('typescript')
2325
})

src/cli/dev.ts

+130-76
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import * as child_process from 'child_process';
66
import * as http from 'http';
77
import mkdirp from 'mkdirp';
88
import rimraf from 'rimraf';
9+
import format_messages from 'webpack-format-messages';
10+
import prettyMs from 'pretty-ms';
911
import { wait_for_port } from './utils';
1012
import { dest } from '../config';
1113
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) {
6971
}
7072

7173
export default async function dev() {
72-
const dir = dest();
74+
process.env.NODE_ENV = 'development';
7375

76+
const dir = dest();
7477
rimraf.sync(dir);
7578
mkdirp.sync(dir);
7679

77-
const chokidar = require('chokidar');
78-
7980
// initial build
8081
const dev_port = await require('get-port')(10000);
8182

@@ -84,20 +85,6 @@ export default async function dev() {
8485

8586
const hot_update_server = create_hot_update_server(dev_port);
8687

87-
// TODO watch the configs themselves?
88-
const compilers = create_compilers();
89-
90-
function watch_files(pattern: string, events: string[], callback: () => void) {
91-
const watcher = chokidar.watch(pattern, {
92-
persistent: true,
93-
ignoreInitial: true
94-
});
95-
96-
events.forEach(event => {
97-
watcher.on(event, callback);
98-
});
99-
}
100-
10188
watch_files('routes/**/*', ['add', 'unlink'], () => {
10289
const routes = create_routes();
10390
create_app({ routes, dev_port });
@@ -116,31 +103,106 @@ export default async function dev() {
116103
client: deferred()
117104
};
118105

119-
const times = {
120-
client_start: Date.now(),
121-
server_start: Date.now(),
122-
serviceworker_start: Date.now()
106+
let restarting = false;
107+
let build = {
108+
unique_warnings: new Set(),
109+
unique_errors: new Set()
123110
};
124111

125-
compilers.server.plugin('invalid', () => {
126-
times.server_start = Date.now();
127-
// TODO print message
128-
deferreds.server = deferred();
129-
});
112+
function restart_build(filename) {
113+
if (restarting) return;
130114

131-
compilers.server.watch({}, (err: Error, stats: any) => {
132-
if (err) {
133-
console.error(chalk.red(err.message));
134-
} else if (stats.hasErrors()) {
135-
// print errors. TODO notify client
136-
stats.toJson().errors.forEach((error: Error) => {
137-
console.error(error); // TODO make this look nice
138-
});
139-
} else {
140-
console.log(`built server in ${Date.now() - times.server_start}ms`); // TODO prettify
115+
restarting = true;
116+
build = {
117+
unique_warnings: new Set(),
118+
unique_errors: new Set()
119+
};
120+
121+
process.nextTick(() => {
122+
restarting = false;
123+
});
124+
125+
console.log(`\n${chalk.bold.cyan(path.relative(process.cwd(), filename))} changed. rebuilding...`);
126+
}
127+
128+
// TODO watch the configs themselves?
129+
const compilers = create_compilers();
130+
131+
function watch(compiler: any, { name, invalid = noop, error = noop, result }: {
132+
name: string,
133+
invalid?: (filename: string) => void;
134+
error?: (error: Error) => void;
135+
result: (stats: any) => void;
136+
}) {
137+
compiler.plugin('invalid', (filename: string) => {
138+
invalid(filename);
139+
});
140+
141+
compiler.watch({}, (err: Error, stats: any) => {
142+
if (err) {
143+
console.error(chalk.red(`✗ ${name}`));
144+
console.error(chalk.red(err.message));
145+
error(err);
146+
} else {
147+
const messages = format_messages(stats);
148+
const info = stats.toJson();
149+
150+
if (messages.errors.length > 0) {
151+
console.log(chalk.bold.red(`✗ ${name}`));
141152

142-
const server_info = stats.toJson();
143-
fs.writeFileSync(path.join(dir, 'server_info.json'), JSON.stringify(server_info, null, ' '));
153+
const filtered = messages.errors.filter((message: string) => {
154+
return !build.unique_errors.has(message);
155+
});
156+
157+
filtered.forEach((message: string) => {
158+
build.unique_errors.add(message);
159+
console.log(message);
160+
});
161+
162+
const hidden = messages.errors.length - filtered.length;
163+
if (hidden > 0) {
164+
console.log(`${hidden} duplicate ${hidden === 1 ? 'error' : 'errors'} hidden\n`);
165+
}
166+
} else {
167+
if (messages.warnings.length > 0) {
168+
console.log(chalk.bold.yellow(`• ${name}`));
169+
170+
const filtered = messages.warnings.filter((message: string) => {
171+
return !build.unique_warnings.has(message);
172+
});
173+
174+
filtered.forEach((message: string) => {
175+
build.unique_warnings.add(message);
176+
console.log(`${message}\n`);
177+
});
178+
179+
const hidden = messages.warnings.length - filtered.length;
180+
if (hidden > 0) {
181+
console.log(`${hidden} duplicate ${hidden === 1 ? 'warning' : 'warnings'} hidden\n`);
182+
}
183+
} else {
184+
console.log(`${chalk.bold.green(`✔ ${name}`)} ${chalk.grey(`(${prettyMs(info.time)})`)}`);
185+
}
186+
187+
result(info);
188+
}
189+
}
190+
});
191+
}
192+
193+
watch(compilers.server, {
194+
name: 'server',
195+
196+
invalid: filename => {
197+
restart_build(filename);
198+
// TODO print message
199+
deferreds.server = deferred();
200+
},
201+
202+
result: info => {
203+
// TODO log compile errors/warnings
204+
205+
fs.writeFileSync(path.join(dir, 'server_info.json'), JSON.stringify(info, null, ' '));
144206

145207
deferreds.client.promise.then(() => {
146208
function restart() {
@@ -162,32 +224,23 @@ export default async function dev() {
162224
}
163225
});
164226

165-
compilers.client.plugin('invalid', (filename: string) => {
166-
times.client_start = Date.now();
227+
watch(compilers.client, {
228+
name: 'client',
167229

168-
deferreds.client = deferred();
230+
invalid: filename => {
231+
restart_build(filename);
232+
deferreds.client = deferred();
169233

170-
// TODO we should delete old assets. due to a webpack bug
171-
// i don't even begin to comprehend, this is apparently
172-
// quite difficult
173-
});
234+
// TODO we should delete old assets. due to a webpack bug
235+
// i don't even begin to comprehend, this is apparently
236+
// quite difficult
237+
},
174238

175-
compilers.client.watch({}, (err: Error, stats: any) => {
176-
if (err) {
177-
console.error(chalk.red(err.message));
178-
} else if (stats.hasErrors()) {
179-
// print errors. TODO notify client
180-
stats.toJson().errors.forEach((error: Error) => {
181-
console.error(error); // TODO make this look nice
182-
});
183-
} else {
184-
console.log(`built client in ${Date.now() - times.client_start}ms`); // TODO prettify
185-
186-
const client_info = stats.toJson();
187-
fs.writeFileSync(path.join(dir, 'client_info.json'), JSON.stringify(client_info, null, ' '));
239+
result: info => {
240+
fs.writeFileSync(path.join(dir, 'client_info.json'), JSON.stringify(info, null, ' '));
188241
deferreds.client.fulfil();
189242

190-
const client_files = client_info.assets.map((chunk: { name: string }) => `/client/${chunk.name}`);
243+
const client_files = info.assets.map((chunk: { name: string }) => `/client/${chunk.name}`);
191244

192245
deferreds.server.promise.then(() => {
193246
hot_update_server.send({
@@ -208,27 +261,28 @@ export default async function dev() {
208261
? function() {
209262
watch_serviceworker = noop;
210263

211-
compilers.serviceworker.plugin('invalid', (filename: string) => {
212-
times.serviceworker_start = Date.now();
213-
});
214-
215-
compilers.serviceworker.watch({}, (err: Error, stats: any) => {
216-
if (err) {
217-
// TODO notify client
218-
} else if (stats.hasErrors()) {
219-
// print errors. TODO notify client
220-
stats.toJson().errors.forEach((error: Error) => {
221-
console.error(error); // TODO make this look nice
222-
});
223-
} else {
224-
console.log(`built service worker in ${Date.now() - times.serviceworker_start}ms`); // TODO prettify
264+
watch(compilers.serviceworker, {
265+
name: 'service worker',
225266

226-
const serviceworker_info = stats.toJson();
227-
fs.writeFileSync(path.join(dir, 'serviceworker_info.json'), JSON.stringify(serviceworker_info, null, ' '));
267+
result: info => {
268+
fs.writeFileSync(path.join(dir, 'serviceworker_info.json'), JSON.stringify(info, null, ' '));
228269
}
229270
});
230271
}
231272
: noop;
232273
}
233274

234-
function noop() {}
275+
function noop() {}
276+
277+
function watch_files(pattern: string, events: string[], callback: () => void) {
278+
const chokidar = require('chokidar');
279+
280+
const watcher = chokidar.watch(pattern, {
281+
persistent: true,
282+
ignoreInitial: true
283+
});
284+
285+
events.forEach(event => {
286+
watcher.on(event, callback);
287+
});
288+
}

test/common/test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Nightmare.action('init', function(done) {
2525

2626
function run(env) {
2727
describe(`env=${env}`, function () {
28-
this.timeout(20000);
28+
this.timeout(30000);
2929

3030
let PORT;
3131
let proc;

0 commit comments

Comments
 (0)