Socket
Socket
Sign inDemoInstall

terser-webpack-plugin

Package Overview
Dependencies
290
Maintainers
1
Versions
77
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.0 to 1.2.0

20

CHANGELOG.md

@@ -5,2 +5,22 @@ # Change Log

<a name="1.2.0"></a>
# [1.2.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.1.0...v1.2.0) (2018-12-22)
### Bug Fixes
* `chunks` is a `Set` in webpack@5 ([#19](https://github.com/webpack-contrib/terser-webpack-plugin/issues/19)) ([df8c425](https://github.com/webpack-contrib/terser-webpack-plugin/commit/df8c425))
* catch `work-farm` errors ([#35](https://github.com/webpack-contrib/terser-webpack-plugin/issues/35)) ([2bdcd38](https://github.com/webpack-contrib/terser-webpack-plugin/commit/2bdcd38))
* dedupe extracted comments ([#40](https://github.com/webpack-contrib/terser-webpack-plugin/issues/40)) ([7f4a159](https://github.com/webpack-contrib/terser-webpack-plugin/commit/7f4a159))
* more consistent cache ([#43](https://github.com/webpack-contrib/terser-webpack-plugin/issues/43)) ([36f5f3c](https://github.com/webpack-contrib/terser-webpack-plugin/commit/36f5f3c))
* regenerate `contenthash` when assets was uglified ([#44](https://github.com/webpack-contrib/terser-webpack-plugin/issues/44)) ([7e6f8b1](https://github.com/webpack-contrib/terser-webpack-plugin/commit/7e6f8b1))
### Features
* `chunkFilter` option for filtering chunks ([#38](https://github.com/webpack-contrib/terser-webpack-plugin/issues/38)) ([7ffe57c](https://github.com/webpack-contrib/terser-webpack-plugin/commit/7ffe57c))
* uglify `mjs` by default ([#39](https://github.com/webpack-contrib/terser-webpack-plugin/issues/39)) ([1644620](https://github.com/webpack-contrib/terser-webpack-plugin/commit/1644620))
<a name="1.1.0"></a>

@@ -7,0 +27,0 @@ # [1.1.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.0.1...v1.1.0) (2018-09-14)

2

dist/cjs.js

@@ -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,50 +6,42 @@ 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("terser/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 TerserPlugin {
constructor(options = {}) {
(0, _schemaUtils2.default)(_options2.default, options, 'Terser Plugin');
(0, _schemaUtils.default)(_options.default, options, 'Terser Plugin');
const {
minify,
terserOptions = {},
test = /\.js(\?.*)?$/i,
test = /\.m?js(\?.*)?$/i,
chunkFilter = () => true,
warningsFilter = () => true,

@@ -64,5 +56,5 @@ extractComments = false,

} = options;
this.options = {
test,
chunkFilter,
warningsFilter,

@@ -77,3 +69,3 @@ extractComments,

minify,
terserOptions: Object.assign({
terserOptions: _objectSpread({
output: {

@@ -137,5 +129,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}]`;

@@ -160,13 +153,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];

@@ -182,4 +175,6 @@

if (this.options.sourceMap && asset.sourceAndMap) {
const { source, map } = asset.sourceAndMap();
const {
source,
map
} = asset.sourceAndMap();
input = source;

@@ -191,3 +186,2 @@

inputSourceMap = map;
compilation.warnings.push(new Error(`${file} contains invalid source map`));

@@ -198,5 +192,5 @@ }

inputSourceMap = null;
}
} // Handling comment extraction
// Handling comment extraction
let commentsFile = false;

@@ -223,13 +217,9 @@

if (this.options.cache) {
const { outputPath } = compiler;
const defaultCacheKeys = {
terser: _package.default.version,
// eslint-disable-next-line global-require
terser: require('terser/package.json').version,
// eslint-disable-next-line global-require
'terser-webpack-plugin': require('../package.json').version,
'terser-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);

@@ -240,10 +230,8 @@ }

} catch (error) {
compilation.errors.push(TerserPlugin.buildError(error, file, TerserPlugin.buildSourceMap(inputSourceMap), new _RequestShortener2.default(compiler.context)));
compilation.errors.push(TerserPlugin.buildError(error, file, TerserPlugin.buildSourceMap(inputSourceMap), new _RequestShortener.default(compiler.context)));
}
});
taskRunner.run(tasks, (tasksError, results) => {
if (tasksError) {
compilation.errors.push(tasksError);
return;

@@ -253,5 +241,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;

@@ -261,9 +261,8 @@

sourceMap = TerserPlugin.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(TerserPlugin.buildError(error, file, sourceMap, new _RequestShortener2.default(compiler.context)));
compilation.errors.push(TerserPlugin.buildError(error, file, sourceMap, new _RequestShortener.default(compiler.context)));
return;

@@ -278,41 +277,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 = TerserPlugin.buildWarning(warning, file, sourceMap, new _RequestShortener2.default(compiler.context), this.options.warningsFilter);
const builtWarning = TerserPlugin.buildWarning(warning, file, sourceMap, new _RequestShortener.default(compiler.context), this.options.warningsFilter);

@@ -325,5 +330,3 @@ if (builtWarning) {

});
taskRunner.exit();
callback();

@@ -333,4 +336,5 @@ });

const plugin = { name: this.constructor.name };
const plugin = {
name: this.constructor.name
};
compiler.hooks.compilation.tap(plugin, compilation => {

@@ -341,7 +345,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)({
terser: _package.default.version,
terserOptions: this.options.terserOptions
});
hash.update('TerserPlugin');
hash.update(data);
});
}
compilation.hooks.optimizeChunkAssets.tapAsync(plugin, optimizeFn.bind(this, compilation));
});
}
}
exports.default = TerserPlugin;
var _default = TerserPlugin;
exports.default = _default;

@@ -1,2 +0,2 @@

'use strict';
"use strict";

@@ -6,9 +6,12 @@ Object.defineProperty(exports, "__esModule", {

});
exports.default = void 0;
var _terser = require('terser');
var _terser = _interopRequireDefault(require("terser"));
var _terser2 = _interopRequireDefault(_terser);
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 buildTerserOptions = ({

@@ -25,5 +28,7 @@ ecma,

ie8,
/* eslint-disable camelcase */
keep_classnames,
keep_fnames,
/* eslint-enable camelcase */

@@ -34,7 +39,7 @@ safari10

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,

@@ -54,12 +59,8 @@ comments: false,

safari10
}); /* eslint-disable
arrow-body-style
*/
});
const buildComments = (options, terserOptions, extractedComments) => {
const condition = {};
const commentsOpts = terserOptions.output.comments;
const commentsOpts = terserOptions.output.comments; // Use /^\**!|@preserve|@license|@cc_on/i RegExp
// Use /^\**!|@preserve|@license|@cc_on/i RegExp
if (typeof options.extractComments === 'boolean') {

@@ -83,5 +84,5 @@ condition.preserve = commentsOpts;

condition.extract = commentsOpts;
}
} // Ensure that both conditions are functions
// Ensure that both conditions are functions
['preserve', 'extract'].forEach(key => {

@@ -94,6 +95,7 @@ let regexStr;

condition[key] = condition[key] ? () => true : () => false;
break;
break;
case 'function':
break;
case 'string':

@@ -121,2 +123,3 @@ if (condition[key] === 'all') {

break;
default:

@@ -126,10 +129,14 @@ 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);
}
}

@@ -151,9 +158,10 @@

if (minifyFn) {
return minifyFn({ [file]: input }, inputSourceMap);
}
return minifyFn({
[file]: input
}, inputSourceMap);
} // Copy terser options
// Copy terser options
const terserOptions = buildTerserOptions(options.terserOptions);
// Add source map data
const terserOptions = buildTerserOptions(options.terserOptions); // Add source map data
if (inputSourceMap) {

@@ -171,7 +179,21 @@ terserOptions.sourceMap = {

const { error, map, code, warnings } = _terser2.default.minify({ [file]: input }, terserOptions);
const {
error,
map,
code,
warnings
} = _terser.default.minify({
[file]: input
}, terserOptions);
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: 'terser-webpack-plugin' }) : cache;
// In some cases cpus() returns undefined
const {
cache,
parallel
} = options;
this.cacheDir = cache === true ? (0, _findCacheDir.default)({
name: 'terser-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, worker);
this.boundWorkers = (options, cb) => this.workers((0, _serializeJavascript2.default)(options), cb);
} : {
maxConcurrentWorkers: this.maxConcurrentWorkers
};
this.workers = (0, _workerFarm.default)(workerOptions, worker);
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": "terser-webpack-plugin",
"version": "1.1.0",
"version": "1.2.0",
"description": "Terser plugin for webpack",

@@ -10,6 +10,5 @@ "license": "MIT",

"bugs": "https://github.com/webpack-contrib/terser-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,8 +41,8 @@ },

"peerDependencies": {
"webpack": "^4.3.0"
"webpack": "^4.0.0"
},
"dependencies": {
"schema-utils": "^1.0.0",
"cacache": "^11.0.2",
"find-cache-dir": "^2.0.0",
"schema-utils": "^1.0.0",
"serialize-javascript": "^1.4.0",

@@ -59,10 +55,12 @@ "source-map": "^0.6.1",

"devDependencies": {
"@babel/cli": "^7.1.5",
"@babel/core": "^7.1.6",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.1.6",
"@commitlint/cli": "^7.0.0",
"@commitlint/config-conventional": "^7.0.1",
"@webpack-contrib/eslint-config-webpack": "^2.0.4",
"babel-cli": "^6.26.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",
"@webpack-contrib/defaults": "^3.0.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^23.6.0",
"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.0",
"standard-version": "^4.3.0",
"uglify-js": "^3.4.3",
"webpack": "^4.16.3",
"webpack-defaults": "^2.3.0"
"webpack": "^4.16.3"
},

@@ -105,6 +101,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": {

@@ -115,3 +125,8 @@ "*.js": [

]
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
}
}

@@ -17,3 +17,3 @@ <div align="center">

This plugin uses [terser](https://github.com/fabiosantoscode/terser) to minify your JavaScript.
This plugin uses [terser](https://github.com/terser-js/terser) to minify your JavaScript.

@@ -40,6 +40,5 @@ ## Requirements

module.exports = {
//...
optimization: {
minimizer: [new TerserPlugin()]
}
minimizer: [new TerserPlugin()],
},
};

@@ -55,11 +54,18 @@ ```

Type: `String|RegExp|Array<String|RegExp>`
Default: `/\.js(\?.*)?$/i`
Default: `/\.m?js(\?.*)?$/i`
Test to match files against.
**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
test: /\.js(\?.*)?$/i
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
}),
],
},
};
```

@@ -74,7 +80,14 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
include: /\/includes/
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
include: /\/includes/,
}),
],
},
};
```

@@ -89,9 +102,45 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
exclude: /\/excludes/
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
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 TerserPlugin({
chunkFilter: (chunk) => {
// Exclude uglification for the `vendor` chunk
if (chunk.name === 'vendor') {
return false;
}
return true;
},
}),
],
},
};
```
### `cache`

@@ -102,3 +151,3 @@

Enable file caching.
Enable file caching.
Default path to cache directory: `node_modules/.cache/terser-webpack-plugin`.

@@ -112,7 +161,14 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
cache: true
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
cache: true,
}),
],
},
};
```

@@ -127,6 +183,11 @@

```js
// in your webpack.config.js
new TerserPlugin({
cache: 'path/to/cache'
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
cache: 'path/to/cache',
}),
],
},
};
```

@@ -149,16 +210,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 TerserPlugin({
cache: true,
cacheKeys: (defaultCacheKeys, file) => {
defaultCacheKeys.myCacheKey = 'myCacheKeyValue';
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
cache: true,
cacheKeys: (defaultCacheKeys, file) => {
defaultCacheKeys.myCacheKey = 'myCacheKeyValue';
return defaultCacheKeys;
return defaultCacheKeys;
},
}),
],
},
})
};
```

@@ -171,3 +242,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`.

@@ -181,7 +252,14 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
parallel: true
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
};
```

@@ -193,7 +271,14 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
parallel: 4
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
};
```

@@ -211,7 +296,14 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
sourceMap: true
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
sourceMap: true,
}),
],
},
};
```

@@ -224,4 +316,4 @@

Allows you to override default minify function.
By default plugin uses [terser](https://github.com/fabiosantoscode/terser) package.
Allows you to override default minify function.
By default plugin uses [terser](https://github.com/terser-js/terser) package.
Useful for using and testing unpublished versions or forks.

@@ -231,18 +323,25 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
minify(file, sourceMap) {
const extractedComments = [];
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
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 };
},
}),
],
},
};
```

@@ -253,25 +352,32 @@

Type: `Object`
Default: [default](https://github.com/fabiosantoscode/terser#minify-options)
Default: [default](https://github.com/terser-js/terser#minify-options)
Terser minify options.
Terser minify [options](https://github.com/terser-js/terser#minify-options).
**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
terserOptions: {
ecma: undefined,
warnings: false,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
output: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false
}
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: undefined,
warnings: false,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
output: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
}),
],
},
};
```

@@ -293,7 +399,14 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
extractComments: true
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
};
```

@@ -305,7 +418,14 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
extractComments: 'all'
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
extractComments: 'all',
}),
],
},
};
```

@@ -315,9 +435,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 TerserPlugin({
extractComments: /@extract/i
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
extractComments: /@extract/i,
}),
],
},
};
```

@@ -327,15 +454,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 TerserPlugin({
extractComments: function (astNode, comment) {
if (/@extract/i.test(comment.value)) {
return true;
}
return false;
}
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
extractComments: (astNode, comment) => {
if (/@extract/i.test(comment.value)) {
return true;
}
return false;
},
}),
],
},
};
```

@@ -347,15 +481,22 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
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 TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: (file) => {
return `${file}.LICENSE`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
```

@@ -369,15 +510,22 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
extractComments: {
condition: 'some',
filename(file) {
return `${file}.LICENSE`;
},
banner(licenseFile) {
return `License information can be found in ${licenseFile}`;
}
}
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
extractComments: {
condition: 'some',
filename: (file) => {
return `${file}.LICENSE`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
```

@@ -393,13 +541,20 @@

**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
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 TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: 'extracted-comments.js',
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
```

@@ -412,19 +567,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 TerserPlugin({
extractComments: {
condition: true,
filename(file) {
return `${file}.LICENSE`;
},
banner(commentsFile) {
return `My custom banner about license information ${commentsFile}`;
}
}
})
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
extractComments: {
condition: true,
filename: (file) => {
return `${file}.LICENSE`;
},
banner: (commentsFile) => {
return `My custom banner about license information ${commentsFile}`;
},
},
}),
],
},
};
```

@@ -437,20 +599,27 @@

Allow to filter [terser](https://github.com/fabiosantoscode/terser) warnings.
Allow to filter [terser](https://github.com/terser-js/terser) warnings.
Return `true` to keep the warning, `false` otherwise.
**webpack.config.js**
```js
// in your webpack.config.js
new TerserPlugin({
warningsFilter: (warning, source) => {
if (/Dropping unreachable code/i.test(warning)) {
return true;
}
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
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;
},
}),
],
},
})
};
```

@@ -464,8 +633,6 @@

**webpack.config.js**
```js
// in your webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
//...
optimization: {

@@ -475,6 +642,6 @@ minimizer: [

cache: true,
parallel: true
})
]
}
parallel: true,
}),
],
},
};

@@ -487,8 +654,29 @@ ```

**webpack.config.js**
```js
// in your webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
output: {
comments: /@license/i,
},
},
extractComments: true,
}),
],
},
};
```
### Remove Comments
If you avoid building with comments, set **terserOptions.output.comments** to **false** as in this config:
**webpack.config.js**
```js
module.exports = {
//...
optimization: {

@@ -499,9 +687,8 @@ minimizer: [

output: {
comments: /@license/i
}
comments: false,
},
},
extractComments: true
})
]
}
}),
],
},
};

@@ -514,8 +701,6 @@ ```

**webpack.config.js**
```js
// in your webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
//...
optimization: {

@@ -526,3 +711,3 @@ minimizer: [

// cache: true,
// cacheKeys(defaultCacheKeys) {
// cacheKeys: (defaultCacheKeys) => {
// delete defaultCacheKeys.terser;

@@ -536,3 +721,3 @@ //

// },
minify(file, sourceMap) {
minify: (file, sourceMap) => {
// https://github.com/mishoo/UglifyJS2#minify-options

@@ -542,3 +727,3 @@ const uglifyJsOptions = {

};
if (sourceMap) {

@@ -549,8 +734,8 @@ uglifyJsOptions.sourceMap = {

}
return require('uglify-js').minify(file, uglifyJsOptions);
},
})
]
}
}),
],
},
};

@@ -557,0 +742,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc