Jak zbudować zminimalizowany i nieskompresowany pakiet za pomocą pakietu WebPack?

233

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

Buduję z

$ webpack

W moim distfolderze dostaję tylko

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

Chciałbym również zobaczyć nieskompresowane bundle.js

Dziękuję Ci
źródło

Odpowiedzi:

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

Od wersji Webpack 4 webpack.optimize.UglifyJsPluginjest przestarzały, a jego użycie powoduje błąd:

webpack.optimize.UglifyJsPlugin został usunięty, zamiast tego użyj config.optimization.minimize

Jak wyjaśnia instrukcja , wtyczkę można zastąpić minimizeopcją. Niestandardową konfigurację można dostarczyć do wtyczki, określając UglifyJsPlugininstancję:

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

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

To wystarczy do prostej konfiguracji. Bardziej skutecznym rozwiązaniem jest użycie Gulp razem z Webpack i zrobienie tego samego w jednym przejściu.

Estus Flask
źródło
1
@FeloVilches Nie wspominam nawet, że odbywa się to w pliku webpack.config.js, ale zakłada się, że gdy będziemy w ziemi Node.js i użyjemy pakietu Webpack.
Estus Flask,
3
Hmm, w Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
paczce web
3
Aktualizacja: teraz możesz użyć wtyczki terser-webpack-plugin webpack.js.org/plugins/terser-webpack-plugin
ijse
156

Możesz użyć jednego pliku konfiguracyjnego i dołączyć warunkowo wtyczkę UglifyJS za pomocą zmiennej środowiskowej:

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

a następnie ustaw tę zmienną, kiedy chcesz ją zminimalizować:

$ PROD_ENV=1 webpack


Edytować:

Jak wspomniano w komentarzach, NODE_ENVjest ogólnie używany (zgodnie z konwencją) do stwierdzenia, czy dane środowisko jest środowiskiem produkcyjnym czy programistycznym. Aby to sprawdzić, możesz również ustawić var PROD = (process.env.NODE_ENV === 'production')i kontynuować normalnie.

lyosef
źródło
6
Węzeł ma jedną „domyślną” zmienną o nazwie NODE_ENV.
JCM
2
Czy opcja nie jest wywoływana compresszamiast minimize?
Slava Fomin II
1
Tylko mała gotcha: kiedy wywołujesz webpack z argumentami, np webpack -p. Ustawienia z webpack.optimize.UglifyJsPlugin w twojej konfiguracji webpack zostaną (przynajmniej częściowo) zignorowane (przynajmniej ustawienie mangle: falsezostanie zignorowane).
Christian Ulbrich,
2
Zauważ, że generuje to tylko jeden plik na raz. Tak aby uczynić tę pracę na pytanie nie powinno być wiele podań WebPACK, webpack && webpack -p.
Estus Flask
1
Dla każdego, kto to czyta, sugerowałbym użycie definePluginzamiast tego, które moim zdaniem jest domyślnie instalowane z Webpack.
Ben Gubler
54

Możesz uruchomić webpack dwa razy z różnymi argumentami:

$ webpack --minimize

następnie sprawdź argumenty wiersza poleceń w 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());
}

...

przykład webpack.config.js

Gordon Freeman
źródło
2
Wydaje mi się bardzo prostym rozwiązaniem; podobnie jak w webpack v3.5.5 ma wbudowany przełącznik o nazwie --optimize-minimize lub -p.
synergiczny
Pomysł jest fajny, ale nie działa teraz, webpack krzyknie „Nieznany argument: zminimalizuj” Rozwiązanie: użyj --env.minimize więcej szczegółów w poniższym linku github.com/webpack/webpack/issues/2254
Zhli
Można użyć bardziej standardowego sposobu przekazywania wskazania środowiska w pakiecie internetowym: stackoverflow.com/questions/44113359/…
MaMazav
40

Aby dodać kolejną odpowiedź, flaga -p(skrót od --optimize-minimize) włączy UglifyJS z domyślnymi argumentami.

Nie dostaniesz zminimalizowanego i surowego pakietu z jednego przebiegu ani nie wygenerujesz pakietów o różnych nazwach, aby -pflaga mogła nie spełniać twojego zastosowania.

I odwrotnie, -dopcja jest krótka--debug --devtool sourcemap --output-pathinfo

Moi webpack.config.js pomija devtool, debug, pathinfo, a minmize plugin na rzecz tych dwóch flag.

everett1992
źródło
Dzięki @ everett1992, to rozwiązanie działa świetnie. Zdecydowana większość czasu, kiedy uruchamiam kompilację programistów, a kiedy skończę, używam flagi -p, aby wypluć zminimalizowaną kompilację produkcyjną. Nie ma potrzeby tworzenia dwóch osobnych konfiguracji pakietu Webpack!
pmont
36

Może się tu spóźniam, ale mam ten sam problem, więc napisałem w tym celu wtyczkę unminified-webpack-plugin .

Instalacja

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

Stosowanie

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

Wykonując powyższe czynności, otrzymasz dwa pliki library.min.js i library.js. Nie musisz uruchamiać pakietu dwa razy, to po prostu działa! ^^

Howard
źródło
Ta wtyczka wydaje się być niezgodna z SourceMapDevToolPlugin. Wszelkie sugestie dotyczące zachowania map źródłowych?
BhavikUp
@BhavikUp, nie jest obsługiwane. Czy uważasz, że naprawdę potrzebujesz mapy źródłowej, aby uzyskać wynik wraz z końcowym plikiem js?
Howard
1
„Nie trzeba uruchamiać pakietu dwa razy [...]” Fajnie, ale rozwiązanie Estusa również nie wymaga „wykonywania pakietu dwa razy” i dodatkowo nie wymaga dodawania wtyczki innej firmy.
Louis
@Howard Man, masz rację :). Przynajmniej dla mnie. Wielkie dzięki za świetną wtyczkę! Wydaje się działać idealnie z opcją webpack 2 i -p.
gaperton
34

Moim zdaniem o wiele łatwiej jest bezpośrednio korzystać z narzędzia UglifyJS :

  1. npm install --save-dev uglify-js
  2. Używaj webpacka jak zwykle, np. Budując ./dst/bundle.jsplik.
  3. Dodaj buildpolecenie do package.json:

    "scripts": {
        "build": "webpack && uglifyjs ./dst/bundle.js -c -m -o ./dst/bundle.min.js --source-map ./dst/bundle.min.js.map"
    }
  4. Ilekroć chcesz zbudować pakiet, a także nielepszony kod i sourcemaps, uruchom npm run buildpolecenie.

Nie musisz instalować uglify-js globalnie, po prostu zainstaluj go lokalnie dla projektu.

Dave Kerr
źródło
tak, jest to łatwe rozwiązanie, które pozwala budować tylko raz
Flion
15

Możesz utworzyć dwie konfiguracje dla webpacka, jedną, która minimalizuje kod, a drugą, która tego nie robi (wystarczy usunąć wiersz optimize.UglifyJSPlugin), a następnie uruchomić obie konfiguracje w tym samym czasie $ webpack && webpack --config webpack.config.min.js

trekforever
źródło
2
Dzięki, działa to świetnie, ale na pewno byłoby miło, gdyby istniał lepszy sposób, niż utrzymywanie dwóch plików konfiguracyjnych, biorąc pod uwagę, że jest to tak częsty przypadek użycia (prawie jakakolwiek kompilacja biblioteki).
Rick Strahl,
12

Zgodnie z tym wierszem: https://github.com/pingyuanChen/webpack-uglify-js-plugin/blob/master/index.js#L117

powinno być coś takiego:

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

Rzeczywiście możesz mieć wiele kompilacji, eksportując różne konfiguracje zgodnie ze swoimi strategiami env / argv.

Idealny
źródło
Dziękuję za pomocną odpowiedź na stare, ale jakoś wciąż aktualne pytanie, Mauro ^ _ ^
Dziękuję
1
Nie mogę znaleźć opcji minimizew dokumentach. Być może jest to przestarzałe?
adi518
@ adi518 Może używasz nowszej wersji wtyczki, a nie tej, zawartej w pakiecie internetowym?
theppand
4

webpack entry.jsx ./output.js -p

działa dla mnie z -pflagą.

gdfgdfg
źródło
4

Możesz sformatować plik webpack.config.js w następujący sposób:

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

A następnie, aby skompilować go w sposób nieuprawniony (w głównym katalogu projektu):

$ webpack

Aby zbudować to zminimalizowane uruchomienie:

$ NODE_ENV=production webpack

Uwagi: Upewnij się, że w wersji niezminimalizowanej zmienisz nazwę pliku wyjściowego na library.jsi dla zminimalizowanego, library.min.jsaby się nie zastępowały.

cnzac
źródło
3

Miałem ten sam problem i musiałem spełnić wszystkie te wymagania:

  • Wersja zminimalizowana + nie zminimalizowana (jak w pytaniu)
  • ES6
  • Wiele platform (Windows + Linux).

W końcu rozwiązałem to w następujący sposób:

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

Następnie mogę zbudować (Nie zapomnij npm installwcześniej):

npm run-script build
MaMazav
źródło
Otrzymałem ten błąd BŁĄD w nieznanym: Niepoprawny typ wartości
Kushal Jain
3

Znalazłem nowe rozwiązanie tego problemu.

Wykorzystuje to tablicę konfiguracji, aby umożliwić pakietowi WWW tworzenie równoległej wersji zminimalizowanej i niezminimalizowanej. To przyspiesza kompilację. Nie trzeba uruchamiać pakietu dwa razy. Nie potrzebujesz dodatkowych wtyczek. Po prostu 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;
  }
};

Uruchomienie webpackspowoduje zbudowanie tylko wersji nie zminimalizowanej.

Uruchomienie webpack --env=productionspowoduje zbudowanie wersji zminimalizowanej i niezminimalizowanej w tym samym czasie.

Rannie Aguilar Peralta
źródło
1

Powinieneś wyeksportować tablicę w następujący sposób:

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'),
];
Dominik
źródło
0

Możesz zdefiniować dwa punkty wejścia w konfiguracji pakietu internetowego, jeden dla normalnego js, ​​a drugi dla zminimalizowanego js. Następnie powinieneś wyprowadzić pakiet z jego nazwą i skonfigurować wtyczkę UglifyJS, aby zawierała pliki min.js. Aby uzyskać więcej informacji, zobacz przykładową konfigurację pakietu internetowego:

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

Po uruchomieniu pakietu WebPack dostaniesz plik bundle.js i bundle.min.js w folderze dist, bez potrzeby instalowania dodatkowej wtyczki.

dyg
źródło
nieaktualne wyjaśnienia
Olaf