Browse Source

Merge pull request #706 from rollup/gh-700

Build/bundle CLI
ghi-672
Rich Harris 9 years ago
committed by GitHub
parent
commit
d5e1373fcb
  1. 1
      .gitignore
  2. 57
      bin/handleError.js
  3. 38
      bin/rollup
  4. 13
      bin/showHelp.js
  5. 61
      bin/src/handleError.js
  6. 2
      bin/src/help.md
  7. 38
      bin/src/index.js
  8. 95
      bin/src/runRollup.js
  9. 4
      bin/src/sourceMappingUrl.js
  10. 19
      package.json
  11. 29
      rollup.config.cli.js
  12. 4
      rollup.config.js
  13. 1
      test/mocha.opts

1
.gitignore

@ -7,3 +7,4 @@ _actual
coverage coverage
.commithash .commithash
.idea .idea
bin/rollup

57
bin/handleError.js

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

38
bin/rollup

@ -1,38 +0,0 @@
#!/usr/bin/env node
var minimist = require( 'minimist' ),
command;
command = minimist( process.argv.slice( 2 ), {
alias: {
// Aliases
strict: 'useStrict',
// Short options
c: 'config',
d: 'indent',
e: 'external',
f: 'format',
g: 'globals',
h: 'help',
i: 'input',
m: 'sourcemap',
n: 'name',
o: 'output',
u: 'id',
v: 'version',
w: 'watch'
}
});
if ( command.help || ( process.argv.length <= 2 && process.stdin.isTTY ) ) {
require( './showHelp' )();
}
else if ( command.version ) {
console.log( 'rollup version ' + require( '../package.json' ).version );
}
else {
require( './runRollup' )( command );
}

13
bin/showHelp.js

@ -1,13 +0,0 @@
var fs = require( 'fs' );
var path = require( 'path' );
module.exports = function () {
fs.readFile( path.join( __dirname, 'help.md' ), function ( err, result ) {
var help;
if ( err ) throw err;
help = result.toString().replace( '<%= version %>', require( '../package.json' ).version );
console.log( '\n' + help + '\n' );
});
};

61
bin/src/handleError.js

@ -0,0 +1,61 @@
import * as 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_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. You can install it globally (recommended) with ' ) + chalk.cyan( 'npm install -g rollup-watch' ) );
},
WATCHER_MISSING_INPUT_OR_OUTPUT: () => {
stderr( chalk.red( 'must specify --input and --output when using rollup --watch' ) );
}
};
export default function handleError ( err ) {
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` );
process.exit( 1 );
}

2
bin/help.md → bin/src/help.md

@ -1,4 +1,4 @@
rollup version <%= version %> rollup version __VERSION__
===================================== =====================================
Usage: rollup [options] <entry file> Usage: rollup [options] <entry file>

38
bin/src/index.js

@ -0,0 +1,38 @@
import minimist from 'minimist';
import help from './help.md';
import { version } from '../../package.json';
import runRollup from './runRollup';
const command = minimist( process.argv.slice( 2 ), {
alias: {
// Aliases
strict: 'useStrict',
// Short options
c: 'config',
d: 'indent',
e: 'external',
f: 'format',
g: 'globals',
h: 'help',
i: 'input',
m: 'sourcemap',
n: 'name',
o: 'output',
u: 'id',
v: 'version',
w: 'watch'
}
});
if ( command.help || ( process.argv.length <= 2 && process.stdin.isTTY ) ) {
console.log( `\n${help.replace('__VERSION__', version)}\n` ); // eslint-disable-line no-console
}
else if ( command.version ) {
console.log( `rollup version ${version}` ); // eslint-disable-line no-console
}
else {
runRollup( command );
}

95
bin/runRollup.js → bin/src/runRollup.js

@ -1,15 +1,17 @@
require( 'source-map-support' ).install(); import { resolve } from 'path';
import relative from 'require-relative';
import handleError from './handleError';
import SOURCEMAPPING_URL from './sourceMappingUrl.js';
var path = require( 'path' ); const rollup = require( '../dist/rollup.js' ); // TODO make this an import, somehow
var relative = require( 'require-relative' );
var handleError = require( './handleError' );
var chalk = require( 'chalk' );
var rollup = require( '../' );
// log to stderr to keep `rollup main.js > bundle.js` from breaking import { install as installSourcemapSupport } from 'source-map-support';
var log = console.error.bind(console); installSourcemapSupport();
module.exports = function ( command ) { // 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 ) { if ( command._.length > 1 ) {
handleError({ code: 'ONE_AT_A_TIME' }); handleError({ code: 'ONE_AT_A_TIME' });
} }
@ -23,8 +25,8 @@ module.exports = function ( command ) {
} }
if ( command.environment ) { if ( command.environment ) {
command.environment.split( ',' ).forEach( function ( pair ) { command.environment.split( ',' ).forEach( pair => {
var index = pair.indexOf( ':' ); const index = pair.indexOf( ':' );
if ( ~index ) { if ( ~index ) {
process.env[ pair.slice( 0, index ) ] = pair.slice( index + 1 ); process.env[ pair.slice( 0, index ) ] = pair.slice( index + 1 );
} else { } else {
@ -33,25 +35,25 @@ module.exports = function ( command ) {
}); });
} }
var config = command.config === true ? 'rollup.config.js' : command.config; let config = command.config === true ? 'rollup.config.js' : command.config;
if ( config ) { if ( config ) {
config = path.resolve( config ); config = resolve( config );
rollup.rollup({ rollup.rollup({
entry: config, entry: config,
onwarn: function ( message ) { onwarn: message => {
if ( /Treating .+ as external dependency/.test( message ) ) return; if ( /Treating .+ as external dependency/.test( message ) ) return;
log( message ); stderr( message );
} }
}).then( function ( bundle ) { }).then( bundle => {
var code = bundle.generate({ const { code } = bundle.generate({
format: 'cjs' format: 'cjs'
}).code; });
// temporarily override require // temporarily override require
var defaultLoader = require.extensions[ '.js' ]; var defaultLoader = require.extensions[ '.js' ];
require.extensions[ '.js' ] = function ( m, filename ) { require.extensions[ '.js' ] = ( m, filename ) => {
if ( filename === config ) { if ( filename === config ) {
m._compile( code, filename ); m._compile( code, filename );
} else { } else {
@ -60,25 +62,23 @@ module.exports = function ( command ) {
}; };
try { try {
var options = require( path.resolve( config ) ); const options = require( resolve( config ) );
if ( Object.keys( options ).length === 0 ) { if ( Object.keys( options ).length === 0 ) {
handleError({ code: 'MISSING_CONFIG' }); handleError({ code: 'MISSING_CONFIG' });
} }
execute( options, command );
require.extensions[ '.js' ] = defaultLoader;
} catch ( err ) { } catch ( err ) {
handleError( err ); handleError( err );
} }
execute( options, command );
require.extensions[ '.js' ] = defaultLoader;
}) })
.catch(log); .catch( stderr );
} else { } else {
execute( {}, command ); execute( {}, command );
} }
}; }
var equivalents = { const equivalents = {
banner: 'banner', banner: 'banner',
footer: 'footer', footer: 'footer',
format: 'format', format: 'format',
@ -95,14 +95,14 @@ var equivalents = {
}; };
function execute ( options, command ) { function execute ( options, command ) {
var external = ( options.external || [] ) let external = ( options.external || [] )
.concat( command.external ? command.external.split( ',' ) : [] ); .concat( command.external ? command.external.split( ',' ) : [] );
if ( command.globals ) { if ( command.globals ) {
var globals = Object.create( null ); let globals = Object.create( null );
command.globals.split( ',' ).forEach(function ( str ) { command.globals.split( ',' ).forEach( str => {
var names = str.split( ':' ); const names = str.split( ':' );
globals[ names[0] ] = names[1]; globals[ names[0] ] = names[1];
// Add missing Module IDs to external. // Add missing Module IDs to external.
@ -114,7 +114,7 @@ function execute ( options, command ) {
command.globals = globals; command.globals = globals;
} }
options.onwarn = options.onwarn || log; options.onwarn = options.onwarn || stderr;
options.external = external; options.external = external;
@ -122,7 +122,7 @@ function execute ( options, command ) {
delete command.conflict; delete command.conflict;
// Use any options passed through the CLI as overrides. // Use any options passed through the CLI as overrides.
Object.keys( equivalents ).forEach( function ( cliOption ) { Object.keys( equivalents ).forEach( cliOption => {
if ( command.hasOwnProperty( cliOption ) ) { if ( command.hasOwnProperty( cliOption ) ) {
options[ equivalents[ cliOption ] ] = command[ cliOption ]; options[ equivalents[ cliOption ] ] = command[ cliOption ];
} }
@ -135,25 +135,25 @@ function execute ( options, command ) {
} }
try { try {
var watch = relative( 'rollup-watch', process.cwd() ); const watch = relative( 'rollup-watch', process.cwd() );
var watcher = watch( rollup, options ); const watcher = watch( rollup, options );
watcher.on( 'event', function ( event ) { watcher.on( 'event', event => {
switch ( event.code ) { switch ( event.code ) {
case 'STARTING': case 'STARTING':
console.error( 'checking rollup-watch version...' ); stderr( 'checking rollup-watch version...' );
break; break;
case 'BUILD_START': case 'BUILD_START':
console.error( 'bundling...' ); stderr( 'bundling...' );
break; break;
case 'BUILD_END': case 'BUILD_END':
console.error( 'bundled in ' + event.duration + 'ms. Watching for changes...' ); stderr( 'bundled in ' + event.duration + 'ms. Watching for changes...' );
break; break;
default: default:
console.error( 'unknown event', event ); stderr( 'unknown event', event );
} }
}); });
} catch ( err ) { } catch ( err ) {
@ -176,7 +176,7 @@ function clone ( object ) {
} }
function assign ( target, source ) { function assign ( target, source ) {
Object.keys( source ).forEach( function ( key ) { Object.keys( source ).forEach( key => {
target[ key ] = source[ key ]; target[ key ] = source[ key ];
}); });
return target; return target;
@ -187,15 +187,15 @@ function bundle ( options ) {
handleError({ code: 'MISSING_INPUT_OPTION' }); handleError({ code: 'MISSING_INPUT_OPTION' });
} }
return rollup.rollup( options ).then( function ( bundle ) { return rollup.rollup( options ).then( bundle => {
if ( options.dest ) { if ( options.dest ) {
return bundle.write( options ); return bundle.write( options );
} }
if ( options.targets ) { if ( options.targets ) {
var result = null; let result = null;
options.targets.forEach( function ( target ) { options.targets.forEach( target => {
result = bundle.write( assign( clone( options ), target ) ); result = bundle.write( assign( clone( options ), target ) );
}); });
@ -206,13 +206,10 @@ function bundle ( options ) {
handleError({ code: 'MISSING_OUTPUT_OPTION' }); handleError({ code: 'MISSING_OUTPUT_OPTION' });
} }
var result = bundle.generate( options ); let { code, map } = bundle.generate( options );
var code = result.code,
map = result.map;
if ( options.sourceMap === 'inline' ) { if ( options.sourceMap === 'inline' ) {
code += '\n//# sourceMappingURL=' + map.toUrl(); code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}`;
} }
process.stdout.write( code ); process.stdout.write( code );

4
bin/src/sourceMappingUrl.js

@ -0,0 +1,4 @@
let SOURCEMAPPING_URL = 'sourceMa';
SOURCEMAPPING_URL += 'ppingURL';
export default SOURCEMAPPING_URL;

19
package.json

@ -8,13 +8,14 @@
"rollup": "./bin/rollup" "rollup": "./bin/rollup"
}, },
"scripts": { "scripts": {
"pretest": "npm run build", "pretest": "npm run build && npm run build:cli",
"test": "mocha --compilers js:buble/register", "test": "mocha",
"pretest-coverage": "npm run build", "pretest-coverage": "npm run build",
"test-coverage": "rm -rf coverage/* && istanbul cover --report json node_modules/.bin/_mocha -- -u exports -R spec test/test.js", "test-coverage": "rm -rf coverage/* && istanbul cover --report json node_modules/.bin/_mocha -- -u exports -R spec test/test.js",
"posttest-coverage": "remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.json -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.lcov -t lcovonly -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped -t html -b dist", "posttest-coverage": "remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.json -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.lcov -t lcovonly -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped -t html -b dist",
"ci": "npm run test-coverage && codecov < coverage/coverage-remapped.lcov", "ci": "npm run test-coverage && codecov < coverage/coverage-remapped.lcov",
"build": "git rev-parse HEAD > .commithash && rollup -c -o dist/rollup.js", "build": "git rev-parse HEAD > .commithash && rollup -c -o dist/rollup.js",
"build:cli": "rollup -c rollup.config.cli.js",
"build:browser": "git rev-parse HEAD > .commithash && rollup -c rollup.config.browser.js -o dist/rollup.browser.js", "build:browser": "git rev-parse HEAD > .commithash && rollup -c rollup.config.browser.js -o dist/rollup.browser.js",
"prepublish": "npm run lint && npm test && npm run build:browser", "prepublish": "npm run lint && npm test && npm run build:browser",
"lint": "eslint src browser" "lint": "eslint src browser"
@ -43,33 +44,35 @@
"acorn": "^3.1.0", "acorn": "^3.1.0",
"babel-core": "^5.8.32", "babel-core": "^5.8.32",
"buble": "^0.6.4", "buble": "^0.6.4",
"chalk": "^1.1.1",
"codecov.io": "^0.1.6", "codecov.io": "^0.1.6",
"console-group": "^0.2.0", "console-group": "^0.2.0",
"eslint": "^2.9.0", "eslint": "^2.9.0",
"estree-walker": "^0.2.0", "estree-walker": "^0.2.0",
"istanbul": "^0.4.0", "istanbul": "^0.4.0",
"magic-string": "^0.15.1", "magic-string": "^0.15.1",
"minimist": "^1.2.0",
"mocha": "^2.3.3", "mocha": "^2.3.3",
"remap-istanbul": "^0.5.1", "remap-istanbul": "^0.5.1",
"rollup": "^0.26.2", "require-relative": "^0.8.7",
"rollup": "^0.29.1",
"rollup-plugin-buble": "^0.6.0", "rollup-plugin-buble": "^0.6.0",
"rollup-plugin-commonjs": "^3.0.0",
"rollup-plugin-json": "^2.0.0",
"rollup-plugin-node-resolve": "^1.5.0", "rollup-plugin-node-resolve": "^1.5.0",
"rollup-plugin-replace": "^1.0.1", "rollup-plugin-replace": "^1.0.1",
"rollup-plugin-string": "^1.0.1",
"sander": "^0.5.0", "sander": "^0.5.0",
"source-map": "^0.5.3", "source-map": "^0.5.3",
"sourcemap-codec": "^1.2.1", "sourcemap-codec": "^1.2.1",
"uglify-js": "^2.6.1" "uglify-js": "^2.6.1"
}, },
"dependencies": { "dependencies": {
"chalk": "^1.1.1",
"minimist": "^1.2.0",
"require-relative": "^0.8.7",
"source-map-support": "^0.4.0" "source-map-support": "^0.4.0"
}, },
"files": [ "files": [
"src",
"dist", "dist",
"bin", "bin/rollup",
"README.md" "README.md"
] ]
} }

29
rollup.config.cli.js

@ -0,0 +1,29 @@
import buble from 'rollup-plugin-buble';
import json from 'rollup-plugin-json';
import string from 'rollup-plugin-string';
import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
export default {
entry: 'bin/src/index.js',
dest: 'bin/rollup',
format: 'cjs',
banner: '#!/usr/bin/env node',
plugins: [
string({ extensions: [ '.md' ] }),
json(),
buble(),
commonjs({
include: 'node_modules/**',
namedExports: { 'chalk': [ 'red', 'cyan', 'grey' ] }
}),
nodeResolve({
main: true
})
],
external: [
'path',
'module',
'source-map-support'
]
};

4
rollup.config.js

@ -1,6 +1,6 @@
import { readFileSync } from 'fs'; import { readFileSync } from 'fs';
import buble from 'rollup-plugin-buble'; import buble from 'rollup-plugin-buble';
import npm from 'rollup-plugin-node-resolve'; import nodeResolve from 'rollup-plugin-node-resolve';
import replace from 'rollup-plugin-replace'; import replace from 'rollup-plugin-replace';
var pkg = JSON.parse( readFileSync( 'package.json', 'utf-8' ) ); var pkg = JSON.parse( readFileSync( 'package.json', 'utf-8' ) );
@ -26,7 +26,7 @@ export default {
include: [ 'src/**', 'node_modules/acorn/**' ] include: [ 'src/**', 'node_modules/acorn/**' ]
}), }),
npm({ nodeResolve({
jsnext: true jsnext: true
}), }),

1
test/mocha.opts

@ -0,0 +1 @@
--compilers js:buble/register
Loading…
Cancel
Save