uglifyjs-webpack-plugin
Advanced tools
Comparing version 2.0.1 to 2.1.0
@@ -5,2 +5,21 @@ # Change Log | ||
<a name="2.1.0"></a> | ||
# [2.1.0](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/compare/v2.0.1...v2.1.0) (2018-12-22) | ||
### Bug Fixes | ||
* `chunks` is a `Set` in webpack@5 ([#365](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/365)) ([bf36e21](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/commit/bf36e21)) | ||
* catch `worker-farm` errors ([#380](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/380)) ([aa7a9fc](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/commit/aa7a9fc)) | ||
* dedupe extracted comments ([#383](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/383)) ([beaf1ad](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/commit/beaf1ad)) | ||
* more consistent cache ([#385](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/385)) ([f61439d](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/commit/f61439d)) | ||
* regenerate `contenthash` when assets was minified ([#386](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/386)) ([65a30da](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/commit/65a30da)) | ||
### Features | ||
* `chunkFilter` option for filtering chunks ([#382](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/382)) ([1e58c99](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/commit/1e58c99)) | ||
<a name="2.0.1"></a> | ||
@@ -7,0 +26,0 @@ ## [2.0.1](https://github.com/webpack-contrib/uglifyjs-webpack-plugin/compare/v2.0.0...v2.0.1) (2018-09-18) |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -3,0 +3,0 @@ const plugin = require('./index'); |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -6,46 +6,37 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.default = void 0; | ||
var _crypto = require('crypto'); | ||
var _crypto = _interopRequireDefault(require("crypto")); | ||
var _crypto2 = _interopRequireDefault(_crypto); | ||
var _path = _interopRequireDefault(require("path")); | ||
var _path = require('path'); | ||
var _sourceMap = require("source-map"); | ||
var _path2 = _interopRequireDefault(_path); | ||
var _webpackSources = require("webpack-sources"); | ||
var _sourceMap = require('source-map'); | ||
var _RequestShortener = _interopRequireDefault(require("webpack/lib/RequestShortener")); | ||
var _webpackSources = require('webpack-sources'); | ||
var _ModuleFilenameHelpers = _interopRequireDefault(require("webpack/lib/ModuleFilenameHelpers")); | ||
var _RequestShortener = require('webpack/lib/RequestShortener'); | ||
var _schemaUtils = _interopRequireDefault(require("schema-utils")); | ||
var _RequestShortener2 = _interopRequireDefault(_RequestShortener); | ||
var _serializeJavascript = _interopRequireDefault(require("serialize-javascript")); | ||
var _ModuleFilenameHelpers = require('webpack/lib/ModuleFilenameHelpers'); | ||
var _package = _interopRequireDefault(require("uglify-js/package.json")); | ||
var _ModuleFilenameHelpers2 = _interopRequireDefault(_ModuleFilenameHelpers); | ||
var _options = _interopRequireDefault(require("./options.json")); | ||
var _schemaUtils = require('schema-utils'); | ||
var _TaskRunner = _interopRequireDefault(require("./TaskRunner")); | ||
var _schemaUtils2 = _interopRequireDefault(_schemaUtils); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var _options = require('./options.json'); | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } | ||
var _options2 = _interopRequireDefault(_options); | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
var _TaskRunner = require('./TaskRunner'); | ||
const warningRegex = /\[.+:([0-9]+),([0-9]+)\]/; | ||
var _TaskRunner2 = _interopRequireDefault(_TaskRunner); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
const warningRegex = /\[.+:([0-9]+),([0-9]+)\]/; /* eslint-disable | ||
no-param-reassign | ||
*/ | ||
class UglifyJsPlugin { | ||
constructor(options = {}) { | ||
(0, _schemaUtils2.default)(_options2.default, options, 'UglifyJs Plugin'); | ||
(0, _schemaUtils.default)(_options.default, options, 'UglifyJs Plugin'); | ||
const { | ||
@@ -55,2 +46,3 @@ minify, | ||
test = /\.js(\?.*)?$/i, | ||
chunkFilter = () => true, | ||
warningsFilter = () => true, | ||
@@ -65,5 +57,5 @@ extractComments = false, | ||
} = options; | ||
this.options = { | ||
test, | ||
chunkFilter, | ||
warningsFilter, | ||
@@ -78,3 +70,3 @@ extractComments, | ||
minify, | ||
uglifyOptions: Object.assign({ | ||
uglifyOptions: _objectSpread({ | ||
output: { | ||
@@ -138,5 +130,6 @@ comments: extractComments ? false : /^\**!|@preserve|@license|@cc_on/i | ||
if (original && original.source && original.source !== file && requestShortener) { | ||
({ source } = original); | ||
({ | ||
source | ||
} = original); | ||
warningMessage = `${warningMessage.replace(warningRegex, '')}`; | ||
locationMessage = `[${requestShortener.shorten(original.source)}:${original.line},${original.column}]`; | ||
@@ -161,13 +154,13 @@ } | ||
const optimizeFn = (compilation, chunks, callback) => { | ||
const taskRunner = new _TaskRunner2.default({ | ||
const taskRunner = new _TaskRunner.default({ | ||
cache: this.options.cache, | ||
parallel: this.options.parallel | ||
}); | ||
const processedAssets = new WeakSet(); | ||
const tasks = []; | ||
chunks.reduce((acc, chunk) => acc.concat(chunk.files || []), []).concat(compilation.additionalChunkAssets || []).filter(_ModuleFilenameHelpers2.default.matchObject.bind(null, this.options)).forEach(file => { | ||
const { | ||
chunkFilter | ||
} = this.options; | ||
Array.from(chunks).filter(chunk => chunkFilter && chunkFilter(chunk)).reduce((acc, chunk) => acc.concat(chunk.files || []), []).concat(compilation.additionalChunkAssets || []).filter(_ModuleFilenameHelpers.default.matchObject.bind(null, this.options)).forEach(file => { | ||
let inputSourceMap; | ||
const asset = compilation.assets[file]; | ||
@@ -183,4 +176,6 @@ | ||
if (this.options.sourceMap && asset.sourceAndMap) { | ||
const { source, map } = asset.sourceAndMap(); | ||
const { | ||
source, | ||
map | ||
} = asset.sourceAndMap(); | ||
input = source; | ||
@@ -192,3 +187,2 @@ | ||
inputSourceMap = map; | ||
compilation.warnings.push(new Error(`${file} contains invalid source map`)); | ||
@@ -199,5 +193,5 @@ } | ||
inputSourceMap = null; | ||
} | ||
} // Handling comment extraction | ||
// Handling comment extraction | ||
let commentsFile = false; | ||
@@ -224,13 +218,10 @@ | ||
if (this.options.cache) { | ||
const { outputPath } = compiler; | ||
const defaultCacheKeys = { | ||
// eslint-disable-next-line global-require | ||
'uglify-js': require('uglify-js/package.json').version, | ||
'uglify-js': _package.default.version, | ||
// eslint-disable-next-line global-require | ||
'uglifyjs-webpack-plugin': require('../package.json').version, | ||
'uglifyjs-webpack-plugin-options': this.options, | ||
path: `${outputPath ? `${outputPath}/` : ''}${file}`, | ||
hash: _crypto2.default.createHash('md4').update(input).digest('hex') | ||
hash: _crypto.default.createHash('md4').update(input).digest('hex') | ||
}; | ||
task.cacheKeys = this.options.cacheKeys(defaultCacheKeys, file); | ||
@@ -241,10 +232,8 @@ } | ||
} catch (error) { | ||
compilation.errors.push(UglifyJsPlugin.buildError(error, file, UglifyJsPlugin.buildSourceMap(inputSourceMap), new _RequestShortener2.default(compiler.context))); | ||
compilation.errors.push(UglifyJsPlugin.buildError(error, file, UglifyJsPlugin.buildSourceMap(inputSourceMap), new _RequestShortener.default(compiler.context))); | ||
} | ||
}); | ||
taskRunner.run(tasks, (tasksError, results) => { | ||
if (tasksError) { | ||
compilation.errors.push(tasksError); | ||
return; | ||
@@ -254,5 +243,17 @@ } | ||
results.forEach((data, index) => { | ||
const { file, input, inputSourceMap, commentsFile } = tasks[index]; | ||
const { error, map, code, warnings, extractedComments } = data; | ||
const { | ||
file, | ||
input, | ||
inputSourceMap, | ||
commentsFile | ||
} = tasks[index]; | ||
const { | ||
error, | ||
map, | ||
code, | ||
warnings | ||
} = data; | ||
let { | ||
extractedComments | ||
} = data; | ||
let sourceMap = null; | ||
@@ -262,9 +263,8 @@ | ||
sourceMap = UglifyJsPlugin.buildSourceMap(inputSourceMap); | ||
} | ||
} // Handling results | ||
// Error case: add errors, and go to next file | ||
// Handling results | ||
// Error case: add errors, and go to next file | ||
if (error) { | ||
compilation.errors.push(UglifyJsPlugin.buildError(error, file, sourceMap, new _RequestShortener2.default(compiler.context))); | ||
compilation.errors.push(UglifyJsPlugin.buildError(error, file, sourceMap, new _RequestShortener.default(compiler.context))); | ||
return; | ||
@@ -279,41 +279,47 @@ } | ||
outputSource = new _webpackSources.RawSource(code); | ||
} | ||
} // Write extracted comments to commentsFile | ||
// Write extracted comments to commentsFile | ||
if (commentsFile && extractedComments.length > 0) { | ||
// Add a banner to the original file | ||
if (this.options.extractComments.banner !== false) { | ||
let banner = this.options.extractComments.banner || `For license information please see ${_path2.default.posix.basename(commentsFile)}`; | ||
if (commentsFile in compilation.assets) { | ||
const commentsFileSource = compilation.assets[commentsFile].source(); | ||
extractedComments = extractedComments.filter(comment => !commentsFileSource.includes(comment)); | ||
} | ||
if (typeof banner === 'function') { | ||
banner = banner(commentsFile); | ||
} | ||
if (extractedComments.length > 0) { | ||
// Add a banner to the original file | ||
if (this.options.extractComments.banner !== false) { | ||
let banner = this.options.extractComments.banner || `For license information please see ${_path.default.posix.basename(commentsFile)}`; | ||
if (banner) { | ||
outputSource = new _webpackSources.ConcatSource(`/*! ${banner} */\n`, outputSource); | ||
if (typeof banner === 'function') { | ||
banner = banner(commentsFile); | ||
} | ||
if (banner) { | ||
outputSource = new _webpackSources.ConcatSource(`/*! ${banner} */\n`, outputSource); | ||
} | ||
} | ||
} | ||
const commentsSource = new _webpackSources.RawSource(`${extractedComments.join('\n\n')}\n`); | ||
const commentsSource = new _webpackSources.RawSource(`${extractedComments.join('\n\n')}\n`); | ||
if (commentsFile in compilation.assets) { | ||
// commentsFile already exists, append new comments... | ||
if (compilation.assets[commentsFile] instanceof _webpackSources.ConcatSource) { | ||
compilation.assets[commentsFile].add('\n'); | ||
compilation.assets[commentsFile].add(commentsSource); | ||
if (commentsFile in compilation.assets) { | ||
// commentsFile already exists, append new comments... | ||
if (compilation.assets[commentsFile] instanceof _webpackSources.ConcatSource) { | ||
compilation.assets[commentsFile].add('\n'); | ||
compilation.assets[commentsFile].add(commentsSource); | ||
} else { | ||
compilation.assets[commentsFile] = new _webpackSources.ConcatSource(compilation.assets[commentsFile], '\n', commentsSource); | ||
} | ||
} else { | ||
compilation.assets[commentsFile] = new _webpackSources.ConcatSource(compilation.assets[commentsFile], '\n', commentsSource); | ||
compilation.assets[commentsFile] = commentsSource; | ||
} | ||
} else { | ||
compilation.assets[commentsFile] = commentsSource; | ||
} | ||
} | ||
} // Updating assets | ||
// Updating assets | ||
processedAssets.add(compilation.assets[file] = outputSource); | ||
// Handling warnings | ||
processedAssets.add(compilation.assets[file] = outputSource); // Handling warnings | ||
if (warnings && warnings.length > 0) { | ||
warnings.forEach(warning => { | ||
const builtWarning = UglifyJsPlugin.buildWarning(warning, file, sourceMap, new _RequestShortener2.default(compiler.context), this.options.warningsFilter); | ||
const builtWarning = UglifyJsPlugin.buildWarning(warning, file, sourceMap, new _RequestShortener.default(compiler.context), this.options.warningsFilter); | ||
@@ -326,5 +332,3 @@ if (builtWarning) { | ||
}); | ||
taskRunner.exit(); | ||
callback(); | ||
@@ -334,4 +338,5 @@ }); | ||
const plugin = { name: this.constructor.name }; | ||
const plugin = { | ||
name: this.constructor.name | ||
}; | ||
compiler.hooks.compilation.tap(plugin, compilation => { | ||
@@ -342,7 +347,25 @@ if (this.options.sourceMap) { | ||
const { | ||
mainTemplate, | ||
chunkTemplate | ||
} = compilation; // Regenerate `contenthash` for minified assets | ||
for (const template of [mainTemplate, chunkTemplate]) { | ||
template.hooks.hashForChunk.tap(plugin, hash => { | ||
const data = (0, _serializeJavascript.default)({ | ||
uglifyjs: _package.default.version, | ||
uglifyjsOptions: this.options.uglifyOptions | ||
}); | ||
hash.update('UglifyJsPlugin'); | ||
hash.update(data); | ||
}); | ||
} | ||
compilation.hooks.optimizeChunkAssets.tapAsync(plugin, optimizeFn.bind(this, compilation)); | ||
}); | ||
} | ||
} | ||
exports.default = UglifyJsPlugin; | ||
var _default = UglifyJsPlugin; | ||
exports.default = _default; |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -6,9 +6,12 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.default = void 0; | ||
var _uglifyJs = require('uglify-js'); | ||
var _uglifyJs = _interopRequireDefault(require("uglify-js")); | ||
var _uglifyJs2 = _interopRequireDefault(_uglifyJs); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
const buildUglifyOptions = ({ | ||
@@ -23,12 +26,14 @@ warnings, | ||
ie8, | ||
/* eslint-disable camelcase */ | ||
keep_fnames | ||
/* eslint-enable camelcase */ | ||
} = {}) => ({ | ||
warnings, | ||
parse: Object.assign({}, parse), | ||
compress: typeof compress === 'boolean' ? compress : Object.assign({}, compress), | ||
parse: _objectSpread({}, parse), | ||
compress: typeof compress === 'boolean' ? compress : _objectSpread({}, compress), | ||
// eslint-disable-next-line no-nested-ternary | ||
mangle: mangle == null ? true : typeof mangle === 'boolean' ? mangle : Object.assign({}, mangle), | ||
output: Object.assign({ | ||
mangle: mangle == null ? true : typeof mangle === 'boolean' ? mangle : _objectSpread({}, mangle), | ||
output: _objectSpread({ | ||
shebang: true, | ||
@@ -45,12 +50,8 @@ comments: false, | ||
keep_fnames | ||
}); /* eslint-disable | ||
arrow-body-style | ||
*/ | ||
}); | ||
const buildComments = (options, uglifyOptions, extractedComments) => { | ||
const condition = {}; | ||
const commentsOpts = uglifyOptions.output.comments; | ||
const commentsOpts = uglifyOptions.output.comments; // Use /^\**!|@preserve|@license|@cc_on/i RegExp | ||
// Use /^\**!|@preserve|@license|@cc_on/i RegExp | ||
if (typeof options.extractComments === 'boolean') { | ||
@@ -74,5 +75,5 @@ condition.preserve = commentsOpts; | ||
condition.extract = commentsOpts; | ||
} | ||
} // Ensure that both conditions are functions | ||
// Ensure that both conditions are functions | ||
['preserve', 'extract'].forEach(key => { | ||
@@ -85,6 +86,7 @@ let regexStr; | ||
condition[key] = condition[key] ? () => true : () => false; | ||
break; | ||
break; | ||
case 'function': | ||
break; | ||
case 'string': | ||
@@ -112,2 +114,3 @@ if (condition[key] === 'all') { | ||
break; | ||
default: | ||
@@ -117,10 +120,16 @@ regex = condition[key]; | ||
condition[key] = (astNode, comment) => regex.test(comment.value); | ||
} | ||
}); | ||
}); // Redefine the comments function to extract and preserve | ||
// comments according to the two conditions | ||
// Redefine the comments function to extract and preserve | ||
// comments according to the two conditions | ||
return (astNode, comment) => { | ||
if (condition.extract(astNode, comment)) { | ||
extractedComments.push(comment.type === 'comment2' ? `/*${comment.value}*/` : `//${comment.value}`); | ||
const commentText = comment.type === 'comment2' ? `/*${comment.value}*/` : `//${comment.value}`; // Don't include duplicate comments | ||
if (!extractedComments.includes(commentText)) { | ||
extractedComments.push(commentText); | ||
} | ||
} | ||
@@ -142,9 +151,10 @@ | ||
if (minifyFn) { | ||
return minifyFn({ [file]: input }, inputSourceMap); | ||
} | ||
return minifyFn({ | ||
[file]: input | ||
}, inputSourceMap); | ||
} // Copy uglify options | ||
// Copy uglify options | ||
const uglifyOptions = buildUglifyOptions(options.uglifyOptions); | ||
// Add source map data | ||
const uglifyOptions = buildUglifyOptions(options.uglifyOptions); // Add source map data | ||
if (inputSourceMap) { | ||
@@ -162,7 +172,21 @@ uglifyOptions.sourceMap = { | ||
const { error, map, code, warnings } = _uglifyJs2.default.minify({ [file]: input }, uglifyOptions); | ||
const { | ||
error, | ||
map, | ||
code, | ||
warnings | ||
} = _uglifyJs.default.minify({ | ||
[file]: input | ||
}, uglifyOptions); | ||
return { error, map, code, warnings, extractedComments }; | ||
return { | ||
error, | ||
map, | ||
code, | ||
warnings, | ||
extractedComments | ||
}; | ||
}; | ||
exports.default = minify; | ||
var _default = minify; | ||
exports.default = _default; |
@@ -67,2 +67,5 @@ { | ||
}, | ||
"chunkFilter": { | ||
"instanceof": "Function" | ||
}, | ||
"cache": { | ||
@@ -69,0 +72,0 @@ "anyOf": [ |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -6,27 +6,16 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.default = void 0; | ||
var _os = require('os'); | ||
var _os = _interopRequireDefault(require("os")); | ||
var _os2 = _interopRequireDefault(_os); | ||
var _cacache = _interopRequireDefault(require("cacache")); | ||
var _cacache = require('cacache'); | ||
var _findCacheDir = _interopRequireDefault(require("find-cache-dir")); | ||
var _cacache2 = _interopRequireDefault(_cacache); | ||
var _workerFarm = _interopRequireDefault(require("worker-farm")); | ||
var _findCacheDir = require('find-cache-dir'); | ||
var _serializeJavascript = _interopRequireDefault(require("serialize-javascript")); | ||
var _findCacheDir2 = _interopRequireDefault(_findCacheDir); | ||
var _minify = _interopRequireDefault(require("./minify")); | ||
var _workerFarm = require('worker-farm'); | ||
var _workerFarm2 = _interopRequireDefault(_workerFarm); | ||
var _serializeJavascript = require('serialize-javascript'); | ||
var _serializeJavascript2 = _interopRequireDefault(_serializeJavascript); | ||
var _minify = require('./minify'); | ||
var _minify2 = _interopRequireDefault(_minify); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -38,7 +27,14 @@ | ||
constructor(options = {}) { | ||
const { cache, parallel } = options; | ||
this.cacheDir = cache === true ? (0, _findCacheDir2.default)({ name: 'uglifyjs-webpack-plugin' }) : cache; | ||
// In some cases cpus() returns undefined | ||
const { | ||
cache, | ||
parallel | ||
} = options; | ||
this.cacheDir = cache === true ? (0, _findCacheDir.default)({ | ||
name: 'uglifyjs-webpack-plugin' | ||
}) : cache; // In some cases cpus() returns undefined | ||
// https://github.com/nodejs/node/issues/19022 | ||
const cpus = _os2.default.cpus() || { length: 1 }; | ||
const cpus = _os.default.cpus() || { | ||
length: 1 | ||
}; | ||
this.maxConcurrentWorkers = parallel === true ? cpus.length - 1 : Math.min(Number(parallel) || 0, cpus.length - 1); | ||
@@ -58,9 +54,19 @@ } | ||
maxConcurrentCallsPerWorker: 1 | ||
} : { maxConcurrentWorkers: this.maxConcurrentWorkers }; | ||
this.workers = (0, _workerFarm2.default)(workerOptions, workerFile); | ||
this.boundWorkers = (options, cb) => this.workers((0, _serializeJavascript2.default)(options), cb); | ||
} : { | ||
maxConcurrentWorkers: this.maxConcurrentWorkers | ||
}; | ||
this.workers = (0, _workerFarm.default)(workerOptions, workerFile); | ||
this.boundWorkers = (options, cb) => { | ||
try { | ||
this.workers((0, _serializeJavascript.default)(options), cb); | ||
} catch (error) { | ||
// worker-farm can fail with ENOMEM or something else | ||
cb(error); | ||
} | ||
}; | ||
} else { | ||
this.boundWorkers = (options, cb) => { | ||
try { | ||
cb(null, (0, _minify2.default)(options)); | ||
cb(null, (0, _minify.default)(options)); | ||
} catch (error) { | ||
@@ -74,2 +80,3 @@ cb(error); | ||
const results = []; | ||
const step = (index, data) => { | ||
@@ -87,7 +94,10 @@ toRun -= 1; | ||
this.boundWorkers(task, (error, data) => { | ||
const result = error ? { error } : data; | ||
const result = error ? { | ||
error | ||
} : data; | ||
const done = () => step(index, result); | ||
if (this.cacheDir && !result.error) { | ||
_cacache2.default.put(this.cacheDir, (0, _serializeJavascript2.default)(task.cacheKeys), JSON.stringify(data)).then(done, done); | ||
_cacache.default.put(this.cacheDir, (0, _serializeJavascript.default)(task.cacheKeys), JSON.stringify(data)).then(done, done); | ||
} else { | ||
@@ -100,3 +110,5 @@ done(); | ||
if (this.cacheDir) { | ||
_cacache2.default.get(this.cacheDir, (0, _serializeJavascript2.default)(task.cacheKeys)).then(({ data }) => step(index, JSON.parse(data)), enqueue); | ||
_cacache.default.get(this.cacheDir, (0, _serializeJavascript.default)(task.cacheKeys)).then(({ | ||
data | ||
}) => step(index, JSON.parse(data)), enqueue); | ||
} else { | ||
@@ -110,6 +122,8 @@ enqueue(); | ||
if (this.workers) { | ||
_workerFarm2.default.end(this.workers); | ||
_workerFarm.default.end(this.workers); | ||
} | ||
} | ||
} | ||
exports.default = TaskRunner; |
@@ -1,7 +0,5 @@ | ||
'use strict'; | ||
"use strict"; | ||
var _minify = require('./minify'); | ||
var _minify = _interopRequireDefault(require("./minify")); | ||
var _minify2 = _interopRequireDefault(_minify); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -15,4 +13,3 @@ | ||
options = new Function('exports', 'require', 'module', '__filename', '__dirname', `'use strict'\nreturn ${options}`)(exports, require, module, __filename, __dirname); | ||
callback(null, (0, _minify2.default)(options)); | ||
callback(null, (0, _minify.default)(options)); | ||
} catch (errors) { | ||
@@ -19,0 +16,0 @@ callback(errors); |
{ | ||
"name": "uglifyjs-webpack-plugin", | ||
"version": "2.0.1", | ||
"version": "2.1.0", | ||
"description": "UglifyJS plugin for webpack", | ||
@@ -10,6 +10,5 @@ "license": "MIT", | ||
"bugs": "https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues", | ||
"bin": "", | ||
"main": "dist/cjs.js", | ||
"engines": { | ||
"node": ">= 6.9.0 <7.0.0 || >= 8.9.0" | ||
"node": ">= 6.9.0" | ||
}, | ||
@@ -23,9 +22,5 @@ "scripts": { | ||
"lint": "eslint --cache src test", | ||
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}", | ||
"lint-staged": "lint-staged", | ||
"prebuild": "npm run clean", | ||
"prepare": "npm run build", | ||
"prepublish": "npm run build", | ||
"release": "standard-version", | ||
"release:ci": "conventional-github-releaser -p angular", | ||
"release:validate": "commitlint --from=$(git describe --tags --abbrev=0) --to=$(git rev-parse HEAD)", | ||
"security": "npm audit", | ||
@@ -38,2 +33,3 @@ "test": "jest", | ||
"ci:coverage": "npm run test:coverage -- --runInBand", | ||
"ci:lint:commits": "commitlint --from=origin/master --to=${CIRCLE_SHA1}", | ||
"defaults": "webpack-defaults" | ||
@@ -45,3 +41,3 @@ }, | ||
"peerDependencies": { | ||
"webpack": "^4.3.0" | ||
"webpack": "^4.0.0" | ||
}, | ||
@@ -59,10 +55,12 @@ "dependencies": { | ||
"devDependencies": { | ||
"@babel/cli": "^7.2.0", | ||
"@babel/core": "^7.2.2", | ||
"@babel/polyfill": "^7.0.0", | ||
"@babel/preset-env": "^7.2.0", | ||
"@commitlint/cli": "^7.1.2", | ||
"@commitlint/config-conventional": "^7.1.2", | ||
"@webpack-contrib/eslint-config-webpack": "^2.0.4", | ||
"babel-cli": "^6.26.0", | ||
"@webpack-contrib/defaults": "^3.0.0", | ||
"@webpack-contrib/eslint-config-webpack": "^3.0.0", | ||
"babel-core": "^7.0.0-bridge.0", | ||
"babel-jest": "^23.4.2", | ||
"babel-plugin-transform-object-rest-spread": "^6.26.0", | ||
"babel-polyfill": "^6.26.0", | ||
"babel-preset-env": "^1.6.1", | ||
"conventional-github-releaser": "^3.1.2", | ||
@@ -75,13 +73,11 @@ "cross-env": "^5.1.3", | ||
"eslint-plugin-import": "^2.8.0", | ||
"eslint-plugin-prettier": "^2.6.2", | ||
"husky": "^0.14.3", | ||
"eslint-plugin-prettier": "^3.0.0", | ||
"husky": "^1.2.1", | ||
"jest": "^23.5.0", | ||
"lint-staged": "^7.2.2", | ||
"lint-staged": "^8.1.0", | ||
"memory-fs": "^0.4.1", | ||
"pre-commit": "^1.2.2", | ||
"prettier": "^1.14.2", | ||
"standard-version": "^4.3.0", | ||
"terser": "^3.7.6", | ||
"webpack": "^4.17.2", | ||
"webpack-defaults": "^2.3.0" | ||
"webpack": "^4.17.2" | ||
}, | ||
@@ -95,6 +91,20 @@ "keywords": [ | ||
], | ||
"jest": { | ||
"testEnvironment": "node" | ||
"babel": { | ||
"presets": [ | ||
[ | ||
"@babel/preset-env", | ||
{ | ||
"targets": { | ||
"node": "6.9.0" | ||
}, | ||
"useBuiltIns": "usage" | ||
} | ||
] | ||
] | ||
}, | ||
"pre-commit": "lint-staged", | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
}, | ||
"lint-staged": { | ||
@@ -105,3 +115,8 @@ "*.js": [ | ||
] | ||
}, | ||
"commitlint": { | ||
"extends": [ | ||
"@commitlint/config-conventional" | ||
] | ||
} | ||
} |
551
README.md
@@ -39,6 +39,5 @@ <div align="center"> | ||
module.exports = { | ||
//... | ||
optimization: { | ||
minimizer: [new UglifyJsPlugin()] | ||
} | ||
minimizer: [new UglifyJsPlugin()], | ||
}, | ||
}; | ||
@@ -58,7 +57,14 @@ ``` | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
test: /\.js(\?.*)?$/i | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
test: /\.js(\?.*)?$/i, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -73,7 +79,14 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
include: /\/includes/ | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
include: /\/includes/, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -88,9 +101,45 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
exclude: /\/excludes/ | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
exclude: /\/excludes/, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
### `chunkFilter` | ||
Type: `Function<(chunk) -> boolean>` | ||
Default: `() => true` | ||
Allowing to filter which chunks should be uglified (by default all chunks are uglified). | ||
Return `true` to uglify the chunk, `false` otherwise. | ||
**webpack.config.js** | ||
```js | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
chunkFilter: (chunk) => { | ||
// Exclude uglification for the `vendor` chunk | ||
if (chunk.name === 'vendor') { | ||
return false; | ||
} | ||
return true; | ||
} | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
### `cache` | ||
@@ -101,3 +150,3 @@ | ||
Enable file caching. | ||
Enable file caching. | ||
Default path to cache directory: `node_modules/.cache/uglifyjs-webpack-plugin`. | ||
@@ -111,7 +160,14 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
cache: true | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
cache: true, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -125,7 +181,14 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
cache: 'path/to/cache' | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
cache: 'path/to/cache', | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -148,16 +211,26 @@ | ||
path: compiler.outputPath ? `${compiler.outputPath}/${file}` : file, // asset path | ||
hash: crypto.createHash('md4').update(input).digest('hex'), // source file hash | ||
hash: crypto | ||
.createHash('md4') | ||
.update(input) | ||
.digest('hex'), // source file hash | ||
}); | ||
``` | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
cache: true, | ||
cacheKeys: (defaultCacheKeys, file) => { | ||
defaultCacheKeys.myCacheKey = 'myCacheKeyValue'; | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
cache: true, | ||
cacheKeys: (defaultCacheKeys, file) => { | ||
defaultCacheKeys.myCacheKey = 'myCacheKeyValue'; | ||
return defaultCacheKeys; | ||
return defaultCacheKeys; | ||
}, | ||
}), | ||
], | ||
}, | ||
}) | ||
}; | ||
``` | ||
@@ -170,3 +243,3 @@ | ||
Use multi-process parallel running to improve the build speed. | ||
Use multi-process parallel running to improve the build speed. | ||
Default number of concurrent runs: `os.cpus().length - 1`. | ||
@@ -180,7 +253,14 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
parallel: true | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
parallel: true, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -192,7 +272,14 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
parallel: 4 | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
parallel: 4, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -210,7 +297,14 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
sourceMap: true | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
sourceMap: true, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -223,3 +317,3 @@ | ||
Allows you to override default minify function. | ||
Allows you to override default minify function. | ||
By default plugin uses [uglify-js](https://github.com/mishoo/UglifyJS2) package. | ||
@@ -230,18 +324,25 @@ Useful for using and testing unpublished versions or forks. | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
minify(file, sourceMap) { | ||
const extractedComments = []; | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
minify(file, sourceMap) { | ||
const extractedComments = []; | ||
// Custom logic for extract comments | ||
// Custom logic for extract comments | ||
const { error, map, code, warnings } = require('uglify-module') // Or require('./path/to/uglify-module') | ||
.minify(file, { | ||
/* Your options for minification */ | ||
}); | ||
const { error, map, code, warnings } = require('uglify-module') // Or require('./path/to/uglify-module') | ||
.minify(file, { | ||
/* Your options for minification */ | ||
}); | ||
return { error, map, code, warnings, extractedComments }; | ||
} | ||
}) | ||
return { error, map, code, warnings, extractedComments }; | ||
}, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -254,19 +355,26 @@ | ||
UglifyJS minify options. | ||
UglifyJS minify [options](https://github.com/mishoo/UglifyJS2#minify-options). | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
uglifyOptions: { | ||
warnings: false, | ||
parse: {}, | ||
compress: {}, | ||
mangle: true, // Note `mangle.properties` is `false` by default. | ||
output: null, | ||
toplevel: false, | ||
nameCache: null, | ||
ie8: false, | ||
keep_fnames: false, | ||
} | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
uglifyOptions: { | ||
warnings: false, | ||
parse: {}, | ||
compress: {}, | ||
mangle: true, // Note `mangle.properties` is `false` by default. | ||
output: null, | ||
toplevel: false, | ||
nameCache: null, | ||
ie8: false, | ||
keep_fnames: false, | ||
}, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -288,7 +396,14 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
extractComments: true | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
extractComments: true, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -300,7 +415,14 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
extractComments: 'all' | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
extractComments: 'all', | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -310,9 +432,16 @@ | ||
All comments that match the given expression will be extracted to the separate file. | ||
All comments that match the given expression will be extracted to the separate file. | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
extractComments: /@extract/i | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
extractComments: /@extract/i, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -322,15 +451,22 @@ | ||
All comments that match the given expression will be extracted to the separate file. | ||
All comments that match the given expression will be extracted to the separate file. | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
extractComments: function (astNode, comment) { | ||
if (/@extract/i.test(comment.value)) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
extractComments: function(astNode, comment) { | ||
if (/@extract/i.test(comment.value)) { | ||
return true; | ||
} | ||
return false; | ||
}, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -342,15 +478,22 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
extractComments: { | ||
condition: /^\**!|@preserve|@license|@cc_on/i, | ||
filename(file) { | ||
return `${file}.LICENSE`; | ||
}, | ||
banner(licenseFile) { | ||
return `License information can be found in ${licenseFile}`; | ||
} | ||
} | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
extractComments: { | ||
condition: /^\**!|@preserve|@license|@cc_on/i, | ||
filename(file) { | ||
return `${file}.LICENSE`; | ||
}, | ||
banner(licenseFile) { | ||
return `License information can be found in ${licenseFile}`; | ||
}, | ||
}, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -364,15 +507,22 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
extractComments: { | ||
condition: 'some', | ||
filename(file) { | ||
return `${file}.LICENSE`; | ||
}, | ||
banner(licenseFile) { | ||
return `License information can be found in ${licenseFile}`; | ||
} | ||
} | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
extractComments: { | ||
condition: 'some', | ||
filename(file) { | ||
return `${file}.LICENSE`; | ||
}, | ||
banner(licenseFile) { | ||
return `License information can be found in ${licenseFile}`; | ||
}, | ||
}, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -388,13 +538,20 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
extractComments: { | ||
condition: /^\**!|@preserve|@license|@cc_on/i, | ||
filename: 'extracted-comments.js', | ||
banner(licenseFile) { | ||
return `License information can be found in ${licenseFile}`; | ||
} | ||
} | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
extractComments: { | ||
condition: /^\**!|@preserve|@license|@cc_on/i, | ||
filename: 'extracted-comments.js', | ||
banner(licenseFile) { | ||
return `License information can be found in ${licenseFile}`; | ||
}, | ||
}, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -407,19 +564,26 @@ | ||
The banner text that points to the extracted file and will be added on top of the original file. | ||
Can be `false` (no banner), a `String`, or a `Function<(string) -> String>` that will be called with the filename where extracted comments have been stored. | ||
The banner text that points to the extracted file and will be added on top of the original file. | ||
Can be `false` (no banner), a `String`, or a `Function<(string) -> String>` that will be called with the filename where extracted comments have been stored. | ||
Will be wrapped into comment. | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
extractComments: { | ||
condition: true, | ||
filename(file) { | ||
return `${file}.LICENSE`; | ||
}, | ||
banner(commentsFile) { | ||
return `My custom banner about license information ${commentsFile}`; | ||
} | ||
} | ||
}) | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
extractComments: { | ||
condition: true, | ||
filename(file) { | ||
return `${file}.LICENSE`; | ||
}, | ||
banner(commentsFile) { | ||
return `My custom banner about license information ${commentsFile}`; | ||
}, | ||
}, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
@@ -435,17 +599,24 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
new UglifyJsPlugin({ | ||
warningsFilter: (warning, source) => { | ||
if (/Dropping unreachable code/i.test(warning)) { | ||
return true; | ||
} | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
warningsFilter: (warning, source) => { | ||
if (/Dropping unreachable code/i.test(warning)) { | ||
return true; | ||
} | ||
if (/filename\.js/i.test(source)) { | ||
return true; | ||
} | ||
if (/filename\.js/i.test(source)) { | ||
return true; | ||
} | ||
return false; | ||
return false; | ||
}, | ||
}), | ||
], | ||
}, | ||
}) | ||
}; | ||
``` | ||
@@ -459,8 +630,6 @@ | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); | ||
module.exports = { | ||
//... | ||
optimization: { | ||
@@ -470,6 +639,6 @@ minimizer: [ | ||
cache: true, | ||
parallel: true | ||
}) | ||
] | ||
} | ||
parallel: true, | ||
}), | ||
], | ||
}, | ||
}; | ||
@@ -482,8 +651,29 @@ ``` | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); | ||
module.exports = { | ||
optimization: { | ||
minimizer: [ | ||
new UglifyJsPlugin({ | ||
uglifyOptions: { | ||
output: { | ||
comments: /@license/i, | ||
}, | ||
}, | ||
extractComments: true, | ||
}), | ||
], | ||
}, | ||
}; | ||
``` | ||
### Remove Comments | ||
If you avoid building with comments, set **uglifyOptions.output.comments** to **false** as in this config: | ||
**webpack.config.js** | ||
```js | ||
module.exports = { | ||
//... | ||
optimization: { | ||
@@ -494,9 +684,8 @@ minimizer: [ | ||
output: { | ||
comments: /@license/i | ||
} | ||
comments: false, | ||
}, | ||
}, | ||
extractComments: true | ||
}) | ||
] | ||
} | ||
}), | ||
], | ||
}, | ||
}; | ||
@@ -509,8 +698,6 @@ ``` | ||
**webpack.config.js** | ||
```js | ||
// in your webpack.config.js | ||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); | ||
module.exports = { | ||
//... | ||
optimization: { | ||
@@ -535,3 +722,3 @@ minimizer: [ | ||
}; | ||
if (sourceMap) { | ||
@@ -542,8 +729,8 @@ uglifyJsOptions.sourceMap = { | ||
} | ||
return require('terser').minify(file, uglifyJsOptions); | ||
}, | ||
}) | ||
] | ||
} | ||
}), | ||
], | ||
}, | ||
}; | ||
@@ -550,0 +737,0 @@ ``` |
63648
715
732