Come creare un bundle minimizzato e non compresso con il webpack?


233

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

Sto costruendo con

$ webpack

Nella mia distcartella, sto solo ricevendo

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

Mi piacerebbe anche vedere il non compresso bundle.js

Risposte:


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

Dal momento che Webpack 4, webpack.optimize.UglifyJsPluginè stato deprecato e il suo utilizzo provoca errori:

webpack.optimize.UglifyJsPlugin è stato rimosso, utilizza invece config.optimization.minimize

Come spiegato nel manuale , il plug-in può essere sostituito con l' minimizeopzione. La configurazione personalizzata può essere fornita al plug-in specificando l' UglifyJsPluginistanza:

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

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

Questo fa il lavoro per una semplice configurazione. Una soluzione più efficace è utilizzare Gulp insieme a Webpack e fare la stessa cosa in un solo passaggio.


1
@FeloVilches Non ho nemmeno menzionato che questo è fatto in webpack.config.js, ma questo è presunto una volta che siamo nella terra di Node.js e usiamo Webpack.
Estus Flask,

3
Hmm, nel webpack 4 ho ottenuto:Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
entithat

3
Aggiornamento: ora puoi usare terser-webpack-plugin webpack.js.org/plugins/terser-webpack-plugin
ijse

156

È possibile utilizzare un singolo file di configurazione e includere il plug-in UglifyJS in modo condizionale utilizzando una variabile di ambiente:

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

e quindi basta impostare questa variabile quando si desidera minimizzarla:

$ PROD_ENV=1 webpack


Modificare:

Come menzionato nei commenti, NODE_ENVviene generalmente utilizzato (per convenzione) per stabilire se un determinato ambiente è un ambiente di produzione o di sviluppo. Per verificarlo, puoi anche impostare var PROD = (process.env.NODE_ENV === 'production')e continuare normalmente.


6
Il nodo ha una variabile "predefinita" per questo, si chiama NODE_ENV.
JCM,

2
L'opzione non è chiamata compressinvece di minimize?
Slava Fomin II

1
Solo un piccolo gotcha: quando chiami webpack con argomenti, come webpack -ple impostazioni di webpack.optimize.UglifyJsPlugin nella tua configurazione webpack verrà (almeno in parte) ignorato (almeno l'impostazione mangle: falseviene ignorata).
Christian Ulbrich,

2
Si noti che questo genera solo un file alla volta. Quindi, al fine di fare questo lavoro per la questione ci dovrebbe essere più passaggi webpack, webpack && webpack -p.
Estus Flask,

1
Per chiunque legga questo, suggerirei definePlugininvece di utilizzare , che penso sia installato di default con Webpack.
Ben Gubler,

54

Puoi eseguire il webpack due volte con diversi argomenti:

$ webpack --minimize

quindi controlla gli argomenti della riga di comando in 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());
}

...

esempio webpack.config.js


2
Mi sembra una soluzione molto semplice; solo che a partire da webpack v3.5.5 ha uno switch incorporato chiamato --optimize-minim o -p.
sinergico

L'idea è interessante, ma non funziona ora, il webpack urlerà "Argomento sconosciuto: minimizza" Soluzione: usa --env.minimize maggiori dettagli nel seguente link github.com/webpack/webpack/issues/2254
Zhli

Può usare modo più standard di passare indicazione ambiente in webpack: stackoverflow.com/questions/44113359/...
MaMazav

40

Per aggiungere un'altra risposta, il flag -p(abbreviazione di --optimize-minimize) abiliterà UglifyJS con argomenti predefiniti.

Non otterrai un bundle minimizzato e grezzo da una singola esecuzione o non genererai bundle con nomi diversi, quindi il -pflag potrebbe non soddisfare il tuo caso d'uso.

Al contrario l' -dopzione è breve--debug --devtool sourcemap --output-pathinfo

I miei webpack.config.js omette devtool, debug, pathinfo, e il minmize plug a favore di questi due bandiere.


Grazie @ everett1992, questa soluzione funziona alla grande. La maggior parte delle volte eseguo la build di sviluppo, quindi quando ho finito uso il flag -p per sputare una build di produzione ridotta. Non è necessario creare due configurazioni Webpack separate!
pmont

36

Forse sono in ritardo qui, ma ho lo stesso problema, quindi a questo scopo ho scritto un plug-in webmin unminified .

Installazione

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

uso

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

Facendo come sopra, otterrai due file library.min.js e library.js. Non è necessario eseguire il webpack due volte, funziona e basta! ^^


Questo plugin sembra non essere compatibile con SourceMapDevToolPlugin. Qualche suggerimento per conservare le mappe di origine?
BhavikUp,

@BhavikUp, non è supportato. Pensi di aver davvero bisogno che la mappa sorgente sia prodotta insieme al file js finale?
Howard,

1
"Non è necessario eseguire il webpack due volte [...]" Bella, ma la soluzione di estus non richiede nemmeno "eseguire il webpack due volte" e inoltre non richiede l'aggiunta di un plug-in di terze parti.
Louis

@Howard Man, hai ragione in tempo :). Almeno per me. Grazie mille per l'ottimo plug-in! Sembra funzionare perfettamente con l'opzione webpack 2 e -p.
gaperton,

34

Secondo me è molto più semplice usare direttamente lo strumento UglifyJS :

  1. npm install --save-dev uglify-js
  2. Usa il webpack normalmente, ad es ./dst/bundle.js. Costruendo un file.
  3. Aggiungi un buildcomando al tuo package.json:

    "scripts": {
        "build": "webpack && uglifyjs ./dst/bundle.js -c -m -o ./dst/bundle.min.js --source-map ./dst/bundle.min.js.map"
    }
  4. Ogni volta che vuoi creare un bundle, nonché codice e sourcemap mappati, esegui il npm run buildcomando.

Non è necessario installare uglify-js a livello globale, basta installarlo localmente per il progetto.


sì, questa è una soluzione facile che ti permette di costruire solo una volta
Flion

15

Puoi creare due configurazioni per il webpack, uno che minimizza il codice e uno che non lo fa (basta rimuovere la riga optim.UglifyJSPlugin) e quindi eseguire entrambe le configurazioni contemporaneamente $ webpack && webpack --config webpack.config.min.js


2
Grazie, funziona alla grande, ma sarebbe sicuramente bello se ci fosse un modo migliore per farlo che mantenere due file di configurazione dato che questo è un caso d'uso così comune (praticamente qualsiasi build di libreria).
Rick Strahl,

12

Secondo questa linea: https://github.com/pingyuanChen/webpack-uglify-js-plugin/blob/master/index.js#L117

dovrebbe essere qualcosa del tipo:

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

In effetti puoi avere più build esportando configurazioni diverse secondo le tue strategie env / argv.


Grazie per la tua utile risposta a una domanda invecchiata ma in qualche modo ancora pertinente, Mauro ^ _ ^
Grazie

1
Impossibile trovare l'opzione minimizenei documenti. Forse è deprecato?
adi518,

@ adi518 Forse stai usando una versione più recente del plugin e non quella, inclusa nel webpack?
thexpand

4

webpack entry.jsx ./output.js -p

funziona per me, con la -pbandiera.


4

Puoi formattare il tuo webpack.config.js in questo modo:

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

E quindi per crearlo non minimizzato (nella directory principale del progetto):

$ webpack

Per costruirlo corsa minimizzata:

$ NODE_ENV=production webpack

Note: assicurarsi che per la versione non minificata si cambi il nome del file di output in library.jse per quelli minimizzati in library.min.jsmodo che non si sovrascrivano l'un l'altro.


3

Ho avuto lo stesso problema e ho dovuto soddisfare tutti questi requisiti:

  • Versione minimizzata + Non minimizzata (come nella domanda)
  • ES6
  • Cross platform (Windows + Linux).

Alla fine l'ho risolto come segue:

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

Quindi posso costruire da (non dimenticare di npm installprima):

npm run-script build

Ho riscontrato questo errore ERRORE in sconosciuto: Tipo di valore non valido
Kushal Jain,

3

Ho trovato una nuova soluzione per questo problema.

Questo utilizza una matrice di configurazione per consentire al webpack di costruire in parallelo la versione minimizzata e non minimizzata. Questo rende la costruzione più veloce. Non è necessario eseguire il webpack due volte. Non sono necessari plugin aggiuntivi. Solo 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;
  }
};

L'esecuzione webpackgenererà solo la versione non ridotta.

L'esecuzione webpack --env=productiongenererà contemporaneamente la versione ridotta e non ridotta.


1

Dovresti esportare un array come questo:

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

Puoi definire due punti di ingresso nella configurazione del tuo webpack, uno per i tuoi js normali e l'altro per i js minimizzati. Quindi dovresti produrre il tuo bundle con il suo nome e configurare il plugin UglifyJS per includere i file min.js. Vedi l'esempio di configurazione del webpack per maggiori dettagli:

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

Dopo aver eseguito webpack, otterrai bundle.js e bundle.min.js nella cartella dist, senza bisogno di plug-in aggiuntivo.


spiegazione deprecata
Olaf
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.