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.js
或npm 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
,因为 bundled
和 webpack
。
只有在构建生产环境时才真正需要缩小,当您 运行 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: true
和 drop_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 在配置中并离开
如果您使用的是较新版本的 uglifyjs-webpack-plugin,那么您可以使用如下所示的代码插件设置,它应该可以正常工作。这里有一些关于 uglify 选项的小变化:
new UglifyJsPlugin({
uglifyOptions: {
mangle: true,
output: {
comments: false
}
},
sourceMap: true,
exclude: [/\.min\.js$/gi]
})
我正在尝试让 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.js
或npm 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
,因为 bundled
和 webpack
。
只有在构建生产环境时才真正需要缩小,当您 运行 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: true
和 drop_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 在配置中并离开
如果您使用的是较新版本的 uglifyjs-webpack-plugin,那么您可以使用如下所示的代码插件设置,它应该可以正常工作。这里有一些关于 uglify 选项的小变化:
new UglifyJsPlugin({
uglifyOptions: {
mangle: true,
output: {
comments: false
}
},
sourceMap: true,
exclude: [/\.min\.js$/gi]
})