Browse Source

more consistent error logging in CLI

gh-1187
Rich Harris 8 years ago
parent
commit
35785fff12
  1. 65
      bin/src/handleError.js
  2. 47
      bin/src/logging.js
  3. 209
      bin/src/runRollup.js

65
bin/src/handleError.js

@ -1,65 +0,0 @@
import chalk from 'chalk';
function stderr ( msg ) {
console.error( msg ); // eslint-disable-line no-console
}
const handlers = {
MISSING_CONFIG: () => {
stderr( chalk.red( 'Config file must export an options object. See https://github.com/rollup/rollup/wiki/Command-Line-Interface#using-a-config-file' ) );
},
MISSING_EXTERNAL_CONFIG: err => {
stderr( chalk.red( `Could not resolve config file ${err.config}` ) );
},
MISSING_INPUT_OPTION: () => {
stderr( chalk.red( 'You must specify an --input (-i) option' ) );
},
MISSING_OUTPUT_OPTION: () => {
stderr( chalk.red( 'You must specify an --output (-o) option when creating a file with a sourcemap' ) );
},
MISSING_NAME: () => {
stderr( chalk.red( 'You must supply a name for UMD exports (e.g. `--name myModule`)' ) );
},
PARSE_ERROR: err => {
stderr( chalk.red( `Error parsing ${err.file}: ${err.message}` ) );
},
ONE_AT_A_TIME: () => {
stderr( chalk.red( 'rollup can only bundle one file at a time' ) );
},
DUPLICATE_IMPORT_OPTIONS: () => {
stderr( chalk.red( 'use --input, or pass input path as argument' ) );
},
ROLLUP_WATCH_NOT_INSTALLED: () => {
stderr( chalk.red( 'rollup --watch depends on the rollup-watch package, which could not be found. Install it with ' ) + chalk.cyan( 'npm install -D rollup-watch' ) );
},
WATCHER_MISSING_INPUT_OR_OUTPUT: () => {
stderr( chalk.red( 'must specify --input and --output when using rollup --watch' ) );
}
};
export default function handleError ( err, recover ) {
const handler = handlers[ err && err.code ];
if ( handler ) {
handler( err );
} else {
stderr( chalk.red( err.message || err ) );
if ( err.stack ) {
stderr( chalk.grey( err.stack ) );
}
}
stderr( `Type ${chalk.cyan( 'rollup --help' )} for help, or visit https://github.com/rollup/rollup/wiki` );
if ( !recover ) process.exit( 1 );
}

47
bin/src/logging.js

@ -0,0 +1,47 @@
import chalk from 'chalk';
import relativeId from '../../src/utils/relativeId.js';
if ( !process.stderr.isTTY ) chalk.enabled = false;
const warnSymbol = process.stderr.isTTY ? `⚠️ ` : `Warning: `;
const errorSymbol = process.stderr.isTTY ? `🚨 ` : `Error: `;
// log to stderr to keep `rollup main.js > bundle.js` from breaking
export const stderr = console.error.bind( console ); // eslint-disable-line no-console
export function handleWarning ( warning ) {
stderr( `${warnSymbol}${chalk.bold( warning.message )}` );
if ( warning.url ) {
stderr( chalk.cyan( warning.url ) );
}
if ( warning.loc ) {
stderr( `${relativeId( warning.loc.file )} (${warning.loc.line}:${warning.loc.column})` );
}
if ( warning.frame ) {
stderr( chalk.dim( warning.frame ) );
}
stderr( '' );
}
export function handleError ( err, recover ) {
stderr( `${errorSymbol}${chalk.bold( err.message )}` );
if ( err.url ) {
stderr( chalk.cyan( err.url ) );
}
if ( err.loc ) {
stderr( `${relativeId( err.loc.file )} (${err.loc.line}:${err.loc.column})` );
}
if ( err.frame ) {
stderr( chalk.dim( err.frame ) );
}
stderr( '' );
if ( !recover ) process.exit( 1 );
}

209
bin/src/runRollup.js

@ -2,27 +2,26 @@ import { realpathSync } from 'fs';
import * as rollup from 'rollup';
import relative from 'require-relative';
import chalk from 'chalk';
import handleError from './handleError';
import relativeId from '../../src/utils/relativeId.js';
import { handleWarning, handleError, stderr } from './logging.js';
import SOURCEMAPPING_URL from './sourceMappingUrl.js';
import { install as installSourcemapSupport } from 'source-map-support';
installSourcemapSupport();
if ( !process.stderr.isTTY ) chalk.enabled = false;
const warnSymbol = process.stderr.isTTY ? `⚠️ ` : `Warning: `;
// stderr to stderr to keep `rollup main.js > bundle.js` from breaking
const stderr = console.error.bind( console ); // eslint-disable-line no-console
export default function runRollup ( command ) {
if ( command._.length > 1 ) {
handleError({ code: 'ONE_AT_A_TIME' });
handleError({
code: 'ONE_AT_A_TIME',
message: 'rollup can only bundle one file at a time'
});
}
if ( command._.length === 1 ) {
if ( command.input ) {
handleError({ code: 'DUPLICATE_IMPORT_OPTIONS' });
handleError({
code: 'DUPLICATE_IMPORT_OPTIONS',
message: 'use --input, or pass input path as argument'
});
}
command.input = command._[0];
@ -51,7 +50,10 @@ export default function runRollup ( command ) {
config = relative.resolve( pkgName, process.cwd() );
} catch ( err ) {
if ( err.code === 'MODULE_NOT_FOUND' ) {
handleError({ code: 'MISSING_EXTERNAL_CONFIG', config });
handleError({
code: 'MISSING_EXTERNAL_CONFIG',
message: `Could not resolve config file ${config}`
});
}
throw err;
@ -64,37 +66,38 @@ export default function runRollup ( command ) {
rollup.rollup({
entry: config,
onwarn: message => {
if ( message.code === 'UNRESOLVED_IMPORT' ) return;
stderr( message.toString() );
onwarn: warning => {
if ( warning.code === 'UNRESOLVED_IMPORT' ) return;
handleWarning( warning );
}
}).then( bundle => {
const { code } = bundle.generate({
format: 'cjs'
});
})
.then( bundle => {
const { code } = bundle.generate({
format: 'cjs'
});
// temporarily override require
const defaultLoader = require.extensions[ '.js' ];
require.extensions[ '.js' ] = ( m, filename ) => {
if ( filename === config ) {
m._compile( code, filename );
} else {
defaultLoader( m, filename );
}
};
// temporarily override require
const defaultLoader = require.extensions[ '.js' ];
require.extensions[ '.js' ] = ( m, filename ) => {
if ( filename === config ) {
m._compile( code, filename );
} else {
defaultLoader( m, filename );
}
};
try {
const options = require( config );
if ( Object.keys( options ).length === 0 ) {
handleError({ code: 'MISSING_CONFIG' });
handleError({
code: 'MISSING_CONFIG',
message: 'Config file must export an options object',
url: 'https://github.com/rollup/rollup/wiki/Command-Line-Interface#using-a-config-file'
});
}
execute( options, command );
require.extensions[ '.js' ] = defaultLoader;
} catch ( err ) {
handleError( err );
}
})
.catch( stderr );
})
.catch( handleError );
} else {
execute( {}, command );
}
@ -157,21 +160,7 @@ function execute ( options, command ) {
if ( seen.has( str ) ) return;
seen.add( str );
stderr( `${warnSymbol}${chalk.bold( warning.message )}` );
if ( warning.url ) {
stderr( chalk.cyan( warning.url ) );
}
if ( warning.loc ) {
stderr( `${relativeId( warning.loc.file )} (${warning.loc.line}:${warning.loc.column})` );
}
if ( warning.frame ) {
stderr( chalk.dim( warning.frame ) );
}
stderr( '' );
handleWarning( warning );
};
}
@ -184,50 +173,52 @@ function execute ( options, command ) {
}
});
try {
if ( command.watch ) {
if ( !options.entry || ( !options.dest && !options.targets ) ) {
handleError({ code: 'WATCHER_MISSING_INPUT_OR_OUTPUT' });
}
if ( command.watch ) {
if ( !options.entry || ( !options.dest && !options.targets ) ) {
handleError({
code: 'WATCHER_MISSING_INPUT_OR_OUTPUT',
message: 'must specify --input and --output when using rollup --watch'
});
}
try {
const watch = relative( 'rollup-watch', process.cwd() );
const watcher = watch( rollup, options );
try {
const watch = relative( 'rollup-watch', process.cwd() );
const watcher = watch( rollup, options );
watcher.on( 'event', event => {
switch ( event.code ) {
case 'STARTING': // TODO this isn't emitted by newer versions of rollup-watch
stderr( 'checking rollup-watch version...' );
break;
watcher.on( 'event', event => {
switch ( event.code ) {
case 'STARTING': // TODO this isn't emitted by newer versions of rollup-watch
stderr( 'checking rollup-watch version...' );
break;
case 'BUILD_START':
stderr( 'bundling...' );
break;
case 'BUILD_START':
stderr( 'bundling...' );
break;
case 'BUILD_END':
stderr( 'bundled in ' + event.duration + 'ms. Watching for changes...' );
break;
case 'BUILD_END':
stderr( 'bundled in ' + event.duration + 'ms. Watching for changes...' );
break;
case 'ERROR':
handleError( event.error, true );
break;
case 'ERROR':
handleError( event.error, true );
break;
default:
stderr( 'unknown event', event );
}
});
} catch ( err ) {
if ( err.code === 'MODULE_NOT_FOUND' ) {
err.code = 'ROLLUP_WATCH_NOT_INSTALLED';
default:
stderr( 'unknown event', event );
}
handleError( err );
});
} catch ( err ) {
if ( err.code === 'MODULE_NOT_FOUND' ) {
handleError({
code: 'ROLLUP_WATCH_NOT_INSTALLED',
message: 'rollup --watch depends on the rollup-watch package, which could not be found. Install it with npm install -D rollup-watch'
});
}
} else {
bundle( options ).catch( handleError );
handleError( err );
}
} catch ( err ) {
handleError( err );
} else {
bundle( options ).catch( handleError );
}
}
@ -244,34 +235,42 @@ function assign ( target, source ) {
function bundle ( options ) {
if ( !options.entry ) {
handleError({ code: 'MISSING_INPUT_OPTION' });
handleError({
code: 'MISSING_INPUT_OPTION',
message: 'You must specify an --input (-i) option'
});
}
return rollup.rollup( options ).then( bundle => {
if ( options.dest ) {
return bundle.write( options );
}
return rollup.rollup( options )
.then( bundle => {
if ( options.dest ) {
return bundle.write( options );
}
if ( options.targets ) {
let result = null;
if ( options.targets ) {
let result = null;
options.targets.forEach( target => {
result = bundle.write( assign( clone( options ), target ) );
});
options.targets.forEach( target => {
result = bundle.write( assign( clone( options ), target ) );
});
return result;
}
return result;
}
if ( options.sourceMap && options.sourceMap !== 'inline' ) {
handleError({ code: 'MISSING_OUTPUT_OPTION' });
}
if ( options.sourceMap && options.sourceMap !== 'inline' ) {
handleError({
code: 'MISSING_OUTPUT_OPTION',
message: 'You must specify an --output (-o) option when creating a file with a sourcemap'
});
}
let { code, map } = bundle.generate( options );
let { code, map } = bundle.generate( options );
if ( options.sourceMap === 'inline' ) {
code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}\n`;
}
if ( options.sourceMap === 'inline' ) {
code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}\n`;
}
process.stdout.write( code );
});
process.stdout.write( code );
})
.catch( handleError );
}

Loading…
Cancel
Save