Bagaimana cara membangun bundel yang diperkecil dan tidak terkompresi dengan webpack?

233

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

Saya membangun dengan

$ webpack

Di distfolder saya , saya hanya mendapatkan

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

Saya juga ingin melihat yang tidak terkompresi bundle.js

Terima kasih
sumber

Jawaban:

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

Sejak Webpack 4, webpack.optimize.UglifyJsPlugintelah ditinggalkan dan penggunaannya menghasilkan kesalahan:

webpack.optimize.UglifyJsPlugin telah dihapus, silakan gunakan config.optimization.minimize sebagai gantinya

Seperti yang dijelaskan manual , plugin dapat diganti dengan minimizeopsi. Konfigurasi khusus dapat disediakan untuk plugin dengan menentukan UglifyJsPlugincontoh:

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

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

Ini melakukan pekerjaan untuk pengaturan yang sederhana. Solusi yang lebih efektif adalah dengan menggunakan Gulp bersama-sama dengan Webpack dan melakukan hal yang sama dalam satu pass.

Estus Flask
sumber
1
@FeloVilches Saya bahkan tidak menyebutkan bahwa ini dilakukan di webpack.config.js, tetapi ini dianggap begitu kita berada di Node.js mendarat dan menggunakan Webpack.
Estus Flask
3
Hmm, di webpack 4 saya mendapat:Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
entithat
3
Pembaruan: sekarang Anda dapat menggunakan terser-webpack-plugin webpack.js.org/plugins/terser-webpack-plugin
ijse
156

Anda dapat menggunakan file konfigurasi tunggal, dan menyertakan plugin UglifyJS dengan menggunakan variabel lingkungan:

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

dan kemudian setel variabel ini saat Anda ingin memperkecilnya:

$ PROD_ENV=1 webpack


Edit:

Seperti disebutkan dalam komentar, NODE_ENVumumnya digunakan (dengan konvensi) untuk menyatakan apakah lingkungan tertentu adalah produksi atau lingkungan pengembangan. Untuk memeriksanya, Anda juga dapat mengatur var PROD = (process.env.NODE_ENV === 'production'), dan melanjutkan secara normal.

Losef
sumber
6
Node memiliki satu variabel "default" untuk itu, itu disebut NODE_ENV.
JCM
2
Bukankah opsi dipanggil compressbukan minimize?
Slava Fomin II
1
Hanya sedikit saja: ketika Anda memanggil webpack dengan argumen, seperti webpack -ppengaturan dari webpack.optimize.UglifyJsPlugin dalam konfigurasi webpack Anda akan (setidaknya sebagian) diabaikan (setidaknya pengaturan mangle: falsediabaikan).
Christian Ulbrich
2
Perhatikan bahwa ini hanya menghasilkan satu file pada satu waktu. Jadi untuk membuat ini berfungsi untuk pertanyaan harus ada beberapa melewati Webpack webpack && webpack -p,.
Estus Flask
1
Bagi siapa pun yang membaca ini, saya akan menyarankan menggunakan definePlugin, yang saya pikir diinstal secara default dengan Webpack.
Ben Gubler
54

Anda dapat menjalankan webpack dua kali dengan berbagai argumen:

$ webpack --minimize

kemudian periksa argumen baris perintah di 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());
}

...

contoh webpack.config.js

Gordon Freeman
sumber
2
Tampaknya solusi yang sangat sederhana bagi saya; Hanya saja pada webpack v3.5.5 ia memiliki saklar bawaan yang disebut --optimize-diminimalkan atau -p.
sinergis
Idenya keren, tetapi tidak berfungsi sekarang, webpack akan berteriak "Argumen tidak dikenal: meminimalkan" Solusi: gunakan --env.minimasikan detail lebih lanjut di tautan berikut github.com/webpack/webpack/issues/2254
Zhli
Dapat menggunakan cara yang lebih standar untuk melewati indikasi lingkungan di webpack: stackoverflow.com/questions/44113359/…
MaMazav
40

Untuk menambahkan jawaban lain, flag -p(kependekan dari --optimize-minimize) akan mengaktifkan UglifyJS dengan argumen default.

Anda tidak akan mendapatkan bundel yang diperkecil dan mentah dari sekali proses atau menghasilkan bundel dengan nama yang berbeda sehingga -pbendera mungkin tidak memenuhi use case Anda.

Sebaliknya -dpilihannya adalah kependekan dari--debug --devtool sourcemap --output-pathinfo

Webpack.config.js saya menghilangkan devtool, debug, pathinfo, dan minmize Plugin mendukung dua bendera ini.

everett1992
sumber
Terima kasih @ everett1992, solusi ini sangat bagus. Sebagian besar waktu saya menjalankan pengembangan dev, maka ketika saya selesai saya menggunakan flag -p untuk memuntahkan build produksi yang diperkecil. Tidak perlu membuat dua konfigurasi Webpack terpisah!
pmont
36

Mungkin saya terlambat ke sini, tetapi saya memiliki masalah yang sama, jadi saya menulis plugin-webpack-unminified untuk tujuan ini.

Instalasi

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

Pemakaian

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

Dengan melakukan seperti di atas, Anda akan mendapatkan dua file library.min.js dan library.js. Tidak perlu menjalankan webpack dua kali, itu hanya berfungsi! ^^

Howard
sumber
Plugin ini tampaknya tidak kompatibel dengan SourceMapDevToolPlugin. Ada saran untuk mempertahankan peta sumber?
BhavikUp
@ BhavikUp, itu tidak didukung. Apakah Anda pikir Anda benar-benar membutuhkan peta sumber untuk di-output bersama dengan file js terakhir?
Howard
1
"Tidak perlu menjalankan webpack dua kali [...]" Bagus, tetapi solusi estus juga tidak perlu "mengeksekusi webpack dua kali" dan juga tidak perlu menambahkan plugin pihak ketiga.
Louis
@Howard Man, Anda tepat waktu :). Setidaknya untuk saya. Terima kasih banyak untuk plug-in yang hebat! Tampaknya berfungsi sempurna dengan opsi webpack 2 dan -p.
gaperton
34

Menurut pendapat saya, jauh lebih mudah menggunakan alat UglifyJS secara langsung:

  1. npm install --save-dev uglify-js
  2. Gunakan webpack seperti biasa, misalnya membuat ./dst/bundle.jsfile.
  3. Tambahkan buildperintah ke package.json:

    "scripts": {
        "build": "webpack && uglifyjs ./dst/bundle.js -c -m -o ./dst/bundle.min.js --source-map ./dst/bundle.min.js.map"
    }
  4. Setiap kali Anda ingin membangun bundel Anda serta kode dan sourcemaps yang di-uglified, jalankan npm run buildperintah.

Tidak perlu menginstal uglify-js secara global, cukup instal secara lokal untuk proyek tersebut.

Dave Kerr
sumber
ya ini adalah solusi mudah yang memungkinkan Anda membangun hanya sekali
Flion
15

Anda dapat membuat dua konfigurasi untuk webpack, satu yang mengecilkan kode dan yang tidak (cukup hapus baris optim.UglifyJSPlugin) dan kemudian jalankan kedua konfigurasi pada saat yang sama $ webpack && webpack --config webpack.config.min.js

penjelajah trek
sumber
2
Terima kasih, ini bekerja dengan baik, tetapi tentu akan menyenangkan jika ada cara yang lebih baik untuk melakukan ini daripada mempertahankan dua file konfigurasi mengingat ini adalah kasus penggunaan umum (hampir semua perpustakaan membangun).
Rick Strahl
12

Menurut dengan baris ini: https://github.com/pingyuanChen/webpack-uglify-js-plugin/blob/master/index.js#L117

harus seperti:

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

Memang Anda dapat memiliki beberapa build dengan mengekspor konfigurasi yang berbeda sesuai dengan strategi env / argv Anda.

Ideabile
sumber
Terima kasih atas jawaban Anda yang bermanfaat pada pertanyaan yang sudah tua tapi entah bagaimana masih relevan, Mauro ^ _ ^
Terima kasih
1
Tidak dapat menemukan opsi minimizedalam dokumen. Mungkin sudah usang?
adi518
@ adi518 Mungkin Anda menggunakan versi yang lebih baru dari plugin dan bukan yang, yang dibundel dalam webpack?
thexpand
4

webpack entry.jsx ./output.js -p

bekerja untuk saya, dengan -pbendera.

gdfgdfg
sumber
4

Anda dapat memformat webpack.config.js Anda seperti ini:

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

Dan kemudian untuk membangunnya jalankan tanpaminminasi (saat berada di direktori utama proyek):

$ webpack

Untuk membangunnya, proses minimal:

$ NODE_ENV=production webpack

Catatan: Pastikan bahwa untuk versi yang tidak diubah Anda mengubah nama file output menjadi library.jsdan untuk yang diperkecil library.min.jssehingga mereka tidak saling menimpa.

cnzac
sumber
3

Saya memiliki masalah yang sama, dan harus memenuhi semua persyaratan ini:

  • Versi Minified + Non minified (seperti dalam pertanyaan)
  • ES6
  • Lintas platform (Windows + Linux).

Saya akhirnya menyelesaikannya sebagai berikut:

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

package.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"
    }
}

Maka saya dapat membangun dengan (Jangan lupa npm installsebelumnya):

npm run-script build
MaMazav
sumber
Saya mendapatkan kesalahan ini KESALAHAN dalam tidak diketahui: Nilai typeof tidak valid
Kushal Jain
3

Saya menemukan solusi baru untuk masalah ini.

Ini menggunakan array konfigurasi untuk memungkinkan webpack untuk membangun versi minified dan non-minified secara paralel. Ini membuat build lebih cepat. Tidak perlu menjalankan paket web dua kali. Tidak perlu plugin tambahan. Hanya paket 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;
  }
};

Menjalankan webpackhanya akan membangun versi non-minified.

Menjalankan webpack --env=productionakan membangun versi yang diperkecil dan tidak-diperkecil pada saat yang sama.

Rannie Aguilar Peralta
sumber
1

Anda harus mengekspor array seperti ini:

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'),
];
Dominic
sumber
0

Anda dapat menetapkan dua titik masuk dalam konfigurasi paket web Anda, satu untuk js normal dan yang lainnya untuk js yang diperkecil. Maka Anda harus mengeluarkan bundel Anda dengan namanya, dan mengonfigurasi plugin UglifyJS untuk menyertakan file min.js. Lihat contoh konfigurasi webpack untuk detail lebih lanjut:

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

Setelah menjalankan webpack, Anda akan mendapatkan bundle.js dan bundle.min.js di folder dist Anda, tidak perlu plugin tambahan.

dyg
sumber
penjelajahan yang tidak berlaku
Olaf