Selaa lähdekoodia

`minify` option and variable declarations merge transformer

sanex3339 4 vuotta sitten
vanhempi
commit
1d86852e45

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 
+v1.3.0
+---
+* **New option:** `minify` enables code minification.
+
 v1.2.1
 ---
 * Support of old browsers when `selfDefending` is enabled. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/615

+ 13 - 1
README.md

@@ -329,6 +329,7 @@ Following options are available for the JS Obfuscator:
     identifiersPrefix: '',
     inputFileName: '',
     log: false,
+    minify: true,
     renameGlobals: false,
     renameProperties: false,
     reservedNames: [],
@@ -374,6 +375,7 @@ Following options are available for the JS Obfuscator:
     --identifiers-dictionary '<list>' (comma separated)
     --identifiers-prefix <string>
     --log <boolean>
+    --minify <boolean>
     --rename-globals <boolean>
     --rename-properties <boolean>
     --reserved-names '<list>' (comma separated)
@@ -657,13 +659,20 @@ Use this option when you want to obfuscate multiple files. This option helps to
 ### `inputFileName`
 Type: `string` Default: `''`
 
-Allows to set name of the input file with source code. This name will used internally for source map generation.
+Allows to set name of the input file with source code. This name will be used internally for source map generation.
 
 ### `log`
 Type: `boolean` Default: `false`
 
 Enables logging of the information to the console.
 
+### `minify`
+Type: `boolean` Default: `true`
+
+Enables code minification.
+
+##### :warning: this option doesn't affect identifier names.
+
 ### `renameGlobals`
 Type: `boolean` Default: `false`
 
@@ -947,6 +956,7 @@ Performance will 50-100% slower than without obfuscation
     disableConsoleOutput: true,
     identifierNamesGenerator: 'hexadecimal',
     log: false,
+    minify: true,
     renameGlobals: false,
     rotateStringArray: true,
     selfDefending: true,
@@ -977,6 +987,7 @@ Performance will 30-35% slower than without obfuscation
     disableConsoleOutput: true,
     identifierNamesGenerator: 'hexadecimal',
     log: false,
+    minify: true,
     renameGlobals: false,
     rotateStringArray: true,
     selfDefending: true,
@@ -1005,6 +1016,7 @@ Performance will slightly slower than without obfuscation
     disableConsoleOutput: true,
     identifierNamesGenerator: 'hexadecimal',
     log: false,
+    minify: true,
     renameGlobals: false,
     rotateStringArray: true,
     selfDefending: true,

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/index.browser.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/index.cli.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/index.js


+ 2 - 2
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "1.2.1",
+  "version": "1.3.0",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -48,7 +48,7 @@
     "@types/chance": "1.1.0",
     "@types/escodegen": "0.0.6",
     "@types/eslint-scope": "3.7.0",
-    "@types/estraverse": "0.0.6",
+    "@types/estraverse": "5.1.0",
     "@types/estree": "0.0.44",
     "@types/md5": "2.2.0",
     "@types/mkdirp": "1.0.1",

+ 6 - 0
src/JavaScriptObfuscator.ts

@@ -81,6 +81,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
         NodeTransformer.ScopeIdentifiersTransformer,
         NodeTransformer.SplitStringTransformer,
         NodeTransformer.TemplateLiteralTransformer,
+        NodeTransformer.VariableDeclarationsMergeTransformer,
         NodeTransformer.VariablePreserveTransformer
     ];
 
@@ -215,6 +216,11 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
 
         astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Converting);
         astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Obfuscating);
+
+        if (this.options.minify) {
+            astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Minification);
+        }
+
         astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Finalizing);
 
         return astTree;

+ 4 - 0
src/cli/JavaScriptObfuscatorCLI.ts

@@ -249,6 +249,10 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
                 '--log <boolean>', 'Enables logging of the information to the console',
                 BooleanSanitizer
             )
+            .option(
+                '--minify <boolean>', 'Enables code minification',
+                BooleanSanitizer
+            )
             .option(
                 '--reserved-names <list> (comma separated, without whitespaces)',
                 'Disables obfuscation and generation of identifiers, which being matched by passed RegExp patterns (comma separated)',

+ 2 - 0
src/container/InversifyContainerFacade.ts

@@ -10,6 +10,7 @@ import { customNodesModule } from './modules/custom-nodes/CustomNodesModule';
 import { finalizingTransformersModule } from './modules/node-transformers/FinalizingTransformersModule';
 import { generatorsModule } from './modules/generators/GeneratorsModule';
 import { initializingTransformersModule } from './modules/node-transformers/InitializingTransformersModule';
+import { minificationTransformersModule } from './modules/node-transformers/MinificationTransformersModule';
 import { nodeModule } from './modules/node/NodeModule';
 import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
 import { obfuscatingTransformersModule } from './modules/node-transformers/ObfuscatingTransformersModule';
@@ -211,6 +212,7 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
         this.container.load(finalizingTransformersModule);
         this.container.load(generatorsModule);
         this.container.load(initializingTransformersModule);
+        this.container.load(minificationTransformersModule);
         this.container.load(nodeModule);
         this.container.load(nodeTransformersModule);
         this.container.load(obfuscatingTransformersModule);

+ 15 - 0
src/container/modules/node-transformers/MinificationTransformersModule.ts

@@ -0,0 +1,15 @@
+import { ContainerModule, interfaces } from 'inversify';
+import { ServiceIdentifiers } from '../../ServiceIdentifiers';
+
+import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
+
+import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
+
+import { VariableDeclarationsMergeTransformer } from '../../../node-transformers/minification-transformers/VariableDeclarationsMergeTransformer';
+
+export const minificationTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
+    // minification transformers
+    bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
+        .to(VariableDeclarationsMergeTransformer)
+        .whenTargetNamed(NodeTransformer.VariableDeclarationsMergeTransformer);
+});

+ 1 - 0
src/enums/node-transformers/NodeTransformationStage.ts

@@ -6,5 +6,6 @@ export enum NodeTransformationStage {
     RenameProperties = 'RenameProperties',
     Converting = 'Converting',
     Obfuscating = 'Obfuscating',
+    Minification = 'Minification',
     Finalizing = 'Finalizing'
 }

+ 1 - 0
src/enums/node-transformers/NodeTransformer.ts

@@ -18,5 +18,6 @@ export enum NodeTransformer {
     ScopeIdentifiersTransformer = 'ScopeIdentifiersTransformer',
     SplitStringTransformer = 'SplitStringTransformer',
     TemplateLiteralTransformer = 'TemplateLiteralTransformer',
+    VariableDeclarationsMergeTransformer = 'VariableDeclarationsMergeTransformer',
     VariablePreserveTransformer = 'VariablePreserveTransformer'
 }

+ 1 - 0
src/interfaces/options/IOptions.ts

@@ -21,6 +21,7 @@ export interface IOptions {
     readonly identifiersPrefix: string;
     readonly inputFileName: string;
     readonly log: boolean;
+    readonly minify: boolean;
     readonly renameGlobals: boolean;
     readonly renameProperties: boolean;
     readonly reservedNames: string[];

+ 91 - 0
src/node-transformers/minification-transformers/VariableDeclarationsMergeTransformer.ts

@@ -0,0 +1,91 @@
+import { inject, injectable, } from 'inversify';
+import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
+
+import * as estraverse from 'estraverse';
+import * as ESTree from 'estree';
+
+import { TStatement } from '../../types/node/TStatement';
+
+import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
+import { IVisitor } from '../../interfaces/node-transformers/IVisitor';
+
+import { NodeTransformationStage } from '../../enums/node-transformers/NodeTransformationStage';
+
+import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
+import { NodeGuards } from '../../node/NodeGuards';
+import { NodeStatementUtils } from '../../node/NodeStatementUtils';
+
+/**
+ * replaces:
+ *     var foo = 1;
+ *     var bar = 2;
+ *
+ * on:
+ *     var foo = 1,
+ *         bar = 2;
+ */
+@injectable()
+export class VariableDeclarationsMergeTransformer extends AbstractNodeTransformer {
+    /**
+     * @param {IRandomGenerator} randomGenerator
+     * @param {IOptions} options
+     */
+    public constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(randomGenerator, options);
+    }
+
+    /**
+     * @param {NodeTransformationStage} nodeTransformationStage
+     * @returns {IVisitor | null}
+     */
+    public getVisitor (nodeTransformationStage: NodeTransformationStage): IVisitor | null {
+        switch (nodeTransformationStage) {
+            case NodeTransformationStage.Minification:
+                return {
+                    enter: (
+                        node: ESTree.Node,
+                        parentNode: ESTree.Node | null
+                    ): ESTree.Node | estraverse.VisitorOption | undefined => {
+                        if (parentNode && NodeGuards.isVariableDeclarationNode(node)) {
+                            return this.transformNode(node, parentNode);
+                        }
+                    }
+                };
+
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * @param {ESTree.VariableDeclaration} variableDeclarationNode
+     * @param {ESTree.Node} parentNode
+     * @returns {ESTree.VariableDeclaration | estraverse.VisitorOption}
+     */
+    public transformNode (
+        variableDeclarationNode: ESTree.VariableDeclaration,
+        parentNode: ESTree.Node
+    ): ESTree.VariableDeclaration | estraverse.VisitorOption {
+        if (!NodeGuards.isNodeWithStatements(parentNode)) {
+            return variableDeclarationNode;
+        }
+
+        const prevStatement: TStatement | null = NodeStatementUtils.getPreviousSiblingStatement(variableDeclarationNode);
+
+        if (!prevStatement || !NodeGuards.isVariableDeclarationNode(prevStatement)) {
+            return variableDeclarationNode;
+        }
+
+        if (variableDeclarationNode.kind !== prevStatement.kind) {
+            return variableDeclarationNode;
+        }
+
+        prevStatement.declarations.push(...variableDeclarationNode.declarations);
+
+        return estraverse.VisitorOption.Remove;
+    }
+}

+ 6 - 0
src/options/Options.ts

@@ -150,6 +150,12 @@ export class Options implements IOptions {
     @IsBoolean()
     public readonly log!: boolean;
 
+    /**
+     * @type {boolean}
+     */
+    @IsBoolean()
+    public readonly minify!: boolean;
+
     /**
      * @type {boolean}
      */

+ 1 - 0
src/options/presets/Default.ts

@@ -21,6 +21,7 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
     identifiersDictionary: [],
     inputFileName: '',
     log: false,
+    minify: true,
     renameGlobals: false,
     renameProperties: false,
     reservedNames: [],

+ 1 - 0
src/options/presets/NoCustomNodes.ts

@@ -20,6 +20,7 @@ export const NO_ADDITIONAL_NODES_PRESET: TInputOptions = Object.freeze({
     identifiersDictionary: [],
     inputFileName: '',
     log: false,
+    minify: false,
     renameGlobals: false,
     renameProperties: false,
     reservedNames: [],

+ 5 - 4
test/dev/dev.ts

@@ -7,14 +7,15 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
-            class Foo {
-                [(1, Symbol.asyncIterator)]() {}
-            }
+            const foo = 1;
+            let bar = 2;
+            
+            bar = 3;
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,
             compact: false,
-            renameProperties: true
+            minify: true
         }
     ).getObfuscatedCode();
 

+ 4 - 4
yarn.lock

@@ -297,10 +297,10 @@
     "@types/estree" "*"
     "@types/json-schema" "*"
 
-"@types/estraverse@0.0.6":
-  version "0.0.6"
-  resolved "https://registry.yarnpkg.com/@types/estraverse/-/estraverse-0.0.6.tgz#669f7cdf72ab797e6125f8d00fed33d4cf30c221"
-  integrity sha1-Zp9833KreX5hJfjQD+0z1M8wwiE=
+"@types/estraverse@5.1.0":
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/@types/estraverse/-/estraverse-5.1.0.tgz#7a16cf8a8ee7764c05ccef3b2701bbcde6d5d0ae"
+  integrity sha512-vH2ItsZq47KprWHdv8OMjlfpygPHp1P7X4zuJuTghXldyezatpaotNSujld/HNsxh9TUS7+JRB0HEldkv67qaw==
   dependencies:
     "@types/estree" "*"
 

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä