Làm thế nào để xây dựng gói rút gọn và không nén với webpack?


233

Đây là của tôi 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})
  ]
};

Tôi đang xây dựng với

$ webpack

Trong distthư mục của tôi , tôi chỉ nhận được

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

Tôi cũng muốn thấy không nén bundle.js

Câu trả lời:


151

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
    })
  ]
};

Vì Webpack 4, webpack.optimize.UglifyJsPluginđã không được dùng nữa và kết quả sử dụng bị lỗi:

webpack.optizes.UglifyJsPlugin đã bị xóa, vui lòng sử dụng config.optimization.minizing thay thế

Như hướng dẫn giải thích, plugin có thể được thay thế bằng minimizetùy chọn. Cấu hình tùy chỉnh có thể được cung cấp cho plugin bằng cách chỉ định UglifyJsPluginthể hiện:

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

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

Điều này thực hiện công việc cho một thiết lập đơn giản. Một giải pháp hiệu quả hơn là sử dụng Gulp cùng với Webpack và thực hiện điều tương tự trong một lần.


1
@FeloVilches Tôi thậm chí không đề cập đến việc này được thực hiện trong webpack.config.js, nhưng điều này được cho là một khi chúng ta ở vùng đất Node.js và sử dụng Webpack.
Bình Estus

3
Hmm, trong webpack 4 tôi đã nhận:Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
entithat

3
Cập nhật: bây giờ bạn có thể sử dụng terser-webpack-plugin webpack.js.org/plugins/terser-webpack-plugin
ijse

156

Bạn có thể sử dụng một tệp cấu hình duy nhất và bao gồm plugin UglifyJS một cách có điều kiện bằng cách sử dụng biến môi trường:

var webpack = require('webpack');

var 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'
  },
  plugins: PROD ? [
    new webpack.optimize.UglifyJsPlugin({
      compress: { warnings: false }
    })
  ] : []
};

và sau đó chỉ đặt biến này khi bạn muốn thu nhỏ nó:

$ PROD_ENV=1 webpack


Biên tập:

Như đã đề cập trong các ý kiến, NODE_ENVthường được sử dụng (theo quy ước) để nêu rõ một môi trường cụ thể là môi trường sản xuất hay môi trường phát triển. Để kiểm tra, bạn cũng có thể thiết lập var PROD = (process.env.NODE_ENV === 'production')và tiếp tục bình thường.


6
Nút có một biến "mặc định" cho điều đó, nó được gọi là NODE_ENV.
JCM

2
Không phải là tùy chọn được gọi compressthay vì minimize?
Slava Fomin II

1
Chỉ là một hình ảnh nhỏ: khi bạn gọi webpack bằng các đối số, như webpack -pcác cài đặt từ webpack.optizes.UglifyJsPlugin trong cấu hình webpack của bạn sẽ bị bỏ qua ( ít nhất là một phần) (ít nhất mangle: falselà bỏ qua cài đặt ).
Christian Ulbrich

2
Lưu ý rằng điều này chỉ tạo ra một tệp tại một thời điểm. Vì vậy, để làm cho câu hỏi này hoạt động, cần có nhiều lượt Webpack webpack && webpack -p.
Bình Estus

1
Đối với bất cứ ai đọc điều này, tôi sẽ đề nghị sử dụng definePluginthay thế, mà tôi nghĩ được cài đặt theo mặc định với Webpack.
Ben Gubler

54

Bạn có thể chạy webpack hai lần với các đối số khác nhau:

$ webpack --minimize

sau đó kiểm tra các đối số dòng lệnh trong 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());
}

...

ví dụ webpack.config.js


2
Có vẻ là giải pháp rất đơn giản với tôi; cũng giống như webpack v3.5.5, nó có công tắc tích hợp có tên là - tối thiểu hóa tối thiểu hóa hoặc -p.
hiệp lực

Ý tưởng này rất hay, nhưng không hoạt động ngay bây giờ, webpack sẽ hét lên "Đối số không xác định: tối thiểu hóa" Giải pháp: sử dụng --env.minizing chi tiết hơn trong liên kết sau github.com/webpack/webpack/issues/2254
Zhli

Có thể sử dụng cách tiêu chuẩn hơn để vượt qua chỉ báo môi trường trong webpack: stackoverflow.com/questions/44113359/
mẹo

40

Để thêm câu trả lời khác, cờ -p(viết tắt --optimize-minimize) sẽ kích hoạt UglifyJS với các đối số mặc định.

Bạn sẽ không nhận được một gói được rút gọn và thô trong một lần chạy hoặc tạo các gói có tên khác nhau để -pcờ có thể không đáp ứng trường hợp sử dụng của bạn.

Ngược lại, -dtùy chọn này là viết tắt của--debug --devtool sourcemap --output-pathinfo

Webpack.config.js tôi bỏ qua devtool, debug, pathinfo, và minmize cắm nghiêng về hai lá cờ này.


Cảm ơn @ everett1992, giải pháp này hoạt động rất tốt. Phần lớn thời gian tôi chạy bản dựng dev, sau đó khi tôi hoàn thành, tôi sử dụng cờ -p để nhổ một bản dựng sản xuất được thu nhỏ. Không cần phải tạo hai cấu hình Webpack riêng biệt!
pmont

36

Có lẽ tôi đến trễ ở đây, nhưng tôi có cùng một vấn đề, vì vậy tôi đã viết một plugin-webpack-minminified cho mục đích này.

Cài đặt

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

Sử dụng

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()
    ]
};

Bằng cách làm như trên, bạn sẽ nhận được hai tệp library.min.js và library.js. Không cần thực thi webpack hai lần, nó chỉ hoạt động! ^^


Plugin này dường như không tương thích với SourceMapDevToolPlugin. Bất kỳ đề xuất để giữ lại bản đồ nguồn?
BhastaUp

@BhastaUp, nó không được hỗ trợ. Bạn có nghĩ rằng bạn thực sự cần bản đồ nguồn để được xuất cùng với tệp js cuối cùng không?
Howard

1
"Không cần thực thi gói web hai lần [...]" Đẹp, nhưng giải pháp của estus cũng không yêu cầu "thực thi gói web hai lần" và ngoài ra không yêu cầu thêm plugin của bên thứ ba.
Louis

@Howard Man, bạn đúng giờ :). Ít nhất, đối với tôi. Cảm ơn rất nhiều cho các plugin tuyệt vời! Có vẻ hoạt động hoàn hảo với tùy chọn webpack 2 và -p.
gaperton

34

Theo tôi, việc sử dụng trực tiếp công cụ UglifyJS dễ dàng hơn nhiều :

  1. npm install --save-dev uglify-js
  2. Sử dụng gói web như bình thường, ví dụ: xây dựng một ./dst/bundle.jstệp.
  3. Thêm một buildlệnh vào package.json:

    "scripts": {
        "build": "webpack && uglifyjs ./dst/bundle.js -c -m -o ./dst/bundle.min.js --source-map ./dst/bundle.min.js.map"
    }
    
  4. Bất cứ khi nào bạn muốn xây dựng một gói của bạn cũng như mã xấu và mã nguồn, hãy chạy npm run buildlệnh.

Không cần phải cài đặt uglify-js trên toàn cầu, chỉ cần cài đặt cục bộ cho dự án.


vâng, đây là một giải pháp dễ dàng cho phép bạn xây dựng chỉ một lần
Flion

15

Bạn có thể tạo hai cấu hình cho gói webpack, một cấu hình thu nhỏ mã và một cấu hình không (chỉ xóa dòng tối ưu hóa.UglifyJSPlugin) và sau đó chạy cả hai cấu hình cùng một lúc $ webpack && webpack --config webpack.config.min.js


2
Cảm ơn, điều này hoạt động rất tốt, nhưng chắc chắn sẽ tốt nếu có cách tốt hơn để duy trì hai tệp cấu hình do đây là trường hợp sử dụng phổ biến như vậy (chỉ về bất kỳ bản dựng thư viện nào).
Rick Strahl

12

Theo dòng này: https://github.com/pingyuanChen/webpack-uglify-js-plugin/blob/master/index.js#L117

nên là một cái gì đó như:

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
    })
  ]
};

Thật vậy, bạn có thể có nhiều bản dựng bằng cách xuất các cấu hình khác nhau theo chiến lược env / argv của bạn.


Cảm ơn câu trả lời hữu ích của bạn về một câu hỏi lâu đời nhưng vẫn có liên quan, Mauro ^ _ ^
Cảm ơn bạn

1
Không thể tìm thấy tùy chọn minimizetrong tài liệu. Có lẽ nó bị phản đối?
adi518

@ adi518 Có lẽ bạn đang sử dụng phiên bản mới hơn của plugin chứ không phải phiên bản được gói trong gói webpack?
thexpand

4

webpack entry.jsx ./output.js -p

làm việc cho tôi, với -pcờ.


4

Bạn có thể định dạng webpack.config.js của mình như thế này:

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 }),
    ],
};'

Và sau đó để xây dựng nó chạy tối thiểu (trong thư mục chính của dự án):

$ webpack

Để xây dựng nó chạy tối thiểu hóa:

$ NODE_ENV=production webpack

Lưu ý: Đảm bảo rằng đối với phiên bản chưa hoàn thành, bạn thay đổi tên tệp đầu ra thành library.jsvà cho bản rút gọn library.min.jsđể chúng không ghi đè lên nhau.


3

Tôi có cùng một vấn đề, và phải đáp ứng tất cả các yêu cầu sau:

  • Phiên bản rút gọn + Không rút gọn (như trong câu hỏi)
  • ES6
  • Nền tảng chéo (Windows + Linux).

Cuối cùng tôi đã giải quyết nó như sau:

webpack.config.js:

const path = require('path');
const MinifyPlugin = require("babel-minify-webpack-plugin");

module.exports = getConfiguration;

function getConfiguration(env) {
    var outFile;
    var plugins = [];
    if (env === 'prod') {
        outFile = 'mylib.dev';
        plugins.push(new MinifyPlugin());
    } else {
        if (env !== 'dev') {
            console.log('Unknown env ' + env + '. Defaults to dev');
        }
        outFile = 'mylib.dev.debug';
    }

    var entry = {};
    entry[outFile] = './src/mylib-entry.js';

    return {
        entry: entry,
        plugins: plugins,
        output: {
            filename: '[name].js',
            path: __dirname
        }
    };
}

gói.json:

{
    "name": "mylib.js",
    ...
    "scripts": {
        "build": "npm-run-all webpack-prod webpack-dev",
        "webpack-prod": "npx webpack --env=prod",
        "webpack-dev": "npx webpack --env=dev"
    },
    "devDependencies": {
        ...
        "babel-minify-webpack-plugin": "^0.2.0",
        "npm-run-all": "^4.1.2",
        "webpack": "^3.10.0"
    }
}

Sau đó, tôi có thể xây dựng bằng cách (Đừng quên npm installtrước đó):

npm run-script build

Tôi đã gặp lỗi này LRI không xác định: Giá trị typeof không hợp lệ
Kushal Jain

3

Tôi tìm thấy một giải pháp mới cho vấn đề này.

Điều này sử dụng một mảng cấu hình để cho phép webpack xây dựng song song phiên bản rút gọn và không rút gọn. Điều này làm cho xây dựng nhanh hơn. Không cần phải chạy webpack hai lần. Không cần bổ sung. Chỉ cần gói web.

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;
  }
};

Chạy webpacksẽ chỉ xây dựng phiên bản không rút gọn.

Chạy webpack --env=productionsẽ xây dựng phiên bản rút gọn và không rút gọn cùng một lúc.


1

Bạn nên xuất một mảng như thế này:

const path = require('path');
const webpack = require('webpack');

const libName = 'YourLibraryName';

function getConfig(env) {
  const config = {
    mode: env,
    output: {
      path: path.resolve('dist'),
      library: libName,
      libraryTarget: 'umd',
      filename: env === 'production' ? `${libName}.min.js` : `${libName}.js`
    },
    target: 'web',
    .... your shared options ...
  };

  return config;
}

module.exports = [
  getConfig('development'),
  getConfig('production'),
];

0

Bạn có thể xác định hai điểm nhập trong cấu hình gói web của bạn, một cho js bình thường của bạn và một cho js rút gọn. Sau đó, bạn nên xuất gói của mình với tên của nó và định cấu hình plugin UglifyJS để bao gồm các tệp min.js. Xem cấu hình webpack ví dụ để biết thêm chi tiết:

module.exports = {
 entry: {
   'bundle': './src/index.js',
   'bundle.min': './src/index.js',
 },

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

 plugins: [
   new webpack.optimize.UglifyJsPlugin({
      include: /\.min\.js$/,
      minimize: true
   })
 ]
};

Sau khi chạy webpack, bạn sẽ nhận được bundle.js và bundle.min.js trong thư mục dist của bạn, không cần thêm plugin.


giải thích không được chấp nhận
Olaf
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.