Skip to content

Commit

Permalink
CLI usage updates (#53)
Browse files Browse the repository at this point in the history
* cli usage updates

* implement run

* implement render output, flatten asset output
  • Loading branch information
guybedford authored and rauchg committed Nov 25, 2018
1 parent 7c421d0 commit f544dbd
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 14 deletions.
4 changes: 3 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ together with all its dependencies, gcc-style.
### CLI

```bash
$ ncc input.js -o bundle.js
$ ncc build input.js -o dist
```

Outputs the build of `input.js` into `dist/index.js`.

### Node.js

```js
Expand Down
100 changes: 87 additions & 13 deletions src/cli.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,132 @@
const { resolve } = require("path");
const { resolve, relative, dirname, sep } = require("path");
const args = require("arg")({
"--help": Boolean,
"-h": "--help",
"--external": [String],
"-e": "--external",
"--out": String,
"-o": "--out",
"--no-minify": Boolean,
M: "--no-minify"
M: "--no-minify",
"--quiet": Boolean,
"-q": "--quiet"
});

const usage = `ncc build <input-file> [opts]
const usage = `Usage: ncc <cmd> <opts>
Commands:
build <input-file> [opts]
run <input-file> [opts]
help
version
Options:
-o, --out [file] Output directory for build (defaults to dist)
-M, --no-minify Skip output minification
-e, --external [mod] Skip bundling 'mod'. Can be used many times
-o, --out [file] Output directory (defaults to dist)
-h, --help Show help
-q, --quiet Disable build summaries / non-error outputs
`;

if (args["--help"]) {
console.error(usage);
process.exit(2);
function renderSummary (code, assets, outDir, buildTime) {
if (!outDir.endsWith(sep))
outDir += sep;
const codeSize = Math.round(Buffer.byteLength(code, 'utf8') / 1024);
const assetSizes = Object.create(null);
let maxSize = codeSize;
let maxAssetNameLength = 8; // "index.js".length
for (const asset of Object.keys(assets)) {
const assetSource = assets[asset];
const assetSize = Math.round((assetSource.byteLength || Buffer.byteLength(assetSource, 'utf8')) / 1024);
assetSizes[asset] = assetSize;
if (assetSize > maxSize)
maxSize = assetSize;
if (asset.length > maxAssetNameLength)
maxAssetNameLength = asset.length;
}
const orderedAssets = Object.keys(assets).sort((a, b) => assetSizes[a] > assetSizes[b] ? 1 : -1);

const sizePadding = maxSize.toString().length;

const indexRender = `${codeSize.toString().padStart(sizePadding, ' ')}kB ${outDir}${'index.js'.padEnd(maxAssetNameLength, ' ')} [${buildTime}ms]\n`;

let output = "", first = true;
for (const asset of orderedAssets) {
if (first)
first = false;
else
output += "\n";
if (codeSize < assetSizes[asset])
output += indexRender;
output += `${assetSizes[asset].toString().padStart(sizePadding, ' ')}kB ${outDir}${asset}`
}

if (maxSize === codeSize)
output += (first ? "" : "\n") + indexRender;

return output;
}

if (args._.length === 0) {
console.error(`Error: No command specified\n${usage}`);
process.exit(1);
}

let run = false;
let outDir = args["--out"];

switch (args._[0]) {
case "run":
if (args._.length > 2) {
console.error(`Error: Too many run arguments provided\n${usage}`);
process.exit(1);
}
if (args["--out"]) {
console.error(`Error: --out flag is not compatible with ncc run\n${usage}`);
process.exit(1);
}
outDir = resolve(require("os").tmpdir(), Math.random().toString(16).substr(2));
run = true;

// fallthrough
case "build":
if (args._.length > 2) {
console.error(`Error: Too many build arguments provided\n${usage}`);
process.exit(1);
}

const ncc = require("./index.js")(resolve(args._[1] || "."), {
const startTime = Date.now();
const ncc = require("./index.js")(eval("require.resolve")(resolve(args._[1] || ".")), {
minify: !args["--no-minify"],
externals: args["--external"]
});

ncc.then(({ code, assets }) => {
const outDir = args["--out"] || resolve("dist");
outDir = outDir || resolve("dist");
const fs = require("fs");
const mkdirp = require("mkdirp");
mkdirp.sync(outDir);
fs.writeFileSync(outDir + "/index.js", code);
for (const asset of Object.keys(assets)) {
mkdirp.sync(path.dirname(asset));
mkdirp.sync(dirname(asset));
fs.writeFileSync(outDir + "/" + asset, assets[asset]);
}

if (!args['--quiet'])
console.log(renderSummary(code, assets, run ? '' : relative(process.cwd(), outDir), Date.now() - startTime));

if (run) {
const ps = require("child_process").fork(outDir + "/index.js");
ps.on("close", () => require("rimraf").sync(outDir));
}
});
break;

case "help":
console.error(usage);
process.exit(2);

case "version":
console.log(require('../package.json').version);
break;

default:
console.error(`Error: Invalid command "${args._[0]}"\n${usage}`);
process.exit(1);
Expand Down

0 comments on commit f544dbd

Please sign in to comment.