From 16fa05949ea452e838312e034e9d048d0a362d34 Mon Sep 17 00:00:00 2001 From: Theenadayalan Date: Tue, 25 Aug 2020 20:05:54 +0530 Subject: [PATCH 1/5] bump terser from v4.8.0 to v5.2.1 --- lib/process-file.js | 80 ++++++++++++++++++++++----------------------- package.json | 2 +- yarn.lock | 8 ++--- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/lib/process-file.js b/lib/process-file.js index bff4445..9939984 100644 --- a/lib/process-file.js +++ b/lib/process-file.js @@ -5,10 +5,8 @@ const defaults = require('lodash.defaultsdeep'); const fs = require('fs'); const mkdirp = require('mkdirp'); const path = require('path'); -const getSourceMapContent = require('./get-sourcemap-content'); - const terser = require('terser'); - +const getSourceMapContent = require('./get-sourcemap-content'); module.exports = function processFile(inFile, outFile, relativePath, outDir, silent, _options) { let src = fs.readFileSync(inFile, 'utf-8'); @@ -48,45 +46,47 @@ module.exports = function processFile(inFile, outFile, relativePath, outDir, sil let start = new Date(); debug('[starting]: %s %dKB', relativePath, (src.length / 1000)); - let result = terser.minify(src, options); - let end = new Date(); - let total = end - start; - if (total > 20000 && !silent) { - console.warn(`[WARN] (broccoli-uglify-sourcemap) Minifying "${relativePath}" took: ${total}ms (more than 20,000ms)`); - } - if (result.error) { - result.error.filename = relativePath; - throw result.error; - } - - debug('[finished]: %s %dKB in %dms', relativePath, (result.code.length / 1000), total); - - if (options.sourceMap) { - let newSourceMap = JSON.parse(result.map); + return terser.minify(src, options) + .then(result => { + let end = new Date(); + let total = end - start; + if (total > 20000 && !silent) { + console.warn(`[WARN] (broccoli-uglify-sourcemap) Minifying "${relativePath}" took: ${total}ms (more than 20,000ms)`); + } - newSourceMap.sources = newSourceMap.sources.map(function(path) { - if (path === relativePath) { - // If out output file has the same name as one of our original - // sources, they will shadow eachother in Dev Tools. So instead we - // alter the reference to the upstream file. - return path.replace(/\.js$/, '-orig.js'); - } else if (path === '0') { - // In [terser-js](https://github.com/terser-js/terser#source-map-options), - // sources are always 0 if old sourcemaps are not provided. - // The value passed for `sourceMap.url` is only used to set - // `//# sourceMappingURL=out.js.map` in `result.code`. - // The value of `filename` is only used to set `file` attribute - // in source map file. - // In broccoli-uglify-sourcemap we know in this case we are generating - // sourcemap for the file we are processing, changing 0 to the actual - // file gives us the correct source. - return relativePath; + debug('[finished]: %s %dKB in %dms', relativePath, (result.code.length / 1000), total); + + if (options.sourceMap) { + let newSourceMap = JSON.parse(result.map); + + newSourceMap.sources = newSourceMap.sources.map(function(path) { + if (path === relativePath) { + // If out output file has the same name as one of our original + // sources, they will shadow eachother in Dev Tools. So instead we + // alter the reference to the upstream file. + return path.replace(/\.js$/, '-orig.js'); + } else if (path === '0') { + // In [terser-js](https://github.com/terser-js/terser#source-map-options), + // sources are always 0 if old sourcemaps are not provided. + // The value passed for `sourceMap.url` is only used to set + // `//# sourceMappingURL=out.js.map` in `result.code`. + // The value of `filename` is only used to set `file` attribute + // in source map file. + // In broccoli-uglify-sourcemap we know in this case we are generating + // sourcemap for the file we are processing, changing 0 to the actual + // file gives us the correct source. + return relativePath; + } + return path; + }); + mkdirp.sync(mapDir); + fs.writeFileSync(path.join(mapDir, mapName), JSON.stringify(newSourceMap)); } - return path; + fs.writeFileSync(outFile, result.code); + }) + .catch(e => { + e.filename = relativePath; + throw e; }); - mkdirp.sync(mapDir); - fs.writeFileSync(path.join(mapDir, mapName), JSON.stringify(newSourceMap)); - } - fs.writeFileSync(outFile, result.code); }; diff --git a/package.json b/package.json index 3e87d97..17afe6f 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "mkdirp": "^0.5.0", "source-map-url": "^0.4.0", "symlink-or-copy": "^1.3.1", - "terser": "^4.8.0", + "terser": "^5.2.1", "walk-sync": "^1.1.3", "workerpool": "^5.0.4" }, diff --git a/yarn.lock b/yarn.lock index bc476d3..0455dd0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5063,10 +5063,10 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" -terser@^4.8.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" - integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== +terser@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.2.1.tgz#40b971b8d28b4fe98c9e8c0d073ab48e7bb96cd8" + integrity sha512-/AOtjRtAMNGO0fIF6m8HfcvXTw/2AKpsOzDn36tA5RfhRdeXyb4RvHxJ5Pah7iL6dFkLk+gOnCaNHGwJPl6TrQ== dependencies: commander "^2.20.0" source-map "~0.6.1" From 6e8f316c54ced914891b754541c9c9eb918cbb52 Mon Sep 17 00:00:00 2001 From: Theenadayalan Date: Thu, 3 Sep 2020 12:06:54 +0530 Subject: [PATCH 2/5] use async/await --- index.js | 40 ++++++++--------- lib/process-file.js | 80 ++++++++++++++++----------------- test/__snapshots__/test.js.snap | 31 ------------- test/test.js | 47 +++++++++---------- 4 files changed, 79 insertions(+), 119 deletions(-) diff --git a/index.js b/index.js index 17e3460..780c6cd 100644 --- a/index.js +++ b/index.js @@ -43,8 +43,11 @@ function UglifyWriter(inputNodes, options) { }, }); - // consumers of this plugin can opt-in to async and concurrent behavior - this.async = (this.options.async === true); + // async prop is deprecated since terser.minify() is async by default + if ('async' in this.options) { + throw new Error('\n Passing `async` property inside `options` is deprecated.'); + } + this.concurrency = Number(process.env.JOBS) || this.options.concurrency || Math.max(require('os').cpus().length - 1, 1); // create a worker pool using an external worker script @@ -63,10 +66,9 @@ function UglifyWriter(inputNodes, options) { } } -UglifyWriter.prototype.build = function() { +UglifyWriter.prototype.build = async function() { let writer = this; - // when options.async === true, allow processFile() operations to complete asynchronously let pendingWork = []; this.inputPaths.forEach(inputPath => { @@ -84,11 +86,8 @@ UglifyWriter.prototype.build = function() { let uglifyOperation = function() { return writer.processFile(inFile, outFile, relativePath, writer.outputPath); }; - if (writer.async) { - pendingWork.push(uglifyOperation); - return; - } - return uglifyOperation(); + pendingWork.push(uglifyOperation); + return; } else if (relativePath.slice(-4) === '.map') { if (writer.excludes.match(`${relativePath.slice(0, -4)}.{js,mjs}`)) { // ensure .map files for excluded JS paths are also copied forward @@ -101,17 +100,16 @@ UglifyWriter.prototype.build = function() { }); }); - return queue(worker, pendingWork, writer.concurrency) - .then((/* results */) => { - // files are finished processing, shut down the workers - writer.pool.terminate(); - return writer.outputPath; - }) - .catch(e => { - // make sure to shut down the workers on error - writer.pool.terminate(); - throw e; - }); + try { + await queue(worker, pendingWork, writer.concurrency); + // files are finished processing, shut down the workers + writer.pool.terminate(); + return writer.outputPath; + } catch (e) { + // make sure to shut down the workers on error + writer.pool.terminate(); + throw e; + } }; UglifyWriter.prototype._isJSExt = function(relativePath) { @@ -120,7 +118,7 @@ UglifyWriter.prototype._isJSExt = function(relativePath) { UglifyWriter.prototype.processFile = function(inFile, outFile, relativePath, outDir) { // don't run this in the workerpool if concurrency is disabled (can set JOBS <= 1) - if (this.async && this.concurrency > 1) { + if (this.concurrency > 1) { debug('running in workerpool, concurrency=%d', this.concurrency); // each of these arguments is a string, which can be sent to the worker process as-is return this.pool.exec('processFileParallel', [inFile, outFile, relativePath, outDir, silent, this.options]); diff --git a/lib/process-file.js b/lib/process-file.js index 9939984..19e9fc7 100644 --- a/lib/process-file.js +++ b/lib/process-file.js @@ -8,7 +8,7 @@ const path = require('path'); const terser = require('terser'); const getSourceMapContent = require('./get-sourcemap-content'); -module.exports = function processFile(inFile, outFile, relativePath, outDir, silent, _options) { +module.exports = async function processFile(inFile, outFile, relativePath, outDir, silent, _options) { let src = fs.readFileSync(inFile, 'utf-8'); let mapName = `${path.basename(outFile).replace(/\.js$/, '')}.map`; @@ -47,46 +47,46 @@ module.exports = function processFile(inFile, outFile, relativePath, outDir, sil let start = new Date(); debug('[starting]: %s %dKB', relativePath, (src.length / 1000)); - return terser.minify(src, options) - .then(result => { - let end = new Date(); - let total = end - start; - if (total > 20000 && !silent) { - console.warn(`[WARN] (broccoli-uglify-sourcemap) Minifying "${relativePath}" took: ${total}ms (more than 20,000ms)`); - } + try { + let result = await terser.minify(src, options); + let end = new Date(); + let total = end - start; - debug('[finished]: %s %dKB in %dms', relativePath, (result.code.length / 1000), total); + if (total > 20000 && !silent) { + console.warn(`[WARN] (broccoli-uglify-sourcemap) Minifying "${relativePath}" took: ${total}ms (more than 20,000ms)`); + } + + debug('[finished]: %s %dKB in %dms', relativePath, (result.code.length / 1000), total); - if (options.sourceMap) { - let newSourceMap = JSON.parse(result.map); + if (options.sourceMap) { + let newSourceMap = JSON.parse(result.map); - newSourceMap.sources = newSourceMap.sources.map(function(path) { - if (path === relativePath) { - // If out output file has the same name as one of our original - // sources, they will shadow eachother in Dev Tools. So instead we - // alter the reference to the upstream file. - return path.replace(/\.js$/, '-orig.js'); - } else if (path === '0') { - // In [terser-js](https://github.com/terser-js/terser#source-map-options), - // sources are always 0 if old sourcemaps are not provided. - // The value passed for `sourceMap.url` is only used to set - // `//# sourceMappingURL=out.js.map` in `result.code`. - // The value of `filename` is only used to set `file` attribute - // in source map file. - // In broccoli-uglify-sourcemap we know in this case we are generating - // sourcemap for the file we are processing, changing 0 to the actual - // file gives us the correct source. - return relativePath; - } - return path; - }); - mkdirp.sync(mapDir); - fs.writeFileSync(path.join(mapDir, mapName), JSON.stringify(newSourceMap)); - } - fs.writeFileSync(outFile, result.code); - }) - .catch(e => { - e.filename = relativePath; - throw e; - }); + newSourceMap.sources = newSourceMap.sources.map(function(path) { + if (path === relativePath) { + // If out output file has the same name as one of our original + // sources, they will shadow eachother in Dev Tools. So instead we + // alter the reference to the upstream file. + return path.replace(/\.js$/, '-orig.js'); + } else if (path === '0') { + // In [terser-js](https://github.com/terser-js/terser#source-map-options), + // sources are always 0 if old sourcemaps are not provided. + // The value passed for `sourceMap.url` is only used to set + // `//# sourceMappingURL=out.js.map` in `result.code`. + // The value of `filename` is only used to set `file` attribute + // in source map file. + // In broccoli-uglify-sourcemap we know in this case we are generating + // sourcemap for the file we are processing, changing 0 to the actual + // file gives us the correct source. + return relativePath; + } + return path; + }); + mkdirp.sync(mapDir); + fs.writeFileSync(path.join(mapDir, mapName), JSON.stringify(newSourceMap)); + } + fs.writeFileSync(outFile, result.code); + } catch (e) { + e.filename = relativePath; + throw e; + } }; diff --git a/test/__snapshots__/test.js.snap b/test/__snapshots__/test.js.snap index 8da8018..d238c80 100644 --- a/test/__snapshots__/test.js.snap +++ b/test/__snapshots__/test.js.snap @@ -105,35 +105,6 @@ Object { } `; -exports[`broccoli-uglify-sourcemap generates expected output async 1`] = ` -Object { - "inside": Object { - "with-upstream-sourcemap.js": "function meaningOfLife(){throw new Error(42)}function boom(){throw new Error(\\"boom\\")}function somethingElse(){throw new Error(\\"somethign else\\")}function fourth(){throw new Error(\\"fourth\\")}function third(){throw new Error(\\"oh no\\")} -//# sourceMappingURL=with-upstream-sourcemap.map", - "with-upstream-sourcemap.map": "{\\"version\\":3,\\"sources\\":[\\"/inner/first.js\\",\\"/inner/second.js\\",\\"/other/fourth.js\\",\\"/other/third.js\\"],\\"names\\":[\\"meaningOfLife\\",\\"Error\\",\\"boom\\",\\"somethingElse\\",\\"fourth\\",\\"third\\"],\\"mappings\\":\\"AAAA,SAAAA,gBAEA,MAAA,IAAAC,MADA,IAIA,SAAAC,OACA,MAAA,IAAAD,MAAA,QCNA,SAAAE,gBACA,MAAA,IAAAF,MAAA,kBCEA,SAAAG,SACA,MAAA,IAAAH,MAAA,UCJA,SAAAI,QACA,MAAA,IAAAJ,MAAA\\",\\"file\\":\\"with-upstream-sourcemap.js\\",\\"sourcesContent\\":[\\"function meaningOfLife() {\\\\n var thisIsALongLocal = 42;\\\\n throw new Error(thisIsALongLocal);\\\\n}\\\\n\\\\nfunction boom() {\\\\n throw new Error('boom');\\\\n}\\\\n\\",\\"function somethingElse() {\\\\n throw new Error(\\\\\\"somethign else\\\\\\");\\\\n}\\\\n\\",\\"\\\\n// Hello world\\\\n\\\\nfunction fourth(){\\\\n throw new Error('fourth');\\\\n}\\\\n\\",\\"function third(){\\\\n throw new Error(\\\\\\"oh no\\\\\\");\\\\n}\\\\n\\"]}", - }, - "mjs": Object { - "index.mjs": "const MJS_I_GUESS=\\"ok\\";export default\\"ok\\"; -//# sourceMappingURL=index.mjs.map", - "index.mjs.map": "{\\"version\\":3,\\"sources\\":[\\"mjs/index.mjs\\"],\\"names\\":[\\"MJS_I_GUESS\\"],\\"mappings\\":\\"AAAA,MAAMA,YAAc,mBAAA\\",\\"file\\":\\"index.mjs\\"}", - }, - "multi": Object { - "with-multi-sourcemap.js": "function meaningOfLife(){throw new Error(42)}function boom(){throw new Error(\\"boom\\")}function somethingElse(){throw new Error(\\"somethign else\\")}function fourth(){throw new Error(\\"fourth\\")}function third(){throw new Error(\\"oh no\\")} -//# sourceMappingURL=with-multi-sourcemap.map", - "with-multi-sourcemap.map": "{\\"version\\":3,\\"sources\\":[\\"/inner/first.js\\",\\"/inner/second.js\\",\\"/other/fourth.js\\",\\"/other/third.js\\"],\\"names\\":[\\"meaningOfLife\\",\\"Error\\",\\"boom\\",\\"somethingElse\\",\\"fourth\\",\\"third\\"],\\"mappings\\":\\"AAAA,SAAAA,gBAEA,MAAA,IAAAC,MADA,IAIA,SAAAC,OACA,MAAA,IAAAD,MAAA,QCNA,SAAAE,gBACA,MAAA,IAAAF,MAAA,kBCEA,SAAAG,SACA,MAAA,IAAAH,MAAA,UCJA,SAAAI,QACA,MAAA,IAAAJ,MAAA\\",\\"file\\":\\"with-multi-sourcemap.js\\",\\"sourcesContent\\":[\\"function meaningOfLife() {\\\\n var thisIsALongLocal = 42;\\\\n throw new Error(thisIsALongLocal);\\\\n}\\\\n\\\\nfunction boom() {\\\\n throw new Error('boom');\\\\n}\\\\n\\",\\"function somethingElse() {\\\\n throw new Error(\\\\\\"somethign else\\\\\\");\\\\n}\\\\n\\",\\"\\\\n// Hello world\\\\n\\\\nfunction fourth(){\\\\n throw new Error('fourth');\\\\n}\\\\n\\",\\"function third(){\\\\n throw new Error(\\\\\\"oh no\\\\\\");\\\\n}\\\\n\\"]}", - }, - "no-upstream-sourcemap.js": "function meaningOfLife(){throw new Error(42)}function boom(){throw new Error(\\"boom\\")}function somethingElse(){throw new Error(\\"somethign else\\")}function fourth(){throw new Error(\\"fourth\\")}function third(){throw new Error(\\"oh no\\")} -//# sourceMappingURL=no-upstream-sourcemap.map", - "no-upstream-sourcemap.map": "{\\"version\\":3,\\"sources\\":[\\"no-upstream-sourcemap.js\\"],\\"names\\":[\\"meaningOfLife\\",\\"Error\\",\\"boom\\",\\"somethingElse\\",\\"fourth\\",\\"third\\"],\\"mappings\\":\\"AACA,SAASA,gBAEP,MAAM,IAAIC,MADa,IAIzB,SAASC,OACP,MAAM,IAAID,MAAM,QAGlB,SAASE,gBACP,MAAM,IAAIF,MAAM,kBAMlB,SAASG,SACP,MAAM,IAAIH,MAAM,UAGlB,SAASI,QACP,MAAM,IAAIJ,MAAM\\",\\"file\\":\\"no-upstream-sourcemap.js\\"}", - "something.css": "#id { - background: white; -}", - "with-broken-sourcemap.js": "function meaningOfLife(){throw new Error(42)} -//# sourceMappingURL=with-broken-sourcemap.map", - "with-broken-sourcemap.map": "{\\"version\\":3,\\"sources\\":[\\"with-broken-sourcemap.js\\"],\\"names\\":[\\"meaningOfLife\\",\\"Error\\"],\\"mappings\\":\\"AAAA,SAASA,gBAEP,MAAM,IAAIC,MADa\\",\\"file\\":\\"with-broken-sourcemap.js\\"}", -} -`; - exports[`broccoli-uglify-sourcemap mjs can uglify .mjs files 1`] = ` Object { "inside": Object { @@ -165,8 +136,6 @@ Object { exports[`broccoli-uglify-sourcemap on error rejects with BuildError 1`] = `Object {}`; -exports[`broccoli-uglify-sourcemap on error rejects with BuildError async 1`] = `Object {}`; - exports[`broccoli-uglify-sourcemap on error shuts down the workerpool 1`] = `Object {}`; exports[`broccoli-uglify-sourcemap shuts down the workerpool 1`] = ` diff --git a/test/test.js b/test/test.js index efcc26c..079127c 100644 --- a/test/test.js +++ b/test/test.js @@ -27,14 +27,6 @@ describe('broccoli-uglify-sourcemap', function() { expect(builder.read()).toMatchSnapshot(); }); - it('generates expected output async', async function() { - builder = createBuilder(new Uglify(fixtures, { async: true })); - - await builder.build(); - - expect(builder.read()).toMatchSnapshot(); - }); - it('can handle ES6 code', async function() { input.write({ 'es6.js': `class Foo { @@ -97,7 +89,7 @@ let { bar } = Foo.prototype;`, }); it('shuts down the workerpool', async function() { - let testUglify = new Uglify(fixtures, { async: true }); + let testUglify = new Uglify(fixtures); builder = createBuilder(testUglify); await builder.build(); @@ -108,20 +100,7 @@ let { bar } = Foo.prototype;`, describe('on error', function() { it('rejects with BuildError', async function() { - builder = createBuilder(new Uglify(fixturesError, {})); - - let shouldError; - await builder.build() - .catch(err => { - shouldError = err; - }); - expect(shouldError.name).toEqual('BuildError'); - - expect(builder.read()).toMatchSnapshot(); - }); - - it('rejects with BuildError async', async function() { - builder = createBuilder(new Uglify(fixturesError, { async: true })); + builder = createBuilder(new Uglify(fixturesError)); let shouldError; await builder.build() @@ -134,7 +113,7 @@ let { bar } = Foo.prototype;`, }); it('shuts down the workerpool', async function() { - let testUglify = new Uglify(fixturesError, { async: true }); + let testUglify = new Uglify(fixturesError); builder = createBuilder(testUglify); await builder.build().catch(() => {}); @@ -150,20 +129,20 @@ let { bar } = Foo.prototype;`, }); it('defaults to CPUs-1 workers', async function() { - let testUglify = new Uglify(fixturesError, { async: true }); + let testUglify = new Uglify(fixturesError); expect(testUglify.concurrency).toEqual(require('os').cpus().length - 1); }); it('sets concurrency using the option', async function() { - let testUglify = new Uglify(fixturesError, { async: true, concurrency: 145 }); + let testUglify = new Uglify(fixturesError, { concurrency: 145 }); expect(testUglify.concurrency).toEqual(145); }); it('overrides concurrency with JOBS env variable', async function() { process.env.JOBS = '7'; - let testUglify = new Uglify(fixturesError, { async: true, concurrency: 145 }); + let testUglify = new Uglify(fixturesError, { concurrency: 145 }); expect(testUglify.concurrency).toEqual(7); }); @@ -179,6 +158,20 @@ let { bar } = Foo.prototype;`, }); }); + describe('deprecation', function() { + it('deprecated async option', async function() { + let shouldError; + try { + builder = createBuilder(new Uglify(fixtures, { async: true })); + } catch (err) { + shouldError = err; + } + + expect(shouldError.name).toEqual('Error'); + expect(shouldError.message).toEqual('async option is deprecated'); + }); + }); + afterEach(async function() { if (input) { await input.dispose(); From ff06ff0a3604b578d96d52b3560854da72d41ff3 Mon Sep 17 00:00:00 2001 From: Theenadayalan Date: Thu, 3 Sep 2020 12:48:25 +0530 Subject: [PATCH 3/5] remove unwanted return --- index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/index.js b/index.js index 780c6cd..e6ae3d7 100644 --- a/index.js +++ b/index.js @@ -87,7 +87,6 @@ UglifyWriter.prototype.build = async function() { return writer.processFile(inFile, outFile, relativePath, writer.outputPath); }; pendingWork.push(uglifyOperation); - return; } else if (relativePath.slice(-4) === '.map') { if (writer.excludes.match(`${relativePath.slice(0, -4)}.{js,mjs}`)) { // ensure .map files for excluded JS paths are also copied forward From a8d945de6dacf5f8577175617f22d77dd96d622a Mon Sep 17 00:00:00 2001 From: Theenadayalan Date: Thu, 3 Sep 2020 12:51:51 +0530 Subject: [PATCH 4/5] test fix --- test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 079127c..c08f5ce 100644 --- a/test/test.js +++ b/test/test.js @@ -168,7 +168,7 @@ let { bar } = Foo.prototype;`, } expect(shouldError.name).toEqual('Error'); - expect(shouldError.message).toEqual('async option is deprecated'); + expect(shouldError.message).toEqual('\n Passing `async` property inside `options` is deprecated.'); }); }); From 32a6426a10141648b4e5a2df008f210446435b55 Mon Sep 17 00:00:00 2001 From: Theenadayalan Date: Fri, 4 Sep 2020 09:46:03 +0530 Subject: [PATCH 5/5] make use of finally in promise --- index.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index e6ae3d7..8855397 100644 --- a/index.js +++ b/index.js @@ -101,13 +101,10 @@ UglifyWriter.prototype.build = async function() { try { await queue(worker, pendingWork, writer.concurrency); - // files are finished processing, shut down the workers - writer.pool.terminate(); return writer.outputPath; - } catch (e) { - // make sure to shut down the workers on error + } finally { + // make sure to shut down the workers on both success and error case writer.pool.terminate(); - throw e; } };