Webpack UglifyJsPlugin 没有缩小代码

Webpack UglifyJsPlugin not minifying code

我正在尝试让 Webpack 在通过 Yarn 运行 时缩小我的 Javascript 代码。我相信我已经正确设置了所有内容,但是 Javascript 只是没有被缩小。

我构建了一个 docker 框来重现此问题:https://github.com/Danack/ReactTest(可能不适用于 Windows)

我已经通过手动调用 Uglify.minify() 测试了 Uglify 代码是否正在缩小测试文件,它是。

这是我的 Webpack 配置文件:

var webpack = require("webpack");
var path = require("path");

// This is just to test whether uglify is working.
var UglifyJS = require('uglify-js');
var fs = require('fs');
var result = UglifyJS.minify('./src/compress_test.js', {
  mangle: true,
  compress: {
    sequences: true,
    dead_code: true,
    conditionals: true,
    booleans: true,
    unused: true,
    if_return: true,
    join_vars: true,
    drop_console: true
  }
});
fs.writeFileSync('./uglify_test/manual.min.js', result.code);

module.exports = {

  entry: "./src/compress_test.js",
  devtool: "source-map",

  output: {
    path: path.resolve('./uglify_test'),
    filename: "[name].js"
  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      mangle: true,
      compress: {
        sequences: true,
        dead_code: true,
        conditionals: true,
        booleans: true,
        unused: true,
        if_return: true,
        join_vars: true,
        drop_console: true
      }
    })
  ]
};

构建项目webpack -d --colors --watch --config ./webpack.config.jsnpm run dev:build

我设置了一个简单的 Javascript 文件,其中包含长变量名,以便于查看 JS 是否被缩小。

// compress_test.js
function really_long_test_function_name(some_really_long_param_name_1, some_really_long_param_name_2) {


  var foo_really_long_var_name_1 = some_really_long_param_name_1 + "asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";
  var foo_really_long_var_name_2 = some_really_long_param_name_2 + "asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";

  var foo_really_long_var_name_3 = foo_really_long_var_name_1 + foo_really_long_var_name_2;
  var foo_really_long_var_name_4 = foo_really_long_var_name_1 + foo_really_long_var_name_3;
  var foo_really_long_var_name_5 = foo_really_long_var_name_1 + foo_really_long_var_name_4;
  var foo_really_long_var_name_6 = foo_really_long_var_name_1 + foo_really_long_var_name_5;
  var foo_really_long_var_name_7 = foo_really_long_var_name_1 + foo_really_long_var_name_6;
  var foo_really_long_var_name_8 = foo_really_long_var_name_1 + foo_really_long_var_name_7;
  var foo_really_long_var_name_9 = foo_really_long_var_name_1 + foo_really_long_var_name_8;


  return foo_really_long_var_name_9.length;
}

通过手动调用 Uglify 生成的 javascript 被很好地缩小了。

// manual.min.js
function really_long_test_function_name(a,p){var d=a+"asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";return(d+(d+(d+(d+(d+(d+(d+(p+"asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd")))))))).length}

Webpack 的内置 javascript 输出不是:

!function(l){function _(n){if(a[n])return a[n].exports;var o=a[n]={i:n,l:!1,exports:{}};return l[n].call(o.exports,o,o.exports,_),o.l=!0,o.exports}var a={};_.m=l,_.c=a,_.i=function(l){return l},_.d=function(l,a,n){_.o(l,a)||Object.defineProperty(l,a,{configurable:!1,enumerable:!0,get:n})},_.n=function(l){var a=l&&l.__esModule?function(){return l.default}:function(){return l};return _.d(a,"a",a),a},_.o=function(l,_){return Object.prototype.hasOwnProperty.call(l,_)},_.p="",_(_.s=0)}([/*!******************************!*\
  !*** ./src/compress_test.js ***!
  \******************************/
function(module,exports){eval('\n\nfunction really_long_test_function_name(some_really_long_param_name_1, some_really_long_param_name_2) {\n\n\n  var foo_really_long_var_name_1 = some_really_long_param_name_1 + "asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";\n  var foo_really_long_var_name_2 = some_really_long_param_name_2 + "asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";\n\n  var foo_really_long_var_name_3 = foo_really_long_var_name_1 + foo_really_long_var_name_2;\n  var foo_really_long_var_name_4 = foo_really_long_var_name_1 + foo_really_long_var_name_3;\n  var foo_really_long_var_name_5 = foo_really_long_var_name_1 + foo_really_long_var_name_4;\n  var foo_really_long_var_name_6 = foo_really_long_var_name_1 + foo_really_long_var_name_5;\n  var foo_really_long_var_name_7 = foo_really_long_var_name_1 + foo_really_long_var_name_6;\n  var foo_really_long_var_name_8 = foo_really_long_var_name_1 + foo_really_long_var_name_7;\n  var foo_really_long_var_name_9 = foo_really_long_var_name_1 + foo_really_long_var_name_8;\n\n\n  return foo_really_long_var_name_9.length;\n}\n\n\n\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjoz **** SOURCE_MAPPING_NOT_SHOWN_HERE***')}]);

长变量名还在。

我需要做什么才能使 webpack 实际缩小它输出的 Javascript?

以防万一,我使用的是 Yarn 0.23.4 和 Node 7.10.0

在您调用选项的代码中,添加:

new webpack.optimize.UglifyJsPlugin({
      mangle: true, { keep_fnames: false, screw_ie8: true },
      compress: true, { keep_fnames: false, screw_ie8: true }
})

我不知道您要设置的选项?你确定它们是 webpack uglify 选项吗?无论如何,希望这对您有所帮助。

编辑:

试试这个:

const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');

检查该库是否在该目录中以确保。

new UglifyJsPlugin({
        beautify: false,
        comments: false,
        ...
      }),

这将更直接地调用您原来的 Uglify 插件...尝试您之前设置的选项。

您不需要手动包含 uglifyjs,因为 bundledwebpack

只有在构建生产环境时才真正需要缩小,当您 运行 webpack 处于生产模式时,缩小会自动应用,即:

webpack -p

webpack --optimize-minimize --define process.env.NODE_ENV="'production'"

有关详细信息,请查看此网站:https://webpack.js.org/guides/production-build/

您似乎正在尝试将 uglify 与 watch 标志一起使用,该标志旨在用于开发。

如您所见,它将您的代码包装在一个 eval 语句和多个包装器中,这些包装器扰乱了丑化过程。我还怀疑它可能出于调试目的故意不破坏源代码。

根据你的Dockerfile,你是运行你的包中的这个命令,这让我觉得你正试图在生产中使用 webpack 作为你的打包器和文件服务器,这是不是它应该用来做什么。

通过采用您的确切配置和文件,我通过简单地声明如下所示的脚本来生成输出缩小文件没有问题:

"prod:build": "webpack"

因为你有 dead_code: truedrop_console: true,你可能必须用你当前的代码将它们设置为 false,因为永远不会调用该方法,我所做的就是调用它使用 console.log 并将 drop_console 设置为 false

console.log(really_long_test_function_name('a', 'b'))

构建的结果将如下所示

!function(o){function n(t){if(r[t])return r[t].exports;var e=r[t]={i:t,l:!1,exports:{}};return o[t].call(e.exports,e,e.exports,n),e.l=!0,e.exports}var r={};n.m=o,n.c=r,n.i=function(o){return o},n.d=function(o,r,t){n.o(o,r)||Object.defineProperty(o,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(o){var r=o&&o.__esModule?function(){return o.default}:function(){return o};return n.d(r,"a",r),r},n.o=function(o,n){return Object.prototype.hasOwnProperty.call(o,n)},n.p="",n(n.s=0)}([function(o,n){console.log(function(o,n){var r=o+"asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";return(r+(r+(r+(r+(r+(r+(r+(n+"asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd")))))))).length}("a","b"))}]);%

运行 webpack 二进制文件将自动采用 webpack.config.js。此外,不需要为插件指定 mangle: true,因为它已经是默认值。


要恢复,请在不使用 -watch 选项的情况下通过缩小进行正常的生产构建,并在您的 docker 中安装 nginx 之类的东西以在生产中为您的文件提供服务。

您使用-d。它是 --debug --devtool eval-cheap-module-source-map --output-pathinfo

的快捷方式

这部分 --devtool eval-cheap-module-source-map 重写你的 devtool 在配置中并离开

original source (lines only)

如果您使用的是较新版本的 uglifyjs-webpack-plugin,那么您可以使用如下所示的代码插件设置,它应该可以正常工作。这里有一些关于 uglify 选项的小变化:

new UglifyJsPlugin({ 
            uglifyOptions: {
                mangle: true,
                output: {
                    comments: false
                }
            },
            sourceMap: true,
            exclude: [/\.min\.js$/gi]
       })