summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@matthewphillips.info> 2021-04-23 13:28:00 -0400
committerGravatar GitHub <noreply@github.com> 2021-04-23 13:28:00 -0400
commit9b9bdbf4a13a77acda47468fd4a1adfd3523f047 (patch)
treebf08d8a87d0c8d9593d382a473e2a032c5398d15 /src
parent510e7920d267e8181f255d3b321bbfda11417d33 (diff)
downloadastro-9b9bdbf4a13a77acda47468fd4a1adfd3523f047.tar.gz
astro-9b9bdbf4a13a77acda47468fd4a1adfd3523f047.tar.zst
astro-9b9bdbf4a13a77acda47468fd4a1adfd3523f047.zip
Add better CLI logging for dev/build (#126)
* Add better CLI logging for dev/build This adds better CLI logging for dev and build. * Fix the sorting
Diffstat (limited to 'src')
-rw-r--r--src/build.ts29
-rw-r--r--src/dev.ts10
-rw-r--r--src/logger.ts34
3 files changed, 57 insertions, 16 deletions
diff --git a/src/build.ts b/src/build.ts
index 2c61b3fed..f5e825ea4 100644
--- a/src/build.ts
+++ b/src/build.ts
@@ -3,11 +3,12 @@ import type { LogOptions } from './logger';
import type { AstroRuntime, LoadResult } from './runtime';
import { existsSync, promises as fsPromises } from 'fs';
+import { bold, green, yellow, underline } from 'kleur/colors';
import path from 'path';
import cheerio from 'cheerio';
import { fileURLToPath } from 'url';
import { fdir } from 'fdir';
-import { defaultLogDestination, error, info } from './logger.js';
+import { defaultLogDestination, error, info, trapWarn } from './logger.js';
import { createRuntime } from './runtime.js';
import { bundle, collectDynamicImports } from './build/bundle.js';
import { generateRSS } from './build/rss.js';
@@ -15,6 +16,7 @@ import { generateSitemap } from './build/sitemap.js';
import { collectStatics } from './build/static.js';
import { canonicalURL } from './build/util.js';
+
const { mkdir, readFile, writeFile } = fsPromises;
interface PageBuildOptions {
@@ -197,7 +199,11 @@ export async function build(astroConfig: AstroConfig): Promise<0 | 1> {
const pages = await allPages(pageRoot);
let builtURLs: string[] = [];
+
try {
+ info(logging , 'build', yellow('! building pages...'));
+ // Vue also console.warns, this silences it.
+ const release = trapWarn();
await Promise.all(
pages.map(async (pathname) => {
const filepath = new URL(`file://${pathname}`);
@@ -222,21 +228,27 @@ export async function build(astroConfig: AstroConfig): Promise<0 | 1> {
mergeSet(imports, await collectDynamicImports(filepath, collectImportsOptions));
})
);
+ info(logging, 'build', green('✔'), 'pages built.');
+ release();
} catch (err) {
error(logging, 'generate', err);
await runtime.shutdown();
return 1;
}
+ info(logging, 'build', yellow('! scanning pages...'));
for (const pathname of await allPages(componentRoot)) {
mergeSet(imports, await collectDynamicImports(new URL(`file://${pathname}`), collectImportsOptions));
}
+ info(logging, 'build', green('✔'), 'pages scanned.');
if (imports.size > 0) {
try {
+ info(logging, 'build', yellow('! bundling client-side code.'));
await bundle(imports, { dist, runtime, astroConfig });
+ info(logging, 'build', green('✔'), 'bundling complete.');
} catch (err) {
- error(logging, 'generate', err);
+ error(logging, 'build', err);
await runtime.shutdown();
return 1;
}
@@ -250,6 +262,7 @@ export async function build(astroConfig: AstroConfig): Promise<0 | 1> {
}
if (existsSync(astroConfig.public)) {
+ info(logging, 'build', yellow(`! copying public folder...`));
const pub = astroConfig.public;
const publicFiles = (await new fdir().withFullPaths().crawl(fileURLToPath(pub)).withPromise()) as string[];
for (const filepath of publicFiles) {
@@ -260,16 +273,28 @@ export async function build(astroConfig: AstroConfig): Promise<0 | 1> {
const bytes = await readFile(fileUrl);
await writeFilep(outUrl, bytes, null);
}
+ info(logging, 'build', green('✔'), 'public folder copied.');
}
// build sitemap
if (astroConfig.buildOptions.sitemap && astroConfig.buildOptions.site) {
+ info(logging, 'build', yellow('! creating a sitemap...'));
const sitemap = generateSitemap(builtURLs.map((url) => ({ canonicalURL: canonicalURL(url, astroConfig.buildOptions.site) })));
await writeFile(new URL('./sitemap.xml', dist), sitemap, 'utf8');
+ info(logging, 'build', green('✔'), 'sitemap built.');
} else if (astroConfig.buildOptions.sitemap) {
info(logging, 'tip', `Set "buildOptions.site" in astro.config.mjs to generate a sitemap.xml`);
}
+ builtURLs.sort((a, b) => a.localeCompare(b, 'en', { numeric: true }));
+ info(logging, 'build', underline('Pages'));
+ const lastIndex = builtURLs.length - 1;
+ builtURLs.forEach((url, index) => {
+ const sep = index === 0 ? '┌' : index === lastIndex ? '└' : '├';
+ info(logging, null, ' ' + sep, url === '/' ? url : url + '/');
+ });
+
await runtime.shutdown();
+ info(logging, 'build', bold(green('▶ Build Complete!')));
return 0;
}
diff --git a/src/dev.ts b/src/dev.ts
index 8f93aabf6..c20d9c723 100644
--- a/src/dev.ts
+++ b/src/dev.ts
@@ -2,9 +2,11 @@ import type { AstroConfig } from './@types/astro';
import type { LogOptions } from './logger.js';
import { logger as snowpackLogger } from 'snowpack';
+import { bold, green } from 'kleur/colors';
import http from 'http';
import { relative as pathRelative } from 'path';
-import { defaultLogDestination, error, parseError } from './logger.js';
+import { performance } from 'perf_hooks';
+import { defaultLogDestination, error, info, parseError } from './logger.js';
import { createRuntime } from './runtime.js';
const hostname = '127.0.0.1';
@@ -19,6 +21,7 @@ const logging: LogOptions = {
/** The primary dev action */
export default async function dev(astroConfig: AstroConfig) {
+ const startServerTime = performance.now();
const { projectRoot } = astroConfig;
const runtime = await createRuntime(astroConfig, { mode: 'development', logging });
@@ -66,8 +69,9 @@ export default async function dev(astroConfig: AstroConfig) {
const port = astroConfig.devOptions.port;
server.listen(port, hostname, () => {
- // eslint-disable-next-line no-console
- console.log(`Server running at http://${hostname}:${port}/`);
+ const endServerTime = performance.now();
+ info(logging, 'dev server', green(`Server started in ${Math.floor(endServerTime - startServerTime)}ms.`));
+ info(logging, 'dev server', `${green('Local:')} http://${hostname}:${port}/`);
});
}
diff --git a/src/logger.ts b/src/logger.ts
index 7ffc2da5a..7bfde67d9 100644
--- a/src/logger.ts
+++ b/src/logger.ts
@@ -15,13 +15,16 @@ export const defaultLogDestination = new Writable({
dest = process.stdout;
}
let type = event.type;
- if (event.level === 'info') {
- type = bold(blue(type));
- } else if (event.level === 'error') {
- type = bold(red(type));
+ if(type !== null) {
+ if (event.level === 'info') {
+ type = bold(blue(type));
+ } else if (event.level === 'error') {
+ type = bold(red(type));
+ }
+
+ dest.write(`[${type}] `);
}
- dest.write(`[${type}] `);
dest.write(utilFormat(...event.args));
dest.write('\n');
@@ -47,7 +50,7 @@ export const defaultLogOptions: LogOptions = {
};
export interface LogMessage {
- type: string;
+ type: string | null;
level: LoggerLevel;
message: string;
args: Array<any>;
@@ -62,7 +65,7 @@ const levels: Record<LoggerLevel, number> = {
};
/** Full logging API */
-export function log(opts: LogOptions = defaultLogOptions, level: LoggerLevel, type: string, ...args: Array<any>) {
+export function log(opts: LogOptions = defaultLogOptions, level: LoggerLevel, type: string | null, ...args: Array<any>) {
const event: LogMessage = {
type,
level,
@@ -79,22 +82,22 @@ export function log(opts: LogOptions = defaultLogOptions, level: LoggerLevel, ty
}
/** Emit a message only shown in debug mode */
-export function debug(opts: LogOptions, type: string, ...messages: Array<any>) {
+export function debug(opts: LogOptions, type: string | null, ...messages: Array<any>) {
return log(opts, 'debug', type, ...messages);
}
/** Emit a general info message (be careful using this too much!) */
-export function info(opts: LogOptions, type: string, ...messages: Array<any>) {
+export function info(opts: LogOptions, type: string | null, ...messages: Array<any>) {
return log(opts, 'info', type, ...messages);
}
/** Emit a warning a user should be aware of */
-export function warn(opts: LogOptions, type: string, ...messages: Array<any>) {
+export function warn(opts: LogOptions, type: string | null, ...messages: Array<any>) {
return log(opts, 'warn', type, ...messages);
}
/** Emit a fatal error message the user should address. */
-export function error(opts: LogOptions, type: string, ...messages: Array<any>) {
+export function error(opts: LogOptions, type: string | null, ...messages: Array<any>) {
return log(opts, 'error', type, ...messages);
}
@@ -129,3 +132,12 @@ export const logger = {
warn: warn.bind(null, defaultLogOptions),
error: error.bind(null, defaultLogOptions),
};
+
+// For silencing libraries that go directly to console.warn
+export function trapWarn(cb: (...args: any[]) => void = () =>{}) {
+ const warn = console.warn;
+ console.warn = function(...args: any[]) {
+ cb(...args);
+ };
+ return () => console.warn = warn;
+} \ No newline at end of file