Comment construire un bundle minifié et non compressé avec webpack?

233

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

Je construis avec

$ webpack

Dans mon distdossier, je reçois seulement

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

J'aimerais aussi voir le non compressé bundle.js

Je vous remercie
la source

Réponses:

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

Depuis Webpack 4, webpack.optimize.UglifyJsPluginest obsolète et son utilisation entraîne une erreur:

webpack.optimize.UglifyJsPlugin a été supprimé, utilisez plutôt config.optimization.minimize

Comme l' explique le manuel , le plugin peut être remplacé par minimizeoption. Une configuration personnalisée peut être fournie au plugin en spécifiant l' UglifyJsPlugininstance:

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

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

Cela fait le travail pour une configuration simple. Une solution plus efficace consiste à utiliser Gulp avec Webpack et à faire la même chose en un seul passage.

Flacon Estus
la source
1
@FeloVilches Je ne mentionne même pas que cela se fait dans webpack.config.js, mais cela est présumé une fois que nous sommes dans le pays Node.js et utilisons Webpack.
Estus Flask
3
Hmm, dans le webpack 4, j'ai:Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
intitulé le
3
Mise à jour: vous pouvez maintenant utiliser terser-webpack-plugin webpack.js.org/plugins/terser-webpack-plugin
ijse
156

Vous pouvez utiliser un seul fichier de configuration et inclure le plugin UglifyJS sous condition à l'aide d'une variable d'environnement:

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

puis définissez simplement cette variable lorsque vous souhaitez la réduire:

$ PROD_ENV=1 webpack


Éditer:

Comme mentionné dans les commentaires, NODE_ENVest généralement utilisé (par convention) pour indiquer si un environnement particulier est un environnement de production ou de développement. Pour le vérifier, vous pouvez également définir var PROD = (process.env.NODE_ENV === 'production')et continuer normalement.

lyosef
la source
6
Le nœud a une variable "par défaut" pour cela, il s'appelle NODE_ENV.
JCM
2
L'option n'est-elle pas appelée à la compressplace de minimize?
Slava Fomin II
1
Juste un petit problème: lorsque vous appelez webpack avec des arguments, comme webpack -ples paramètres de webpack.optimize.UglifyJsPlugin dans votre configuration de webpack seront (au moins partiellement) ignorés (au moins le paramètre mangle: falseest ignoré).
Christian Ulbrich
2
Notez que cela ne génère qu'un seul fichier à la fois. Ainsi, afin de faire ce travail pour la question il devrait y avoir plusieurs passes de webpack, webpack && webpack -p.
Estus Flask
1
Pour tous ceux qui liront ceci, je suggère d'utiliser à la definePluginplace, qui je pense est installé par défaut avec Webpack.
Ben Gubler
54

Vous pouvez exécuter Webpack deux fois avec différents arguments:

$ webpack --minimize

puis vérifiez les arguments de la ligne de commande dans 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());
}

...

exemple webpack.config.js

Gordon Freeman
la source
2
Semble une solution très simple pour moi; juste que depuis webpack v3.5.5, il a un commutateur intégré appelé --optimize-minimiser ou -p.
synergique du
L'idée est cool, mais ne fonctionne pas maintenant, webpack criera "Argument inconnu: minimiser" Solution: utilisez --env.minimize plus de détails dans le lien suivant github.com/webpack/webpack/issues/2254
Zhli
Peut utiliser un moyen plus standard pour passer l'indication d'environnement dans le webpack: stackoverflow.com/questions/44113359/…
MaMazav
40

Pour ajouter une autre réponse, le drapeau -p(abréviation de --optimize-minimize) activera UglifyJS avec des arguments par défaut.

Vous n'obtiendrez pas un bundle réduit et brut lors d'une seule exécution ou ne générerez pas de bundles nommés différemment, de sorte que l' -pindicateur peut ne pas correspondre à votre cas d'utilisation.

Inversement, l' -doption est courte pour--debug --devtool sourcemap --output-pathinfo

Mon webpack.config.js passe sous silence devtool, debug, pathinfoet le minmize plug - in en faveur de ces deux drapeaux.

everett1992
la source
Merci @ everett1992, cette solution fonctionne très bien. La grande majorité du temps, j'exécute la version de développement, puis lorsque j'ai terminé, j'utilise l'indicateur -p pour cracher une version de production réduite. Pas besoin de créer deux configurations Webpack séparées!
pmont
36

Je suis peut-être en retard ici, mais j'ai le même problème, j'ai donc écrit un plugin non-webpack à cet effet.

Installation

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

Usage

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

En procédant comme ci-dessus, vous obtiendrez deux fichiers library.min.js et library.js. Pas besoin d'exécuter le webpack deux fois, cela fonctionne! ^^

Howard
la source
Ce plugin ne semble pas compatible avec SourceMapDevToolPlugin. Des suggestions pour conserver les cartes sources?
BhavikUp
@BhavikUp, ce n'est pas pris en charge. Pensez-vous que vous avez vraiment besoin que la carte source soit sortie avec le fichier js final?
Howard
1
"Pas besoin d'exécuter deux fois webpack [...]" Bien , mais la solution d' Estus ne nécessite pas non plus "d'exécuter deux fois webpack" et ne nécessite pas en plus d'ajouter un plugin tiers.
Louis
@Howard Man, vous avez raison à l'heure :). Au moins pour moi. Merci beaucoup pour ce super plug-in! Semble fonctionner parfaitement avec l'option webpack 2 et -p.
gaperton
34

À mon avis, il est beaucoup plus facile d'utiliser directement l'outil UglifyJS :

  1. npm install --save-dev uglify-js
  2. Utilisez le webpack comme d'habitude, par exemple en créant un ./dst/bundle.jsfichier.
  3. Ajoutez une buildcommande à votre package.json:

    "scripts": {
        "build": "webpack && uglifyjs ./dst/bundle.js -c -m -o ./dst/bundle.min.js --source-map ./dst/bundle.min.js.map"
    }
  4. Chaque fois que vous souhaitez créer un bundle ainsi que du code uglified et des sourcemaps, exécutez la npm run buildcommande.

Pas besoin d'installer uglify-js globalement, installez-le simplement localement pour le projet.

Dave Kerr
la source
oui, c'est une solution facile qui vous permet de construire une seule fois
Flion
15

Vous pouvez créer deux configurations pour webpack, une qui réduit le code et une qui ne le fait pas (supprimez simplement la ligne d'optimiser.UglifyJSPlugin), puis exécutez les deux configurations en même temps $ webpack && webpack --config webpack.config.min.js

trekforever
la source
2
Merci, cela fonctionne très bien, mais ce serait certainement bien s'il y avait une meilleure façon de le faire que de maintenir deux fichiers de configuration étant donné qu'il s'agit d'un cas d'utilisation courant (à peu près n'importe quelle génération de bibliothèque).
Rick Strahl
12

Selon cette ligne: https://github.com/pingyuanChen/webpack-uglify-js-plugin/blob/master/index.js#L117

devrait être quelque chose comme:

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

En effet, vous pouvez avoir plusieurs builds en exportant différentes configurations en fonction de vos stratégies env / argv.

Ideabile
la source
Merci pour votre réponse utile sur une question vieillie mais en quelque sorte toujours pertinente, Mauro ^ _ ^
Merci
1
Impossible de trouver l'option minimizedans les documents. Peut-être que c'est obsolète?
adi518
@ adi518 Peut-être que vous utilisez une version plus récente du plugin et non celle fournie avec le webpack?
expand
4

webpack entry.jsx ./output.js -p

travaille pour moi, avec -pdrapeau.

gdfgdfg
la source
4

Vous pouvez formater votre webpack.config.js comme ceci:

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

Et puis pour le construire en exécution non minimisée (dans le répertoire principal du projet):

$ webpack

Pour le construire en run minifié:

$ NODE_ENV=production webpack

Remarques: Assurez-vous que pour la version non minimisée, vous modifiez le nom du fichier de sortie pour library.jset pour le minifié library.min.jsafin qu'ils ne se remplacent pas.

cnzac
la source
3

J'ai eu le même problème et j'ai dû répondre à toutes ces exigences:

  • Version minifiée + non minifiée (comme dans la question)
  • ES6
  • Multiplateforme (Windows + Linux).

Je l'ai finalement résolu comme suit:

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

Ensuite, je peux construire par (N'oubliez pas npm installavant):

npm run-script build
MaMazav
la source
J'ai obtenu cette erreur ERREUR en inconnu: valeur de typeof invalide
Kushal Jain
3

J'ai trouvé une nouvelle solution à ce problème.

Cela utilise un tableau de configuration pour permettre au webpack de construire la version minifiée et non minifiée en parallèle. Cela rend la construction plus rapide. Pas besoin d'exécuter le webpack deux fois. Pas besoin de plugins supplémentaires. Juste 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'exécution webpackne génèrera que la version non réduite.

L'exécution webpack --env=productiongénérera la version minifiée et non minifiée en même temps.

Rannie Aguilar Peralta
la source
1

Vous devez exporter un tableau comme celui-ci:

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'),
];
Dominique
la source
0

Vous pouvez définir deux points d'entrée dans votre configuration de webpack, l'un pour vos js normaux et l'autre pour les js minifiés. Ensuite, vous devez sortir votre bundle avec son nom et configurer le plugin UglifyJS pour inclure les fichiers min.js. Voir l'exemple de configuration de webpack pour plus de détails:

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

Après avoir exécuté webpack, vous obtiendrez bundle.js et bundle.min.js dans votre dossier dist, pas besoin de plugin supplémentaire.

dyg
la source
explication obsolète
Olaf