WebPack + TerserPlugin:mangle忽略属性和类名-乱码的质量很差

时间:2019-11-13 10:31:14

标签: typescript webpack terser

生成的代码已缩小,但几乎未修改。这是在Google Chrome浏览器中的外观(美化): Example of result did not mangled code 1/2. Example of result did not mangled code 1/2.

所有属性名称,很多变量都有其原始名称。 即使明确指定了Terser的mangle选项:

  • mangle:是的,
  • sourceMap:否,
  • keep_fnames:否,
  • 顶级:true,

这是WebPack配置:

const TerserPlugin = require('terser-webpack-plugin');
const path = require('path');

module.exports = {
    entry: './src/scripts/index.ts',
    devtool: 'inline-source-map',
    module: {
        rules: [        
            {
                test: /\.tsx?$/,                
                use: {
                    loader: 'ts-loader',
                    options: { configFile: 'tsconfig-build.json' }
                },
                exclude: /node_modules/,                
            },
        ],        
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ],
    },
    plugins: [ ],

    // PROBLEMS HERE:
    optimization: {        
        minimize: true,        
        minimizer: [new TerserPlugin({
            sourceMap: false,            
            extractComments: false, // To avoid separate file with licenses.
            terserOptions: {
                mangle: true,
                sourceMap: false,       
                //keep_classnames: false,
                keep_fnames: false,
                toplevel: true,                                
            },                     
        })],
    },

    output: {    
        path: path.resolve(__dirname, resultDirPath),
        filename: 'main.js',
        publicPath: './',
    }   

}

我在配置中错过了什么吗?

3 个答案:

答案 0 :(得分:1)

不幸的是,没有没有简便的解决方案,而该代码已经是Terser所能提供的最好的代码。


但是,我找到了一个完美的解决方案:"JavaScript obfuscator" – https://github.com/javascript-obfuscator/javascript-obfuscator#readme

及其WebPack插件:"javascript-obfuscator plugin for Webpack" – https://github.com/javascript-obfuscator/webpack-obfuscator

在Google Chrome中进行美化后,生成的JS文件如下所示: An example of perfectly obfuscated JS code with "JavaScript obfuscator".

顺便说一句,在我的情况下,它仅大35%。


因此,总结一下,您所需要的只是:

  1. 安装“ Webpack的JavaScript-obfuscator插件”:“ npm install --save-dev webpack-obfuscator“
  2. 并将插件添加到WebPack:
const JavaScriptObfuscator = require('webpack-obfuscator');

// ...

// webpack plugins array
plugins: [
    new JavaScriptObfuscator ({
      rotateUnicodeArray: true
  }, ['excluded_bundle_name.js'])
],

仅此而已!

答案 1 :(得分:1)

我相信在您的原始配置中,您需要添加mangle.properties才能使ES6类方法和数据成员受到破坏。为避免损坏外部库,我使用与下面的正则表达式匹配的前缀策略“唯一”命名了要处理的所有方法和数据成员。

            new TerserPlugin({
                terserOptions: {
                    mangle: {
                        properties: {
                            regex: /(^P1|^p1|^_p1)[A-Z]\w*/
                        }
                    }
                }
            })
        "terser-webpack-plugin": "^2.2.1",

这种方法的小缺点:

  • 我的命名当前与我使用的外部库中的命名不匹配。在将来的库版本中无法保证这一点。
  • 这使我原来的src有点难看。

答案 2 :(得分:1)

mangle: { properties: true } 是安全的,如果您不进行自省或其他在 TypeScript 中不常见的魔术:

class MyClassName {
    constructor(public arg: string) {
        console.log(arg);
    }

    getContext() {
        console.log("I'm not mangled because I might be a HTMLCanvasElement.getContext");
    }

    someCustomMethodName() {
        console.log("What's my name?");
    }
}

const x = new Foo("Hello world");
x.getContext();
x.someCustomMethodName();

会变成

(() => {
    const e = new class {
        constructor(e) {
            this.o = e, console.log(e);
        }

        getContext() {
            console.log("I'm not mangled because I might be a HTMLCanvasElement.getContext");
        }

        t() {
            console.log("What's my name?");
        }
    }("Hello world");
    e.getContext(), e.t();
})();