diff --git a/package.json b/package.json index 742ea5a1..384c69a1 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "firebase": "^5.5.8", "firebase-admin": "^6.3.0", "fontkit": "^1.7.7", + "get-folder-size": "^2.0.0", "glob": "^7.1.3", "got": "^9.3.2", "graphql": "^14.0.2", diff --git a/readme.md b/readme.md index de7b907b..72e505fa 100644 --- a/readme.md +++ b/readme.md @@ -63,7 +63,9 @@ require('@zeit/ncc')('/path/to/input', { minify: true, // default // externals to leave as requires of the build externals: ["externalpackage"], - sourceMap: true // default + sourceMap: true, // default + // provide a custom cache path or disable caching + cache: "./custom/cache/path" | false }).then(({ code, assets }) => { console.log(code); // assets is an object of asset file names to sources diff --git a/src/cli.js b/src/cli.js index 9ea60174..1a2b3a83 100755 --- a/src/cli.js +++ b/src/cli.js @@ -2,14 +2,16 @@ const { resolve, relative, dirname, sep } = require("path"); const glob = require("glob"); const shebangRegEx = require("./utils/shebang"); const rimraf = require("rimraf"); +const crypto = require("crypto"); +const fs = require("fs"); +const mkdirp = require("mkdirp"); const usage = `Usage: ncc Commands: build [opts] run [opts] - cache clean - cache dir + cache clean|dir|size help version @@ -17,6 +19,7 @@ Options: -o, --out [file] Output directory for build (defaults to dist) -M, --no-minify Skip output minification -S, --no-source-map Skip source map output + -C, --no-cache Skip build cache population -e, --external [mod] Skip bundling 'mod'. Can be used many times -q, --quiet Disable build summaries / non-error outputs `; @@ -29,6 +32,8 @@ try { "-e": "--external", "--out": String, "-o": "--out", + "--no-cache": Boolean, + "-C": "--no-cache", "--no-minify": Boolean, "-M": "--no-minify", "--no-source-map": Boolean, @@ -106,14 +111,27 @@ switch (args._[0]) { errFlagNotCompatible(flags[0], "cache"); const cacheDir = require("./utils/ncc-cache-dir"); - if (args._[1] === "dir") { - console.log(cacheDir); - } - else if (args._[1] === "clear") { - rimraf.sync(cacheDir); - } - else { - errInvalidCommand("cache " + args._[1]); + switch (args._[1]) { + case "clean": + rimraf.sync(cacheDir); + break; + case "dir": + console.log(cacheDir); + break; + case "size": + require("get-folder-size")(cacheDir, (err, size) => { + if (err) { + if (err.code === 'ENOENT') { + console.log("0MB"); + return; + } + throw err; + } + console.log(`${(size / 1024 / 1024).toFixed(2)}MB`); + }); + break; + default: + errInvalidCommand("cache " + args._[1]); } break; @@ -126,10 +144,15 @@ switch (args._[0]) { outDir = resolve( require("os").tmpdir(), - Math.random() - .toString(16) - .substr(2) + crypto.createHash('md5').digest(resolve(args._[1] || ".")).toString('hex') ); + if (fs.existsSync(outDir)) { + console.error( + `Error: Application at ${args._[1] || "."} is already running or didn't cleanup after previous run.` + + `To manually clear the last run build, try running "rm -rf ${outDir}".` + ); + process.exit(1); + } run = true; // fallthrough @@ -143,14 +166,13 @@ switch (args._[0]) { { minify: !args["--no-minify"] && !run, externals: args["--external"], - sourceMap: !args["--no-source-map"] + sourceMap: !args["--no-source-map"], + cacheDirectory: args["--no-cache"] ? false : undefined } ); ncc.then( async ({ code, map, assets }) => { outDir = outDir || resolve("dist"); - const fs = require("fs"); - const mkdirp = require("mkdirp"); mkdirp.sync(outDir); // remove all existing ".js" files in the out directory await Promise.all( diff --git a/src/index.js b/src/index.js index 5c5ca63c..d8bfdb21 100644 --- a/src/index.js +++ b/src/index.js @@ -35,10 +35,11 @@ function resolveModule(context, request, callback, forcedExternals = []) { module.exports = async ( entry, { + cache, externals = [], + filename = "index.js", minify = false, - sourceMap = false, - filename = "index.js" + sourceMap = false } = {} ) => { const shebangMatch = fs.readFileSync(resolve.sync(entry)).toString().match(shebangRegEx); @@ -47,9 +48,9 @@ module.exports = async ( const assets = Object.create(null); const compiler = webpack({ entry, - cache: { + cache: cache === false ? undefined : { type: "filesystem", - cacheDirectory: nccCacheDir, + cacheDirectory: typeof cache === 'string' ? cache : nccCacheDir, name: "ncc", version: require('../package.json').version, store: "instant" diff --git a/yarn.lock b/yarn.lock index 1cb80c0c..ea0bf516 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4122,6 +4122,11 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gar@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/gar/-/gar-1.0.3.tgz#cd6e954dff11821697a9ed5852c7ac5f18df02ce" + integrity sha512-zDpwk/l3HbhjVAvdxNUTJFzgXiNy0a7EmE/50XT38o1z+7NJbFhp+8CDsv1Qgy2adBAwUVYlMpIX2fZUbmlUJw== + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -4189,6 +4194,14 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-folder-size@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-folder-size/-/get-folder-size-2.0.0.tgz#f0ecb4aa30ea855e051366714eaabcc41cf9d43f" + integrity sha512-5h4efQY/sHvf9ZuwOan1HgNaRyApKnJjZ1ZdTOPkpTjIHZNqeMTabBU/LLN6lU9jncBwxJKFcG9cuqiGhu47uQ== + dependencies: + gar "^1.0.2" + tiny-each-async "2.0.3" + get-stdin@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" @@ -10446,6 +10459,11 @@ timm@^1.6.1: resolved "https://registry.yarnpkg.com/timm/-/timm-1.6.1.tgz#5f8aafc932248c76caf2c6af60542a32d3c30701" integrity sha512-hqDTYi/bWuDxL2i6T3v6nrvkAQ/1Bc060GSkVEQZp02zTSTB4CHSKsOkliequCftQaNRcjRqUZmpGWs5FfhrNg== +tiny-each-async@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tiny-each-async/-/tiny-each-async-2.0.3.tgz#8ebbbfd6d6295f1370003fbb37162afe5a0a51d1" + integrity sha1-jru/1tYpXxNwAD+7NxYq/loKUdE= + tiny-inflate@^1.0.0, tiny-inflate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.2.tgz#93d9decffc8805bd57eae4310f0b745e9b6fb3a7"