Skip to content

Commit

Permalink
feat: added uglify-js minimizer (#425)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Aug 17, 2021
1 parent 0551a9b commit 69e9592
Show file tree
Hide file tree
Showing 12 changed files with 1,993 additions and 847 deletions.
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -528,9 +528,9 @@ module.exports = {
};
```

### swc
### [`swc`](https://github.com/swc-project/swc)

[swc is a super-fast compiler written in rust; producing widely-supported javascript from modern standards and typescript.](https://github.com/swc-project/swc)
[`swc`](https://github.com/swc-project/swc) is a super-fast compiler written in rust; producing widely-supported javascript from modern standards and typescript.

> ⚠ the `extractComments` option is not supported
Expand All @@ -552,6 +552,28 @@ module.exports = {
};
```

### [`uglify-js`](https://github.com/mishoo/UglifyJS)

UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.

**webpack.config.js**

```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.uglifyJsMinify,
// `terserOptions` options will be passed to `uglify-js`
// Link to options - https://github.com/mishoo/UglifyJS#minify-options
terserOptions: {},
}),
],
},
};
```

### Custom Minify Function

Override default minify function - use `uglify-js` for minification.
Expand Down
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"uglify-js": {
"optional": true
}
},
"dependencies": {
Expand All @@ -62,7 +65,9 @@
"@babel/preset-env": "^7.14.9",
"@commitlint/cli": "^13.1.0",
"@commitlint/config-conventional": "^13.1.0",
"@swc/core": "^1.2.78",
"@types/serialize-javascript": "^5.0.1",
"@types/uglify-js": "^3.13.1",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^27.0.6",
"copy-webpack-plugin": "^9.0.1",
Expand All @@ -80,7 +85,6 @@
"npm-run-all": "^4.1.5",
"prettier": "^2.3.2",
"standard-version": "^9.3.1",
"@swc/core": "^1.2.78",
"typescript": "^4.3.5",
"uglify-js": "^3.14.1",
"webpack": "^5.48.0",
Expand Down
90 changes: 84 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as terserPackageJson from "terser/package.json";
import pLimit from "p-limit";
import { Worker } from "jest-worker";

import { terserMinify, swcMinify } from "./utils";
import { terserMinify, uglifyJsMinify, swcMinify } from "./utils";

import * as schema from "./options.json";
import { minify as minifyFn } from "./minify";
Expand All @@ -20,6 +20,7 @@ import { minify as minifyFn } from "./minify";
/** @typedef {import("webpack").Asset} Asset */
/** @typedef {import("terser").ECMA} TerserECMA */
/** @typedef {import("terser").MinifyOptions} TerserMinifyOptions */
/** @typedef {import("uglify-js").MinifyOptions} UglifyJSMinifyOptions */
/** @typedef {import("@swc/core").JsMinifyOptions} SwcMinifyOptions */
/** @typedef {import("jest-worker").Worker} JestWorker */
/** @typedef {import("source-map").RawSourceMap} RawSourceMap */
Expand All @@ -28,7 +29,7 @@ import { minify as minifyFn } from "./minify";

/** @typedef {Rule[] | Rule} Rules */

/** @typedef {JestWorker & { transform: (options: string) => InternalMinifyResult, minify: (options: InternalMinifyOptions) => InternalMinifyResult }} MinifyWorker */
/** @typedef {JestWorker & { transform: (options: string) => MinifyResult, minify: (options: InternalMinifyOptions) => MinifyResult }} MinifyWorker */

/**
* @callback ExtractCommentsFunction
Expand All @@ -38,7 +39,7 @@ import { minify as minifyFn } from "./minify";
*/

/**
* @typedef {boolean | string | RegExp | ExtractCommentsFunction} ExtractCommentsCondition
* @typedef {boolean | 'all' | 'some' | RegExp | ExtractCommentsFunction} ExtractCommentsCondition
*/

/**
Expand Down Expand Up @@ -70,7 +71,7 @@ import { minify as minifyFn } from "./minify";
* @param {RawSourceMap | undefined} sourceMap
* @param {CustomMinifyOptions} minifyOptions
* @param {ExtractCommentsOptions | undefined} extractComments
* @returns {Promise<InternalMinifyResult>}
* @returns {Promise<MinifyResult>}
*/

/**
Expand All @@ -88,9 +89,12 @@ import { minify as minifyFn } from "./minify";
*/

/**
* @typedef {Object} InternalMinifyResult
* @typedef {Object} MinifyResult
* @property {string} code
* @property {RawSourceMap} [map]
* @property {Array<Error | string>} [errors]
* @property {Array<Error | string>} [warnings]
* @property {Array<string>} [extractedComments]
* @property {Array<string>} [extractedComments]
*/

Expand All @@ -105,6 +109,17 @@ import { minify as minifyFn } from "./minify";
* @property {terserMinify} minify
*/

/**
* @typedef {Object} PluginOptionsForUglifyJS
* @property {Rules} [test]
* @property {Rules} [include]
* @property {Rules} [exclude]
* @property {UglifyJSMinifyOptions} [terserOptions]
* @property {ExtractCommentsOptions} [extractComments]
* @property {boolean} [parallel]
* @property {uglifyJsMinify} minify
*/

/**
* @typedef {Object} PluginOptionsForSwc
* @property {Rules} [test]
Expand Down Expand Up @@ -139,7 +154,7 @@ import { minify as minifyFn } from "./minify";
*/

/**
* @typedef {DefaultPluginOptions | PluginOptionsForTerser | PluginOptionsForSwc | PluginOptionsForCustomMinifyFunction} PluginOptions
* @typedef {DefaultPluginOptions | PluginOptionsForTerser | PluginOptionsForUglifyJS | PluginOptionsForSwc | PluginOptionsForCustomMinifyFunction} PluginOptions
*/

class TerserPlugin {
Expand Down Expand Up @@ -545,11 +560,73 @@ class TerserPlugin {

await cacheItem.storePromise({
source: output.source,
errors: output.errors,
warnings: output.warnings,
commentsFilename: output.commentsFilename,
extractedCommentsSource: output.extractedCommentsSource,
});
}

if (output.errors && output.errors.length > 0) {
output.errors.forEach(
/**
* @param {Error | { message: string, filename?: string, line: number, col: number } | string} error
*/
(error) => {
/** @type {Error & { file?: string }} */
let errored;

if (error instanceof Error) {
errored = error;
} else if (typeof error === "string") {
errored = new Error(error);
} else {
const filename = error.filename || name;
const line =
typeof error.line !== "undefined" ? error.line : "";
const col = typeof error.col !== "undefined" ? error.col : "";

errored = new Error(
`${error.message} [${filename}${line ? `:${line}` : ""}${
col ? `,${col}` : ""
}]`
);
}

errored.file = name;

compilation.errors.push(/** @type {WebpackError} */ (errored));
}
);
}

if (output.warnings && output.warnings.length > 0) {
output.warnings.forEach(
/**
* @param {string} warning
*/
(warning) => {
const Warning = class Warning extends Error {
/**
* @param {string} message
*/
constructor(message) {
super(message);

this.name = "Warning";
this.hideStack = true;
this.file = name;
}
};

compilation.warnings.push(
/** @type {WebpackError} */
(new Warning(warning))
);
}
);
}

/** @type {Record<string, any>} */
const newInfo = { minimized: true };
const { source, extractedCommentsSource } = output;
Expand Down Expand Up @@ -732,6 +809,7 @@ class TerserPlugin {
}

TerserPlugin.terserMinify = terserMinify;
TerserPlugin.uglifyJsMinify = uglifyJsMinify;
TerserPlugin.swcMinify = swcMinify;

export default TerserPlugin;
6 changes: 3 additions & 3 deletions src/minify.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/** @typedef {import("./index.js").InternalMinifyOptions} InternalMinifyOptions */
/** @typedef {import("./index.js").InternalMinifyResult} InternalMinifyResult */
/** @typedef {import("./index.js").MinifyResult} MinifyResult */

/**
* @param {InternalMinifyOptions} options
* @returns {Promise<InternalMinifyResult>}
* @returns {Promise<MinifyResult>}
*/
async function minify(options) {
const {
Expand All @@ -25,7 +25,7 @@ async function minify(options) {

/**
* @param {string} options
* @returns {Promise<InternalMinifyResult>}
* @returns {Promise<MinifyResult>}
*/
async function transform(options) {
// 'use strict' => this === undefined (Clean Scope)
Expand Down
Loading

0 comments on commit 69e9592

Please sign in to comment.