如何使用webpack构建压缩和未压缩的包?

269

这是我的webpack.config.js文件

var webpack = require("webpack");

module.exports = {

  entry: "./entry.js",
  devtool: "source-map",
  output: {
    path: "./dist",
    filename: "bundle.min.js"
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin({minimize: true})
  ]
};

我正在使用......

$ webpack

在我的dist文件夹中,我只得到了:

  • bundle.min.js
  • bundle.min.js.map

我还想看到未压缩的bundle.js

14个回答

169

webpack.config.js:

const webpack = require("webpack");

module.exports = {
  entry: {
    "bundle": "./entry.js",
    "bundle.min": "./entry.js",
  },
  devtool: "source-map",
  output: {
    path: "./dist",
    filename: "[name].js"
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      include: /\.min\.js$/,
      minimize: true
    })
  ]
};
自 Webpack 4 开始,webpack.optimize.UglifyJsPlugin已被弃用且使用会导致错误:

webpack.optimize.UglifyJsPlugin已被移除,请使用config.optimization.minimize代替

根据手册的说明,该插件可以被minimize选项替换。通过指定UglifyJsPlugin实例,可以为该插件提供自定义配置:
const webpack = require("webpack");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  // ...
  optimization: {
    minimize: true,
    minimizer: [new UglifyJsPlugin({
      include: /\.min\.js$/
    })]
  }
};

这对于简单的设置足够了。一个更有效的解决方案是使用 Gulp 与 Webpack 一起,在一个流程中完成同样的事情。


1
@FeloVilches,我甚至没有提到这是在webpack.config.js中完成的,但是一旦我们进入Node.js领域并使用Webpack,这就被假定了。 - Estus Flask
3
在webpack 4中,我遇到了这个问题:Error: webpack.optimize.UglifyJsPlugin已被删除,请使用config.optimization.minimize代替。 - entithat
7
更新:现在您可以使用 terser-webpack-plugin 插件,详情请见 https://webpack.js.org/plugins/terser-webpack-plugin/ - ijse

168

您可以使用单个配置文件,并使用环境变量有条件地包含UglifyJS插件:

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

const PROD = JSON.parse(process.env.PROD_ENV || '0');

module.exports = {

  entry: './entry.js',
  devtool: 'source-map',
  output: {
    path: './dist',
    filename: PROD ? 'bundle.min.js' : 'bundle.js'
  },
  optimization: {
    minimize: PROD,
    minimizer: [
      new TerserPlugin({ parallel: true })
  ]
};

然后,在您想要进行最小化时,只需设置此变量:

$ PROD_ENV=1 webpack

编辑:

如评论中所述,NODE_ENV通常被用来(按惯例)说明一个特定的环境是生产环境还是开发环境。要检查它,您也可以设置const PROD = (process.env.NODE_ENV === 'production'),然后继续正常操作。

编辑:

如评论所述,NODE_ENV通常用于表明特定环境是生产环境还是开发环境。要检查它,您还可以设置const PROD = (process.env.NODE_ENV === 'production'),然后继续正常操作。


6
Node有一个名为"NODE_ENV"的“默认”变量。 - jonathancardoso
3
选项应该叫做“压缩”而不是“最小化”,对吗? - Slava Fomin II
1
只是一个小问题:当您使用参数调用webpack,例如webpack -p时,您在webpack配置中的_webpack.optimize.UglifyJsPlugin_设置将被(至少部分)忽略(至少设置mangle: false会被忽略)。 - Christian Ulbrich
2
注意,这只生成一个文件。因此,为了使其适用于该问题,应进行多个Webpack passes,“webpack && webpack -p”。 - Estus Flask
1
对于任何阅读此内容的人,我建议使用definePlugin,我认为它已经默认安装在Webpack中了。 - Ben Gubler
显示剩余3条评论

57

你可以使用不同的参数两次运行webpack:

$ webpack --minimize

然后在webpack.config.js中检查命令行参数:

var path = require('path'),
  webpack = require('webpack'),
  minimize = process.argv.indexOf('--minimize') !== -1,
  plugins = [];

if (minimize) {
  plugins.push(new webpack.optimize.UglifyJsPlugin());
}

...

示例 webpack.config.js


2
对我来说,这似乎是一个非常简单的解决方案;只是从webpack v3.5.5开始,它内置了一个称为--optimize-minimize或-p的开关。 - synergetic
1
这个想法很酷,但现在不起作用,webpack会报错“未知参数:minimize” 解决方案:使用--env.minimize 更多细节请参见以下链接https://github.com/webpack/webpack/issues/2254 - Zhli
可以使用更标准的方式在webpack中传递环境指示:https://dev59.com/R1cP5IYBdhLWcg3wnbQV - MaMazav

41
为了添加另一个答案,标志“-p”(短横线表示“--optimize-minimize”)将启用具有默认参数的UglifyJS。 您将不会在单次运行中获得缩小和原始包或生成具有不同名称的包,因此-p标志可能不符合您的用例。
相反,-d选项缩写为 --debug --devtool sourcemap --output-pathinfo 我的webpack.config.js省略了devtooldebugpathinfo和minmize插件,而使用这两个标志。

感谢 @everett1992,这个解决方案非常好用。大多数情况下我运行开发构建,然后完成后使用 -p 标志输出一个压缩的生产构建。无需创建两个单独的Webpack配置! - pmont

37

也许我来晚了,但我遇到了同样的问题,所以我编写了一个unminified-webpack-plugin来解决这个问题。

安装

npm install --save-dev unminified-webpack-plugin

使用方法

var path = require('path');
var webpack = require('webpack');
var UnminifiedWebpackPlugin = require('unminified-webpack-plugin');

module.exports = {
    entry: {
        index: './src/index.js'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'library.min.js'
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new UnminifiedWebpackPlugin()
    ]
};

按照上述步骤操作,你将得到两个文件 library.min.js 和 library.js。不需要执行两次 webpack,它会自动工作!^^


这个插件似乎与SourceMapDevToolPlugin不兼容。有什么建议可以保留源映射吗? - BhavikUp
@BhavikUp,这是不支持的。你真的需要在最终JS文件中输出源映射吗? - Howard
1
"无需执行两次webpack[...] " 很好,但是estus的解决方案也不需要“执行两次 webpack”,并且还不需要添加第三方插件。 - Louis
@Howard Man,你来得正是时候:)。至少对我来说是这样。非常感谢你提供的优秀插件!看起来它可以完美地与webpack 2和-p选项配合使用。 - gaperton

36

我认为直接使用UglifyJS工具会更加简单:

  1. npm install --save-dev uglify-js
  2. 像平常一样使用webpack,例如构建一个./dst/bundle.js文件。
  3. 在你的package.json中添加一个build命令:

"scripts": {
    "build": "webpack && uglifyjs ./dst/bundle.js -c -m -o ./dst/bundle.min.js --source-map ./dst/bundle.min.js.map"
}
  • 每当你想构建自己的包以及压缩代码和源映射时,请运行npm run build命令。
  • 无需在全局安装uglify-js,只需在本地为项目安装它即可。


    是的,这是一个简单的解决方案,可以让您只需构建一次。 - Flion

    16

    你可以为webpack创建两个配置文件,一个用于压缩代码,另一个不用(只需删除optimize.UglifyJSPlugin行),然后同时运行两个配置:$ webpack && webpack --config webpack.config.min.js


    3
    谢谢,这个方法很有效,但是如果有更好的方法来避免维护两个配置文件的话,那就太好了,因为这是一个非常常见的用例(几乎每个库的构建都需要)。 - Rick Strahl

    12
    根据这行代码:https://github.com/pingyuanChen/webpack-uglify-js-plugin/blob/master/index.js#L117,应该是这样的:
    var webpack = require("webpack");
    
    module.exports = {
    
      entry: "./entry.js",
      devtool: "source-map",
      output: {
        path: "./dist",
        filename: "bundle.js"
      },
      plugins: [
        new webpack.optimize.UglifyJsPlugin({
         minimize: true,
         compress: false
        })
      ]
    };
    

    实际上,你可以通过根据你的环境/argv策略导出不同的配置来拥有多个构建。


    感谢您对一个虽然有点老但仍然相关的问题给出了有帮助的答案,Mauro ^_^ - Mulan
    1
    在文档中找不到“最小化”选项。也许它已被弃用? - adi518
    @adi518 也许你正在使用插件的新版本,而不是打包在webpack中的那个版本? - thexpand

    9

    我找到了一个新的解决方案来解决这个问题。

    使用一个配置数组,使得webpack能够同时构建精简和非精简版本,从而加快构建速度。不需要运行两次webpack,也不需要额外的插件,只需要使用webpack即可。

    webpack.config.js

    const devConfig = {
      mode: 'development',
      entry: { bundle: './src/entry.js' },
      output: { filename: '[name].js' },
      module: { ... },
      resolve: { ... },
      plugins: { ... }
    };
    
    const prodConfig = {
      ...devConfig,
      mode: 'production',
      output: { filename: '[name].min.js' }
    };
    
    module.exports = (env) => {
      switch (env) {
        case 'production':
          return [devConfig, prodConfig];
        default:
          return devConfig;
      }
    };
    

    运行webpack只会构建非压缩版本。

    运行webpack --env=production将同时构建压缩和非压缩版本。


    4
    你可以按照以下方式格式化你的webpack.config.js文件:
    var debug = process.env.NODE_ENV !== "production";
    var webpack = require('webpack');
    
    module.exports = {
        context: __dirname,
        devtool: debug ? "inline-sourcemap" : null,
        entry: "./entry.js",
        output: {
            path: __dirname + "/dist",
            filename: "library.min.js"
        },
        plugins: debug ? [] : [
            new webpack.optimize.DedupePlugin(),
            new webpack.optimize.OccurenceOrderPlugin(),
            new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
        ],
    };'
    

    然后要构建未压缩的版本,请执行以下命令(在项目的主目录中):

    $ webpack
    

    要进行压缩构建,请运行以下命令:
    $ NODE_ENV=production webpack
    

    注意事项: 确保在未压缩版本中将输出文件名更改为library.js,在压缩版本中更改为library.min.js,以便它们不会相互覆盖。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接