Как собрать миниатюрный и несжатый пакет с помощью веб-пакета?

233

Вот мой 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})
  ]
};

Я строю с

$ webpack

В моей distпапке я только получаю

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

Я также хотел бы видеть несжатый bundle.js

Спасибо
источник

Ответы:

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

Начиная с Webpack 4, webpack.optimize.UglifyJsPluginустарел, и его использование приводит к ошибке:

webpack.optimize.UglifyJsPlugin был удален, вместо этого используйте config.optimization.minimize

Как объясняется в руководстве , плагин можно заменить на minimizeопцию. Пользовательская конфигурация может быть предоставлена ​​плагину путем указания UglifyJsPluginэкземпляра:

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

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

Это делает работу для простой настройки. Более эффективное решение - использовать Gulp вместе с Webpack и делать то же самое за один проход.

Настой Эстус
источник
1
@FeloVilches Я даже не упоминаю, что это делается в webpack.config.js, но это предполагается, как только мы попадаем в Node.js и используем Webpack.
Estus Flask
3
Хм, в webpack 4 я получил:Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
entithat
3
Обновление: теперь вы можете использовать terser-webpack-plugin webpack.js.org/plugins/terser-webpack-plugin
ijse
156

Вы можете использовать один файл конфигурации и включить плагин UglifyJS, условно используя переменную окружения:

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

а затем просто установите эту переменную, когда вы хотите минимизировать ее:

$ PROD_ENV=1 webpack


Редактировать:

Как упомянуто в комментариях, NODE_ENVобычно используется (по соглашению), чтобы указать, является ли конкретная среда производственной или средой разработки. Чтобы проверить это, вы также можете установить var PROD = (process.env.NODE_ENV === 'production')и продолжить в обычном режиме.

lyosef
источник
6
Для этого у узла есть одна переменная «по умолчанию», она называется NODE_ENV.
JCM
2
Не вызывается ли опция compressвместо minimize?
Слава Фомин II
1
Просто небольшая ошибка: когда вы вызываете webpack с аргументами, например, webpack -pнастройки из webpack.optimize.UglifyJsPlugin в вашей конфигурации webpack будут (хотя бы частично) игнорироваться (по крайней мере, настройка mangle: falseигнорируется).
Кристиан Ульбрих
2
Обратите внимание, что это создает только один файл за раз. Таким образом, чтобы сделать эту работу для вопроса, должно быть несколько проходов Webpack webpack && webpack -p.
Estus Flask
1
Для тех, кто читает это, я бы предложил использовать definePluginвместо этого, который я думаю, установлен по умолчанию с Webpack.
Бен Габлер,
54

Вы можете запустить webpack дважды с разными аргументами:

$ webpack --minimize

затем проверьте аргументы командной строки в 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());
}

...

пример webpack.config.js

Гордон Фриман
источник
2
Кажется очень простым решением для меня; просто в webpack v3.5.5 он имеет встроенный ключ --optimize-minimal или -p.
синергетика
Идея классная, но не работает сейчас, веб-пакет будет кричать «Неизвестный аргумент: свести к минимуму». Решение: используйте --env.minimize, чтобы узнать подробности по следующей ссылке github.com/webpack/webpack/issues/2254
Zhli
Можно использовать более стандартный способ передачи индикации среды в веб-пакете: stackoverflow.com/questions/44113359/…
MaMazav
40

Чтобы добавить другой ответ, флаг -p(сокращение --optimize-minimize) активирует UglifyJS с аргументами по умолчанию.

Вы не получите минимизированный и необработанный пакет из одного прогона или не сгенерируете пакеты с другим именем, поэтому -pфлаг может не соответствовать вашему варианту использования.

И наоборот, -dвариант короток для--debug --devtool sourcemap --output-pathinfo

Мой webpack.config.js опускает devtool, debug, pathinfoи minmize плагина в пользу этих двух флагов.

everett1992
источник
Спасибо @ everett1992, это решение прекрасно работает. Большую часть времени я запускаю сборку dev, затем, когда я закончу, я использую флаг -p, чтобы выплевывать минимизированную производственную сборку. Нет необходимости создавать две отдельные конфигурации Webpack!
pmont
36

Может быть, я опоздал сюда, но у меня та же проблема, поэтому я написал unminified-webpack-plugin для этой цели.

Монтаж

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

использование

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

Сделав, как указано выше, вы получите два файла library.min.js и library.js. Нет необходимости выполнять webpack дважды, он просто работает! ^^

Говард
источник
Этот плагин, кажется, не совместим с SourceMapDevToolPlugin. Любые предложения, чтобы сохранить исходные карты?
BhavikUp
@BhavikUp, это не поддерживается. Как вы думаете, вам действительно нужна исходная карта для вывода вместе с окончательным файлом JS?
Говард
1
«Нет необходимости выполнять веб-пакет дважды [...]» Хорошо , но решение estus также не требует «выполнять веб-пакет дважды» и дополнительно не требует добавления стороннего плагина.
Луи
@Howard Человек, вы как раз вовремя :). По крайней мере для меня. Большое спасибо за отличный плагин! Кажется, отлично работает с опциями webpack 2 и -p.
Гапертон
34

По моему мнению, намного проще просто использовать инструмент UglifyJS напрямую:

  1. npm install --save-dev uglify-js
  2. Используйте веб-пакет как обычно, например, для создания ./dst/bundle.jsфайла.
  3. Добавьте buildкоманду к вашему package.json:

    "scripts": {
        "build": "webpack && uglifyjs ./dst/bundle.js -c -m -o ./dst/bundle.min.js --source-map ./dst/bundle.min.js.map"
    }
  4. Всякий раз, когда вы захотите собрать свой пакет, а также код и исходные карты с измененным кодом, выполните npm run buildкоманду.

Не нужно устанавливать uglify-js глобально, просто установите его локально для проекта.

Дейв Керр
источник
да, это простое решение, которое позволяет вам строить только один раз
Флион
15

Вы можете создать две конфигурации для веб-пакета, один для минимизации кода, а другой - нет (просто удалите строку optimize.UglifyJSPlugin), а затем запустите обе конфигурации одновременно $ webpack && webpack --config webpack.config.min.js

trekforever
источник
2
Спасибо, это прекрасно работает, но было бы неплохо, если бы был лучший способ сделать это, чем поддерживать два конфигурационных файла, учитывая, что это очень распространенный вариант использования (практически для любой сборки библиотеки).
Рик Страл
12

Согласно этой строке: https://github.com/pingyuanChen/webpack-uglify-js-plugin/blob/master/index.js#L117

должно быть что-то вроде:

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

Действительно, вы можете иметь несколько сборок, экспортируя различные конфигурации в соответствии со своими стратегиями env / argv.

Ideabile
источник
Спасибо за ваш полезный ответ на вопрос, который все еще актуален, Мауро ^ _ ^
Спасибо,
1
Не могу найти вариант minimizeв документах. Возможно, это устарело?
adi518
@ adi518 Может быть, вы используете более новую версию плагина, а не ту, которая включена в веб-пакет?
thexpand
4

webpack entry.jsx ./output.js -p

у меня работает, с -pфлагом.

gdfgdfg
источник
4

Вы можете отформатировать ваш webpack.config.js следующим образом:

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

А затем построить его незавершенным запуском (находясь в главном каталоге проекта):

$ webpack

Для его построения минимизирован прогон:

$ NODE_ENV=production webpack

Примечания. Убедитесь, что для неунифицированной версии вы изменили имя выходного файла на library.jsи для минимизированного, library.min.jsчтобы они не перезаписывали друг друга.

cnzac
источник
3

У меня была та же проблема, и я должен был удовлетворить все эти требования:

  • Minified + не минимизированная версия (как в вопросе)
  • ES6
  • Кроссплатформенность (Windows + Linux).

Я наконец решил это следующим образом:

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

Тогда я могу построить (не забудьте npm installраньше):

npm run-script build
MaMazav
источник
Я получил эту ошибку ОШИБКА в неизвестно: Неверное значение typeof
Kushal Jain
3

Я нашел новое решение для этой проблемы.

При этом используется массив конфигурации, позволяющий веб-пакету параллельно создавать минимизированную и не минимизированную версии. Это делает сборку быстрее. Нет необходимости запускать веб-пакет дважды. Не нужно дополнительных плагинов. Просто веб-пакет.

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

Запуск webpackтолько соберет неминифицированную версию.

Запуск webpack --env=productionсоздаст минимизированную и не минимизированную версии одновременно.

Ранни Агилар Перальта
источник
1

Вы должны экспортировать массив следующим образом:

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
источник
0

Вы можете определить две точки входа в конфигурации вашего веб-пакета, одну для вашего обычного js, а другую для минимизированного js. Затем вы должны вывести свой пакет с его именем и настроить плагин UglifyJS для включения файлов min.js. См. Пример конфигурации веб-пакета для более подробной информации:

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

После запуска webpack вы получите bundle.js и bundle.min.js в вашей папке dist, не требуя дополнительного плагина.

DYG
источник
устарела экспликация
Олаф