当使用继承缩小/丑化ES6代码时,Webpack会删除类名

Ana*_*oly 6 javascript node.js uglifyjs uglifyjs2 webpack

在使用继承缩小/丑化ES6代码时,Webpack删除了类名:

我们尝试缩小/ uglifyMVCE代码:

班级儿童:

const ParentClass = require('parent');

class Child extends ParentClass{
    constructor(){
        super();
    }
}

module.exports = Child;
Run Code Online (Sandbox Code Playgroud)

index.js调用Child类:

const Child = require('./classes_so/child');

let child = new Child();

console.log(child.constructor.name);
Run Code Online (Sandbox Code Playgroud)

模块父内部node_modules:

class Parent {
    constructor() {
        if (this.constructor.name === 'Parent'){
            throw new TypeError("Parent class is abstract - cant be instance");
        }
    }

}

module.exports = Parent;
Run Code Online (Sandbox Code Playgroud)

整个输出我会后的问题结束,在这里我要发布唯一相关的线,我认为会导致错误的行为(由原来的输出线33-37):

n.exports = class extends r {
        constructor() {
            super();
        }
    };
Run Code Online (Sandbox Code Playgroud)

为什么这里缺少一个类名:class extends r?我希望这个价值会被破坏但是会存在,我可以把它看成是一个错误吗?我试图使用keep_classnames标志,但它保留了不可接受的原始类名.

我们正在使用:

  • Webpack:3.11.0(尝试4,相同的行为)
  • uglifyjs-webpack-plugin:1.2.4(尝试使用不同的插件)
  • NodeJS:v6.9.1和v8.9.1(相同输出)
  • 展示问题的完整项目:webpack-uglify-inheritence

更新1:

我们webpack.config.js:

const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const path = require('path');
const fs = require('fs');

const nodeModules = {};
const localDependencies = ['.bin'];
fs.readdirSync('node_modules')
    .filter(function (x) {
        return localDependencies.indexOf(x) === -1;
    })
    .forEach(function (mod) {
        nodeModules[mod] = 'commonjs ' + mod;
    });

try {


    module.exports = {
        target: 'node',
        node: {
            console: false,
            global: false,
            process: false,
            Buffer: false,
            __filename: true,
            __dirname: true
        },

        entry: './index_so.js',

        output: {
            path: path.join(__dirname, 'build'),
            filename: 'index.js'
        },

        externals: nodeModules,
        plugins: [
            new webpack.IgnorePlugin(/\.(css|less)$/),
            new webpack.BannerPlugin({
                banner: 'require("source-map-support").install();',
                raw: true,
                entryOnly: false
            })
        ],
        devtool: 'sourcemap',

        module: {
            loaders: [
                {test: /\.json$/, loader: "json-loader"}
            ]
        },

        plugins: [
            new UglifyJsPlugin({
                uglifyOptions: {
                    compress: {
                        warnings: false
                    },
                    keep_classnames: false,
                    mangle: true,
                    output: {
                        beautify: true
                    }
                }
            })
        ]
    };
}
catch (e) {
    console.error(e);
}
Run Code Online (Sandbox Code Playgroud)

上面示例中的整个缩小/未经授权的代码:

!function(n) {
    var t = {};
    function e(r) {
        if (t[r]) return t[r].exports;
        var o = t[r] = {
            i: r,
            l: !1,
            exports: {}
        };
        return n[r].call(o.exports, o, o.exports, e), o.l = !0, o.exports;
    }
    e.m = n, e.c = t, e.d = function(n, t, r) {
        e.o(n, t) || Object.defineProperty(n, t, {
            configurable: !1,
            enumerable: !0,
            get: r
        });
    }, e.n = function(n) {
        var t = n && n.__esModule ? function() {
            return n.default;
        } : function() {
            return n;
        };
        return e.d(t, "a", t), t;
    }, e.o = function(n, t) {
        return Object.prototype.hasOwnProperty.call(n, t);
    }, e.p = "", e(e.s = 0);
}([ function(n, t, e) {
    let r = new (e(1))();
    console.log(r.constructor.name);
}, function(n, t, e) {
    const r = e(2);
    n.exports = class extends r {
        constructor() {
            super();
        }
    };
}, function(n, t) {
    n.exports = require("parent");
} ]);
Run Code Online (Sandbox Code Playgroud)

t.n*_*ese 4

给定设置中的问题不在于 webpack 或 uglify 的代码中,而在于这部分代码:

class Parent {
  constructor() {
    if (this.constructor.name === 'Parent') {
      throw new TypeError("Parent class is abstract - cant be instance");
    }
  }

}

module.exports = Parent;
Run Code Online (Sandbox Code Playgroud)

/this.constructor.name === 'Parent'名称上的中继, 以测试是否被直接实例化。classfunctionParent

与其传递可能导致各种问题的名称,不如测试构造函数是否等于类。

class Parent {
  constructor() {
    if (this.constructor === Parent) {
      throw new TypeError("Parent class is abstract - cant be instance");
    }
  }

}

module.exports = Parent;
Run Code Online (Sandbox Code Playgroud)

  • @Anatoly我用“6.9.1”和更新版本以及“8.9.1”测试了它,如果“new Child”,“this.constructor === Parent”返回“false”,如果“new ParentClass”则返回“true”。您确定您正确更新并重新配置了您的“webpack-parent-class”。 (2认同)