Spec-Zone.ru › webpack 4

Производство

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

Это руководство основано на Устранении лишнего кода и Разработке. Пожалуйста, убедитесь, что вы знакомы с концепциями/настройками, представленными в этих руководствах, прежде чем продолжить.

Настройка

Цели сборки разработки и производства сильно различаются. В разработке мы хотим сильную карту сопоставления исходных файлов и локальный сервер с функцией живой перезагрузки или заменой модулей на лету. В производстве наши цели смещаются на фокусировку на сжатых пакетах, более легких картах сопоставления исходных файлов и оптимизированных ресурсах для улучшения времени загрузки. При такой логической сепарации мы обычно рекомендуем писать отдельные конфигурации webpack для каждой среды.

Хотя мы разделим специфические части производства и разработки, обратите внимание, что мы все равно будем поддерживать общую конфигурацию, чтобы сохранить DRY-принцип. Для объединения этих конфигураций мы будем использовать утилиту под названием webpack-merge. Благодаря общей конфигурации, нам не нужно будет дублировать код в конфигурациях, специфичных для каждой среды.

Давайте начнем с установки webpack-merge и разделения уже обработанных частей из предыдущих руководств:

npm install --save-dev webpack-merge

project

  webpack-demo
  |- package.json
- |- webpack.config.js
+ |- webpack.common.js
+ |- webpack.dev.js
+ |- webpack.prod.js
  |- /dist
  |- /src
    |- index.js
    |- math.js
  |- /node_modules

webpack.common.js

+ const path = require('path');
+ const { CleanWebpackPlugin } = require('clean-webpack-plugin');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
+
+ module.exports = {
+   entry: {
+     app: './src/index.js',
+   },
+   plugins: [
+     // new CleanWebpackPlugin(['dist/*']) for < v2 versions of CleanWebpackPlugin
+     new CleanWebpackPlugin(),
+     new HtmlWebpackPlugin({
+       title: 'Production',
+     }),
+   ],
+   output: {
+     filename: '[name].bundle.js',
+     path: path.resolve(__dirname, 'dist'),
+   },
+ };

webpack.dev.js

+ const merge = require('webpack-merge');
+ const common = require('./webpack.common.js');
+
+ module.exports = merge(common, {
+   mode: 'development',
+   devtool: 'inline-source-map',
+   devServer: {
+     contentBase: './dist',
+   },
+ });

webpack.prod.js

+ const merge = require('webpack-merge');
+ const common = require('./webpack.common.js');
+
+ module.exports = merge(common, {
+   mode: 'production',
+ });

В webpack.common.js, мы теперь настроили нашу конфигурацию entry и output и добавили необходимые плагины для обеих сред. В webpack.dev.js, мы установили mode в development. Также мы добавили рекомендуемые devtool для этой среды (сильное сопоставление исходных файлов), а также нашу простую конфигурацию devServer. Наконец, в webpack.prod.js, mode установлено на production, которое загружает TerserPlugin, которое было впервые представлено в руководстве по устранению лишнего кода.

Обратите внимание на использование merge() в конфигурациях, специфичных для среды, для лёгкого включения нашей общей конфигурации в dev и prod. Инструмент webpack-merge предлагает ряд расширенных функций для объединения, но для нашего случая нам не понадобятся ни одна из них.

Сценарии NPM

Теперь изменим наши сценарии npm, чтобы использовать новые файлы конфигурации. Для сценария start, который запускает webpack-dev-server, мы будем использовать webpack.dev.js, а для сценария build, который запускает webpack для создания сборки производства, мы будем использовать webpack.prod.js.

package.json

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "src/index.js",
    "scripts": {
-     "start": "webpack-dev-server --open",
+     "start": "webpack-dev-server --open --config webpack.dev.js",
-     "build": "webpack"
+     "build": "webpack --config webpack.prod.js"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.17",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "express": "^4.15.3",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^4.30.0",
      "webpack-dev-middleware": "^1.12.0",
      "webpack-dev-server": "^2.9.1",
      "webpack-merge": "^4.1.0",
      "xml-loader": "^1.2.1"
    }
  }

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

Указание режима

Многие библиотеки будут использовать переменную process.env.NODE_ENV для определения того, что должно быть включено в библиотеку. Например, когда среда не производственная, некоторые библиотеки могут добавлять дополнительное логирование и тестирование для облегчения отладки. Однако, при process.env.NODE_ENV === 'production', они могут удалять или добавлять значительные части кода, чтобы оптимизировать работу для ваших реальных пользователей. Начиная с webpack v4, указание mode автоматически настраивает DefinePlugin для вас:

webpack.prod.js

  const merge = require('webpack-merge');
  const common = require('./webpack.common.js');

  module.exports = merge(common, {
    mode: 'production',
  });

Фактически, NODE_ENV - это системная переменная среды, которую Node.js предоставляет работающим скриптам. Она используется по соглашению для определения поведения dev/prod утилитами сервера, скриптами сборки и клиентскими библиотеками. Вопреки ожиданиям, process.env.NODE_ENV не устанавливается в "production" **внутри** скрипта сборки webpack.config.js, см. #2537. Таким образом, условные операторы, такие как process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js' в конфигурациях webpack, не работают как ожидается.

Если вы используете библиотеку, такую как react, вы должны увидеть значительное уменьшение размера пакета после добавления этого плагина. Также обратите внимание, что любой наш локальный /src код может использовать это, поэтому следующее условие будет валидным:

src/index.js

  import { cube } from './math.js';
+
+ if (process.env.NODE_ENV !== 'production') {
+   console.log('Looks like we are in development mode!');
+ }

  function component() {
    const element = document.createElement('pre');

    element.innerHTML = [
      'Hello webpack!',
      '5 cubed is equal to ' + cube(5)
    ].join('\n\n');

    return element;
  }

  document.body.appendChild(component());

Минимизация

webpack v4+ по умолчанию минимизирует ваш код в production mode.

Обратите внимание, что хотя TerserPlugin - отличная отправная точка для минимизации и используется по умолчанию, существуют и другие варианты. Вот несколько более популярных:

  • BabelMinifyWebpackPlugin
  • ClosureWebpackPlugin

Если вы решите попробовать другой плагин для минимизации, убедитесь, что ваш новый выбор также удаляет мёртвый код, как описано в руководстве по устранению лишнего кода, и используйте его в качестве optimization.minimizer.

Карты сопоставления исходных файлов

Мы рекомендуем включить карты сопоставления исходных файлов в производственной среде, так как они полезны для отладки и проведения бенчмаркинговых тестов. Тем не менее, вы должны выбрать один с достаточно быстрой скоростью сборки, рекомендуемый для использования в производстве (см. devtool). В этом руководстве мы будем использовать опцию source-map в производственной среде, в отличие от inline-source-map, которую мы использовали в среде разработки:

webpack.prod.js

  const merge = require('webpack-merge');
  const common = require('./webpack.common.js');

  module.exports = merge(common, {
    mode: 'production',
+   devtool: 'source-map',
  });

Избегайте использования inline-*** и eval-*** в производстве, так как они могут увеличить размер пакета и снизить общую производительность.

Минимизация CSS

Минимизация CSS крайне важна для производственной среды. Обратитесь к разделу Минимизация для производства.

Альтернативы командной строки

Некоторые из описанных выше действий также могут быть выполнены с помощью командной строки. Например, флаг --optimize-minimize включит TerserPlugin за кулисами. Флаг --define process.env.NODE_ENV="'production'" сделает то же самое для экземпляра DefinePlugin описанного выше. А webpack -p автоматически вызовет оба этих флага и, следовательно, включит нужные плагины.

Хотя эти сокращённые методы удобны, мы обычно рекомендуем использовать конфигурацию, так как лучше понимать, что для вас делается в обоих случаях. Конфигурация также даёт вам больший контроль над точной настройкой других параметров в обоих плагинах.

© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://v4.webpack.js.org/guides/production

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API