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


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')и продолжить в обычном режиме.


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, это решение прекрасно работает. Большую часть времени я запускаю сборку 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


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.


Спасибо за ваш полезный ответ на вопрос, который все еще актуален, Мауро ^ _ ^
Спасибо,

1
Не могу найти вариант minimizeв документах. Возможно, это устарело?
adi518

@ adi518 Может быть, вы используете более новую версию плагина, а не ту, которая включена в веб-пакет?
thexpand


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чтобы они не перезаписывали друг друга.


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

Я получил эту ошибку ОШИБКА в неизвестно: Неверное значение 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'),
];

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, не требуя дополнительного плагина.


устарела экспликация
Олаф
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.