【问题标题】:Webpack UglifyJsPlugin not minifying codeWebpack UglifyJsPlugin 没有缩小代码
【发布时间】:2017-10-14 04:09:57
【问题描述】:

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

我已经构建了一个 docker box 来重现这个问题: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

【问题讨论】:

    标签: webpack uglifyjs


    【解决方案1】:

    您使用-d。这是--debug --devtool eval-cheap-module-source-map --output-pathinfo的快捷方式

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

    original source (lines only)

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

        你应该只在为生产构建时真正需要缩小,当你在生产模式下运行 webpack 时会自动应用缩小,即:

        webpack -p
        

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

        欲了解更多详情,请查看本网站:https://webpack.js.org/guides/production-build/

        【讨论】:

        • 如果我使用 -p 标志,而不删除 UglifyJsPlugin,我会收到一个错误,这显然是在两次应用 Uglify 时很常见的事情。如果我删除插件并保留 -p 标志,那么看起来没有进行任何缩小。
        • 顺便说一句,我还尝试在 webpack 配置文件中使用 new webpack.DefinePlugin({'process.env': {'NODE_ENV': JSON.stringify('production')}}) 来进行显式生产配置。这似乎也没有太大区别。
        【解决方案4】:

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

        如您所见,它将您的代码包装在一个 eval 语句和多个包装器中,这会干扰丑化过程。我还怀疑它可能为了调试目的而故意保留源代码。

        从您的Dockerfile 中,您正在从您的包中运行此命令,这让我认为您正在尝试将 webpack 用作生产环境中的打包程序和文件服务器,这不是它应该用于的用途。

        通过获取您的确切配置和文件,我只需声明一个如下所示的脚本即可生成输出缩小文件:

        "prod:build": "webpack"
        

        由于您有dead_code: truedrop_console: true,您可能必须使用当前代码将它们设置为false,因为该方法从未被调用,我所做的是使用console.log 调用它并设置@987654328 @到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 之类的东西来为生产中的文件提供服务。

        【讨论】:

        • " 这让我觉得你正在尝试将 webpack 用作生产环境中的打包程序和文件服务器”——不,编译后的文件实际上将作为 PHP 应用程序的一部分提供。这些东西仅供开发人员使用,比实际设置更易于复制。你能确认你是通过 docker box 运行 webpack 吗?不幸的是,在我明天回到非 Windows 机器之前,我无法测试“prod:build”。
        • 如果这是为开发人员准备的,无论如何激活 uglify 对我来说没有意义,您需要能够轻松调试,并且修改您的方法将无济于事。如果编译后的文件将由 PHP 提供,那很好。我没有通过docker box完成,但是运行prod:build应该绝对没有问题,让我知道;)
        【解决方案5】:

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

        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 插件...试试你之前设置的选项。

        【讨论】:

        • "我不知道您要设置的选项?"我随机尝试了一些东西,但这些都是有效的选项:lisperator.net/uglifyjs/compress 您发布的 JS 似乎无效。
        • 你没有使用那个......你正在使用“webpack.optimize.UglifyJsPlugin”。它们并不完全相同...您是否尝试过我的建议?
        • “你尝试我的建议了吗?” - 是的。您的建议给出了语法错误,因为它不是有效的 Javascript。
        • 顺便说一句,我认为 webpack 的 UglifyJsPlugin 只是该库的包装器,因为它在它的依赖项中列出:github.com/webpack-contrib/uglifyjs-webpack-plugin/blob/master/…
        • 包装器可以对源模块的语法做任何事情...查看 webpack-plugin 的源代码...如果您不想在这些选项中保持持久性并且不尝试任何事情否则,那我想真的没有人能帮助你吗?因为那你的问题是什么?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-30
        • 1970-01-01
        • 2018-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多