webpack от входа, чтобы отказаться

JavaScript Webpack

процесс сборки вебпака

Существует ряд процессов от запуска сборки веб-пакета до вывода результата:

  1. Разберите параметры конфигурации webpack.config.js, вызовите оболочку и добавьте параметры командной строки, и интегрируйте первые два параметра в объект параметров через оптимист и передайте его объекту управления следующего процесса.
  2. Зарегистрируйте все настроенные плагины и позвольте плагину прослушивать узлы событий жизненного цикла сборки веб-пакета, чтобы реагировать соответствующим образом.
  3. Начните синтаксический анализ файла из настроенного файла записи записи, чтобы построить синтаксическое дерево AST, найти файлы, от которых зависит каждый файл, и выполнить рекурсию.
  4. В процессе рекурсивного разбора файлов в соответствии с типом файла и конфигурацией загрузчика находится подходящий загрузчик для преобразования файла.
  5. После завершения рекурсии получается окончательный результат каждого файла, и фрагмент блока кода генерируется в соответствии с конфигурацией записи.
  6. Вывести все фрагменты в файловую систему.

запись и контекст

entry

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

  • Однократная
entry: './src/app.js'
//等同于上面写法
entry: {
    main: './src/app.js'
}
  • многократный
  entry: {
    app: './src/pages/app/index.js',
    list: './src/pages/list/index.js'
  }

Это говорит нам о том, что веб-пакет начинает создавать граф зависимостей из app.js и .js. Эти графы зависимостей являются полностью отдельными и независимыми друг от друга.

Для многостраничных приложений файл записи получается динамически.Следующий метод используется для получения файла записи динамической пары "ключ-значение".

const glob = require('glob') 
const path = require('path') 
const GLOB_FILE_PATH = './src/pages/**/index.js' 
const CUT_PATH = './src/pages/' 
exports.getEntries = function(argv){ 
    let paths = glob.sync(GLOB_FILE_PATH) 
    let entries = {} 
    for (let i = 0; i < paths.length; i++){ 
        let pathName = path.dirname(paths[i]).replace(new RegExp('^' + CUT_PATH), '') 
        entries[pathName] = paths[i] 
    } 
    return entries 
}

context

Базовый каталог для времени компиляции веб-пакета,entryа такжеloaderбудет искать файлы относительно этого каталога

Значение по умолчанию — корневая директория проекта, изменять не рекомендуется.

экспорт (выход)

Сообщите webpack, куда выводить созданные им пакеты

output: {
    path: path.join(__dirname, 'dist'),
    publicPath: '/',
    filename: 'js/[name].js',
    clean: true, // 在生成文件之前清空 output 目录
}

publicPath

Используется для указания корневого пути внешних ресурсов (таких как изображения, js, css и т. д.), которые необходимо загрузить упакованным файлом.

Значение по умолчанию — пустая строка "", обычно установленная в "/"
静态资源最终访问路径 = output.publicPath + 资源loader或插件等配置路径

  • Конфигурация файла выходного изображения загрузчика
{ name: 'imgs/[name].[ext]' }
// 那么图片最终的访问路径为
output.publicPath('/') + 'imgs/[name].[ext]' = '/imgs/[name].[ext]'
  • Плагин извлекает конфигурацию файла css:
new ExtractTextPlugin('css/[name].[contenthash:10].css')
// html中加载css打包后代码
<link href="/css/app.9502b0c565.css" rel="stylesheet">
  • Загрузить упакованный код js в html
<script type="text/javascript" src="/js/runtime.4ece365fd5.js"></script>

path

вывод файла пакетасодержание

Рекомендуются абсолютные пути; по умолчанию используется текущий путь.
Использование шаблона [hash] в пути можно использовать для регрессии версий.

output: {
    path: path.resolve('./dist/[hash:8]/')
}

loader

Загрузчики позволяют веб-пакету обрабатывать файлы, отличные от JavaScript (сам веб-пакет понимает только JavaScript)

Примечание: module.loaders заменяется на module.rules, цепной загрузчик

  • старый синтаксис webpack1
module: {
    loaders: [{
        test: /\.less$/,
        loader: "style!css!less"
    })
}
  • синтаксис нового синтаксиса webpack
module: {
    rules: [{
        test: /\.less$/,
        use: [
            "style-loader",
            "css-loader",
            "less-loader"
        ]
    }]
}

класс стиля

меньше-загрузчик (в зависимости от меньшего)

npm i less less-loader --save-dev

less-loader загружает меньше файлов, меньше передает в
вывод → CSS

sass-loader (в зависимости от node-sass)

npm i node-sass sass-loader --save-dev

sass-loader загружает файлы sass/scss, node-sass передает в css
вывод → CSS

postcss-loader загружает и транспилирует файлы CSS

npm i postcss-loader autoprefixer --save-dev

postcssЭто инструмент для преобразования css через плагины JS, предоставляющий JS API, разработчики могут настраивать разработку в соответствии с интерфейсом API.плагин postcss, более популярные инструменты:

  • autoprefixerПолный префикс поставщика браузера
  • stylelintинструмент проверки кода
  • postcss-pxtoremПеревести единицы px в рем

Рабочий процесс:

  1. Разбор CSS в структуру абстрактного синтаксиса (AST), которую JavaScript может манипулировать
  2. вызвать плагинобработать AST и получить результат

вывод → CSS

postcss.configКонфигурация выглядит следующим образом:

module.exports = {
    plugins: {
        autoprefixer: {},
        "postcss-pxtorem": {
            rootValue: 16,
            propList: ['*'],
            minPixelValue: 1,
            exclude: (e) => {
                if (/src(\\|\/)excludeDirName(\\|\/)/.test(e)) {
                    return false
                }
                    return true
                },
            }
        }
    }
}

Для webpack4 используйте postcss-loader v4; для webpack5 используйте последнюю версию и установите зависимостиpostcss

css-loader

npm i css-loader --save-dev

Функция: после синтаксического анализа css преобразовать код css в модуль js, а затем@import а также url()Такие внешние ресурсы обрабатываются. (например, парсинг jsimport/require() Такой же)

@import './style.css' => require('./style.css')
url(./image.png) => require('./image.png')

Выводит массив строк кода js, которые можно выполнить

Включить CSS-модули

module: {
    rules: [
      {
        test: /.css$/i,
        loader: "css-loader",
        options: {
          modules: {
              localIdentName:'[name]-[local]-[hash:base64:5]'
          }
        },
      },
    ],
  },
};

Функция включения модуля css заключается в создании уникального класса после компиляции, чтобы избежать конфликтов классов с другими файлами.
Ниже представлен компонент React.

import style from './style.less'
export default ()=>{
    return( <div className={style.container}>主体内容</div> )
}

.container{
    font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
}

Скомпилированный результат css-loader

.style-container-32JMV{
    font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
}

Однако в проекте также будут встречаться сторонние библиотеки компонентов, такие как antd и swiper, и исходный стиль необходимо изменить.Модуль CSS также предоставляет режим глобального правила.

:global(.container) {
  width: 100%;
}

С меньшим количеством вы можете определить несколько глобальных классов одновременно

:global {
    .layout{
        margin: 0;
        padding: 0;
    }
    .container{
      width: 100%;
    }
}

style-loader добавляет экспорт модуля как стили в DOM

npm i style-loader --save-dev

Вставьте css в DOM в виде тегов стиля, обычно используемых в среде разработки, а производственная среда будет использоватьmini-css-extract-pluginПлагин извлекает css в отдельные файлы.

Окончательная конфигурация загрузчика стилей

const getStyleLoaders = () =>
    [
      'style-loader',
      {
        loader: 'css-loader',
        options: {
          modules: {
            localIdentName: '[name]-[local]-[hash:base64:5]',
          },
        },
      },
      'postcss-loader',
      'sass-loader',
    ].filter(Boolean);

module: {
    rules: [
        {
          test: /\.(sc|c)ss$/,
          use: getStyleLoaders(),
        }
    ]
}

Преобразовать скомпилированный класс

babel-loader

Поскольку браузеры могут читать только синтаксис ES5, для компиляции синтаксиса ES2015+ в синтаксис ES5 требуется Babel.

  1. Установить

npm i @babel/core @babel/preset-env @babel/preset-react babel-loader @babel/plugin-proposal-class-properties --save-dev

  1. Применение
{
    test: /\.js$/,
    use: {
        loader: 'babel-loader',
        exclude: /node_modules/,
        options: {
            cacheDirectory: true,
        }
    }
}

options

  • cacheDirectory: значение по умолчанию — false. Если установлено, указанный каталог будет использоваться для кэширования результата выполнения загрузчика.
  • babelrc по умолчанию true, установите false, .babelrc не будет включен

.babelrc

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
      }
    ],
    "@babel/typescript",
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": 3,
        "helpers": true,
        "regenerator": true,
        "useESModules": true
      }
    ]
  ]
}

ts-loader загружает TypeScript как JavaScript

script-loader

Выполняйте JS-скрипты один раз в глобальном контексте так же, как если бы вы импортировали их через

класс файла

raw-loader загружает исходное содержимое файла, например файл .txt

file-loader упаковывает файлы в выходной каталог

{
    test: /\.(gif|png|jpe?g|svg)$/,
    use: [{
        loader: 'file-loader',
        options:{
            name: 'static/img/[name].[ext]?[hash]',
        }
    }]
}

Вывод по умолчанию — корневой каталог вывода, а имя — 32 в качестве хеш-значения.

url-загрузчик работает как файловый загрузчик

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

{
    test: /\.(png|jpg|gif)$/,
        use: [
        {
            loader: 'url-loader',
            options: {
                limit:10240,
                name: 'static/img/[name].[ext]?[hash]'
            }
        }
    ]
}

встроенная возможность создания статических ресурсов в webpack5

{
    test: /\.(gif|png|jpe?g|svg)(\?.*)?$/,
    type: 'asset',
    generator: {
        filename: 'static/img/[name].[ext]?[hash]',
    },
    parser: {
        dataUrlCondition: {
            maxSize: 10 * 1024,
        },
    },
}

Описание значения типа:

  • актив/источник — функционально эквивалентно сырому загрузчику
  • assets/inline — функция эквивалентна url-loader, если вы хотите установить правила кодирования, вы можете установить dataUrlCondition в генераторе
  • актив/ресурс — функционально эквивалентен файловому загрузчику
  • актив — Тип по умолчанию будет выбран в соответствии с размером файла.Если размер файла меньше 8 КБ, будет использоваться актив/встроенный, в противном случае будет использоваться актив/ресурс.Вы также можете установить порог вручную.

Чистые и тестовые классы

mocha-loader использует тесты mocha (браузер/NodeJS)

eslint-loader использует ESLint для очистки кода

jshint-loader очищает код с помощью JSHint

Класс шаблона

html-loader решает проблему загрузки картинок в html

минимизировать: true сжимать html-файлы

handlebars-loader загружает файлы рулей и компилирует их в html файлы

handlebars-template-loader решает проблему пути изображения руля

markup-inline-loader

Преобразование встроенных файлов SVG/MathML в HTML. Полезно при применении к шрифтам значков или при применении CSS-анимации к SVG.

{
    test: /\.html$/,
    use: [
      'html-loader',
      'markup-inline-loader'
    ]
}

использовать в html:
<img markup-inline src="./_images/camera.svg" />
<img data-markup-inline src="./_images/camera.svg" />

класс кадра

vue-loader загружает и транспилирует компоненты Vue

angular2-template-loader загружает и транспилирует компоненты Angular

плагин

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

html-webpack-plugin (создает HTML-файлы)

  • Для внешних ресурсов, таких как сценарии и ссылки, представленные в html-файлах, динамически добавляйте хэш после каждой компиляции, чтобы предотвратить проблему со ссылками на кэшированные внешние файлы.
  • Вы можете генерировать и создавать файлы записей html.Например, одна страница может генерировать запись файла html и настроить N html-webpack-плагинов для создания записей N страниц.
const HtmlWebpackPlugin = require('html-webpack-plugin');
    plugins: [
        new htmlWebpackPlugin(options),
        new htmlWebpackPlugin(options)
    ]
имя Типы По умолчанию описывать
title {String} `` Заголовок, используемый для сгенерированного HTML-документа.
filename {String} 'index.html' Создать html имя файла
template {String} `` Путь к шаблону и имя файла (путь относительно output.context)
inject {Boolean|String} true true или 'body': все ресурсы JavaScript будут размещены внизу элемента body.
'head': поместите скрипт в элемент head
false: скрипт не помещается в html
favicon {String} `` Добавьте указанный путь к значку в выходной HTML
minify {Boolean|Object} true Сократить вывод htmlhtml-minifier
hash {Boolean} false true: добавлять уникальный хэш компиляции ко всем сценариям, включенным в webpack, и файлам CSS. Это очень полезно для очистки кеша
cache {Boolean} true Выдавать файлы, только если они были изменены

mini-css-extract-plugin (извлечение файлов css)

webpack рассматривает все ресурсы как модуль, CSS, изображения, ресурсы файла шрифта JS упакованы в файл bundle.js, который отдельно извлекает код модуля css в файл css.

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
  module: {
    rules: [
      {
        test: /.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
  plugins: [new MiniCssExtractPlugin()],
};

использование веб-пакета4extract-text-webpack-plugin

terser-webpack-plugin(сжать js-файл)

webpack5 имеет встроенныйterser-webpack-plugin, если вам нужно настроить или webpack4, вам нужно установить

const TerserPlugin = require('terser-webpack-plugin');
optimization: {
    minimize: true,
    minimizer: [new TerserPlugin({
        terserOptions: {
            compress: {
                comparisons: false,
                drop_console: true, //丢掉console
                inline: 2,
            },
            output: {
                comments: false,
            }
        }
    })]
}
имя Типы По умолчанию описывать
test {RegExp|Array<RegExp>} /.m?js(?.*)?$/i соответствующие файлы
parallel {Boolean|Number} true Используйте несколько процессов для параллельного запуска, чтобы увеличить скорость сборки
terserOptions {Object} default minify options

Возможное использование проектов webpack4uglifyjs-webpack-pluginПлагин для сжатия JS

copy-webpack-plugin (копировать статические ресурсы)

const CopyPlugin = require("copy-webpack-plugin")
CopyWebpackPlugin(
    patterns: [
        {
            from: 'src/static',
            to: 'static',
        },
    ])

from определяет исходный каталог для копирования.
чтобы определить целевой каталог для копирования, output.path по умолчанию
фильтр игнорирует копию указанного файла, может быть нечеткое соответствие.

clean-webpack-plugin очищает каталог сборки перед упаковкой

Файлы в выходном каталоге будут удалены по умолчанию, но сам каталог не будет удален; эта функция была встроена в webpack 5.20.0+, подробности см. в настройках вывода выше.

Использование и общие элементы конфигурации

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
plugins: [new CleanWebpackPlugin({
    verbose:true, //打开日志,默认关闭
    cleanStaleWebpackAssets: true //默认删除未使用的资源
})]

сжатие-webpack-plugin сжатие gzip

процесс распаковки http gzip

  1. Когда браузер запрашивает ресурсы, он предоставляет свои собственные.accept-encodingЗаголовок запроса, сообщающий серверу о поддерживаемом типе кодирования сжатия.
  2. Сервер включает конфигурацию gzip => получает запрос файла ресурсов клиента, сервер кодирует ответ через gzip (если есть файл gzip, то файл gzip используется напрямую для уменьшения нагрузки на сервер) После кодирования остается контент -кодировка: gzip в шапке отправить в браузер
  3. После того, как браузер получит ответ, согласноcontent-encoding:gzipчтобы декодировать ответ, а затем отобразить страницу.

Решение для горячей замены модуля — HotModuleReplacementPlugin (HMR)

  1. Прежде чем говорить о горячей замене модуля, давайте сначала поговорим о горячем обновлении. Горячее обновление означает, что страница автоматически обновляется при изменении кода, код выглядит следующим образом:
devServer: {
    hot: true // 激活服务器的HMR
}

Конфигурация очень простая, но есть минус, страница будет обновляться и все ресурсы нужно перезагружать, поэтому есть горячая замена.

  1. Горячая замена заключается в замене содержимого модуля без обновления страницы, основной принципwebpack-dev-serverпройти черезwebsocketОтправьте обновленный код в браузер черезmodule.hot.acceptЗарегистрированный обратный вызов выполняется

Добавьте следующую конфигурацию

// webpack.config.js
new webpack.HotModuleReplacementPlugin()

файл входа в проект

import App from './App';
if (module.hot) {
    module.hot.accept('./App', () => {
        ReactDOM.render( <App />, document.getElementById('root') );
    });
}

Встроенное HMR-решение webpack решает проблему обновления страницы, но по-прежнему существует проблема внутреннего состояния, которая не способствует отладке в среде разработки.

недостаток: если вы используете реакцию или vue, состояние в компоненте станет начальным значением после обновления.Для React то, что вы делаете в HMR, — это повторное введение корневого компонента, а затем повторный рендеринг, потому что HMR является горячей заменой для корневой компонент, поэтому состояние корневого компонента и его дочерних компонентов будет потеряно, но состояние, хранящееся в хранилище избыточности, все равно будет сохранено.

  1. Вариант 1: С точки зрения React, введитеreact-hot-loaderдля решения вышеуказанных проблем.

использоватьreact-hot-loader, вы можете удалитьwebpack.HotModuleReplacementPluginплагин

// App.jsx
import { hot } from 'react-hot-loader/root'
export default hot(App)
// .babelrc
{
  "plugins": ["react-hot-loader/babel"]
}
// package.json
{
  "dependencies": {
    "react-hot-loader": "^4.13.0",
    "@hot-loader/react-dom": "^17.0.1"
  }
}
// webpack.config.js
{
  resolve: {
    alias: {
      'react-dom': '@hot-loader/react-dom' //解决React 16.6+ 新特性的热替换问题
    }
  }
}
  1. Сценарий 2:react-refreshа также@pmmmwh/react-refresh-webpack-plugin

Официальное решение React для горячей замены модулей (HMR)

const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
{
    module: {
                {
                    test: /\.tsx?$/,
                    loader: 'babel-loader',
                    options: {
                        plugins: [isEnvDevelopment && require.resolve('react-refresh/babel')].filter(Boolean),
                    }
                }
            },
    plugins:[isEnvDevelopment && new ReactRefreshPlugin(),]
}

Требовать:react-dom@16.9+

webpack поставляется с плагинами

webpack.DefinePlugin настраивает глобальные константы

Определите константы в проекте, чтобы различать среду (она является константой и не может быть переназначена в проекте), не висит вwindow, но доступный во всех модулях. обычно сотрудничаютcross-envиспользовать вместе

cross-env (установить кросс-платформенные переменные среды узла)

Что такое переменные среды узла? process — это глобальная переменная, существующая в nodejs, а process.env — это некоторая информация о среде выполнения проекта.
Какая польза от переменных окружения? Наиболее распространенный сценарий заключается в том, что при упаковке веб-пакета создается среда службы узла.Установив переменные среды, служба помечается меткой, обозначающей текущую запущенную среду.

// package.json
"scripts": {
    "dev": "cross-env NODE_ENV_MARK=dev webpack-dev-server --config config/start.js",
}
//开发环境 dev.env.js
module.exports = {
    NODE_ENV: '"development"',
    prefix: '"//devapi.abc.com"',
};
const env = require(`../env/${process.env.NODE_ENV_MARK}.env`)
new webpack.DefinePlugin({
    'process.env': env
})

Плагин прогресса webpack.ProgressPlugin

Извлечение webpack.optimize.CommonsChunkPluginchunksОбщие модули совместно используются

Webpack относится к набору кода после того, как несколько модулей упакованы в виде фрагментов.
Этот плагин был удален в webpack4 и более поздних версиях, если вам нужно распаковать, обратитесь к модулю оптимизации в статье.SplitChunksPlugin

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

module.exports = {
    entry: {
        main1: '/src/main1.js',
        main2: '/src/main2.js',
        jquery:["jquery"],
        vue:["vue"]
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: ["common",'jquery','vue'],//对应于上面的entry的key
            minChunks:2
        })
    ]
};

После упаковки jquery и vue будут генерировать независимые фрагменты, а общедоступные бизнес-модули в main1 и main2 будут упакованы в common.js;
Когда minChunks равно бесконечности, общедоступные бизнес-модули будут упакованы в main1.js и main2.js соответственно.

разное

webpack-dev-server

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

анализ скорости сборки плагина speed-measure-webpack

анализ объема сборки webpack-bundle-analyzer

оптимизация

Оптимизации делятся на две широкие категории: скорость сборки и размер вывода.

Вот класс скорости сборки:

1. Обновление версии веб-пакета (время сборки)

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

2. Кэш (время сборки)

  • Постоянный кэш жесткого диска
cache: { 
    type: 'filesystem', // 使用文件缓存 
},

dll❎:Публичная библиотека впервые упакована в отдельный файл.После этого вам нужно только упаковать бизнес-код, чтобы сократить время упаковки.В Webpack4+ есть официально встроенные сопутствующие функции

  • Включить кеш babel-loader

Процесс компиляции babel занимает много времени. К счастью, babel-loader предоставляет возможность кэшировать результаты компиляции. При перезапуске webpack нет необходимости вводить новшества в компиляцию, а нужно повторно использовать кэшированные результаты, чтобы сократить процесс компиляции. Механизм кэширования babel-loader по умолчанию отключен, а открытые конфигурации следующие:

{
    test: /\.js$/,
    loader: 'babel-loader',
    options: {
        cacheDirectory: true,
    },
}

3. Сузить область поиска загрузчика (время сборки)

{
    test: /\.js$/,
    loader: 'babel-loader',
    include: path.resolve(__dirname, 'src'),
}

4. Оптимизируйте разрешение для более быстрого анализа (время сборки)

  • Каталоги, которые искались при настройке модуля парсинга

аналогичныйimport redux from 'redux'Таким образом, когда путь не является ни относительным, ни абсолютным, будет выполняться поиск в каталоге node_modules в текущем каталоге.Конфигурация по умолчанию будет использовать восходящий рекурсивный поиск для поиска node_modules, но обычно в корневом каталоге есть только один node_modules.

module.exports = {
    resolve: {
        modules: [
            'node_modules',
            path.resolve(__dirname, 'src'),
        ]
    }
};

Ниже приведен оптимизированный размер вывода сборки.

5.tree-shaking (объем упаковки)

С помощью статических характеристик модулей es6 (зависимости между модулями определяются во время компиляции) удалитьexportно ни одинimportпрошлые вещи

@babel/presets-envПо умолчанию модуль ES будет преобразован в форму CommonJS, что приведет к аннулированию функции встряхивания дерева Webpack.После установки значения false преобразование модульных операторов будет отключено, а синтаксис модуля будет передан Webpack для обработки.

"presets": [
    [
      "@babel/preset-env",
      {
        "modules": false
      }
    ]
]
  • purgecss-webpack-plugin для встряхивания дерева css

6. Сжатие файлов (объем упаковки)

  • сжать css

css-minimizer-webpack-pluginИспользуйте CSSNANO для оптимизации и компрессора CSS, кэш-памяти поддержки, одновременный режим и тепловой замены CSS также хорошо поддерживается. WebPack5 не рекомендуетсяoptimize-css-assets-webpack-plugin

optimization: {
    minimizer: [
      new CssMinimizerPlugin({
        parallel: true, //默认使用多线程运行,os.cpus().length - 1
      }),
    ],
  },
  • Сжать JS
new TerserPlugin({
    terserOptions: {
        compress: {
            comparisons: false,
            drop_console: true, //丢掉console
            inline: 2,
        },
        output: {
            comments: false,
        }
    }
})
  • использоватьimagemin-webpack-pluginСжать изображение

7. Разделение на чанки (объем упаковки)

  • Разделяет splitChunks для сторонних библиотек и общего кода
  • файл времени выполнения

время выполнения:ссылка на код модуля, после упаковки, после того как браузер загрузит входной файл, webpack будет иметь программу запуска для управления созданием и выполнением модулей

Шаги для создания асинхронного модуля:

  1. Создайте объект Promise, используйте installChunks для записи его разрешения и отклонения, чтобы позже переключать контексты после получения ресурсов, и контролировать фактическое выполнение .then()
  2. installedChunks записывает семейство чанков и загружает их.
  3. Создайте тег сценария, чтобы инициировать асинхронный запрос
  • Функция webpack import() загружается по запросу
optimization: {
    splitChunks: {
        chunks: 'all',
        minChunks: 2,
        cacheGroups: {
            dll: {
                chunks: 'all',
                test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
                name: 'dll',
                priority: 100,
                enforce: true,/* 为此缓存组创建块时,告诉webpack忽略minSize,minChunks,maxAsyncRequests,maxInitialRequests选项。*/
                reuseExistingChunk: true,
            },
            commons: {
                name: 'commons',
                minChunks: 2,
                chunks: 'all',
                reuseExistingChunk: true,
            },
        },
    },
    runtimeChunk: true,
}

Кроме того, есть имя файла для генерации хеш-значения, а кеш браузера используется для уменьшения загрузки файла.

output: {
    filename: `static/js/[name]${isEnvProduction ? '.[contenthash:8]' : ''}.js`,
},

8. Другие

  • использовать псевдоним

resolve.alias настраивает сопоставления путей. Большинство библиотек, опубликованных в npm, содержат два каталога: один — это каталог lib, в котором модульная структура cmd, а другой — каталог dist, объединяющий все файлы в один файл, и большинство входных файлов указывают на lib.
По умолчанию webpack считывает входные файлы в каталоге lib, а затем рекурсивно загружает другие зависимые файлы.Этот процесс занимает много времени.Конфигурация псевдонима позволяет webpack напрямую использовать все файлы в каталоге dist, чтобы уменьшить рекурсивный анализ файлов. Конфигурация выглядит следующим образом:

module.exports = {
  resolve: {
    alias: {
      'moment': 'moment/min/moment.min.js',
      'react': 'react/dist/react.js',
      'react-dom': 'react-dom/dist/react-dom.js'
    }
  }
};
  • использовать noParse

module.noParseНастройте, какие файлы могут быть проанализированы из webpack. Некоторые библиотеки самодостаточны и не зависят от других библиотек и не используют модуляризацию, например jquey, momentjs, chart.js, для их использования их необходимо импортировать целиком.
Webpack — это модульный инструмент для упаковки.Разбирать зависимости этих файлов совершенно необязательно, так как они не зависят от других файлов и имеют очень большой размер.Чтобы их игнорировать, настройте их следующим образом:

module.exports = {
  module: {
    noParse: /node_modules\/(jquey|moment|chart\.js)/
  }
};
  • Некоторые оптимизации для webpack4

Поскольку webpack4 не поддерживает многопоточные сборки, вы можете использоватьhappypackЭто позволяет использовать многопоточность

Сводка по оптимизации:

  • С точки зрения ускорения времени сборки, включая обновление веб-пакета и настройку кеша, это может значительно ускорить вторичную сборку.
  • При уменьшении объема упаковки, включающей в себя сжатый код, код с повторяющимся разделением, Tree Shaking, позволяет уменьшить объем упаковки до максимальной амплитуды.
  • С точки зрения ускорения загрузки важны загрузка по запросу, кэширование браузера и CDN.