«Раз и навсегда» настроить webpack4 от поверхностного к глубокому

JavaScript Webpack
«Раз и навсегда» настроить webpack4 от поверхностного к глубокому

предисловие

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

Основные концепции, которые вебпак должен освоить👇

  • Entry: Модуль входа, который начинает собирать webpack.
  • Output: как назвать выходной файл и выходной каталог, например, общий каталог dist.
  • Loaders: функция состоит в том, чтобы анализировать файлы и обрабатывать файлы, отличные от js, которые не могут быть обработаны, в модули, которые могут быть обработаны веб-пакетом.
  • Plugins: Дополнительная оптимизация, извлечение сущности (общая дедупликация модулей), обработка сжатия (css/js/html) и т. д., расширение функций веб-пакета.
  • Chunk: Лично думаю, что это webpack 4Code Splittingпродукт, заброшенный webpack3CommonsChunkPlugin, его самой большой особенностью является простая конфигурация, когда вы устанавливаетеmodeдаproduction, то автоматически запустится webpack 4Code Splitting, можно выполнить дедупликацию некоторых общих модулей и упаковать их в отдельныйchunk.

На этот раз, чтобы изучить новые функции webpack4, в основном следуйтеОфициальный сайтнастроить.


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

Основы веб-пакета

что такое вебпак

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

В настоящее время webpack 4.0 может упаковать любую форму модуля.

Как установить вебпак

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

node -v
npm -v

После того, как появятся два номера версии, вы можете продолжить изучение webpack.Инструмент управления пакетами npm обязателен.

Инициализировать проект

npm init 

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

Далее обнаруживается, что в этом корневом каталоге будетСоздайте файл package.json, этот файл описывает проект узла, некоторую информацию о пакете узла. Это,То, что генерирует npm init, — это файл package.json.

описание свойства package.json

	name - 包名.
    version - 包的版本号。
    description - 包的描述。
    homepage - 包的官网URL。
    author - 包的作者,它的值是你在https://npmjs.org网站的有效账户名,遵循“账户名<邮件>”的规则,		例如:zhangsan <zhangsan@163.com>。
    contributors - 包的其他贡献者。
    dependencies / devDependencies - 生产/开发环境依赖包列表。它们将会被安装在 node_module 目录下。
    main - main 字段指定了程序的主入口文件,require('moduleName') 就会加载这个文件。这个字段的默认值是模块根目录下面的 index.js。
    keywords - 关键字

Следующим шагом будет установка вебпака

 npm install webpack webpack-cli -g   // 全局安装webpack

Однако не рекомендуется устанавливать таким образом.Если у вас есть несколько проектов, если одна из ваших зависимостей веб-пакета имеет версию 3.x, а текущая версия — версия 4.0, то проект не запустится.

Затем сначала удалите глобально установленный веб-пакет, а затем установите его отдельно в текущем проекте, который вы хотите запустить.

 npm uninstall webpack webpack-cli -g   //卸载全局webpack

Как установить глобально👇

 npm install webpack webpack-cli -D   // 局部安装

Чтобы проверить версию,webpack -vЭта команда не работает в настоящее время, потому что в это время node перейдет к глобальному поиску и обнаружит, что пакет веб-пакета не может быть найден, поскольку мы ранее удалили глобальный веб-пакет, поэтому нам нужно использовать новую команду.

npx webpack -v

В это время вы можете увидеть номер версии.

Как проверить версию пакета

npm info webpack   // 查看webpack包版本

конфигурационный файл вебпака

webpack.config.js — это файл конфигурации webpack по умолчанию.Мы можем настроить файл конфигурации, например, вход и выход из файла.

const path = require('path')
module.exports = {
    entry : './index.js',
    output : {
        filename : 'bundle.js',
        path : path.join(__dirname, 'dist')
    }
}

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

Затем в это время запустите в командной строкеnpx webpack, он будет искать информацию о конфигурации в файле webpack.config.js.

Файл конфигурации по умолчанию должен иметь имя webpack.config.js., но вы сами написали информацию о файле конфигурации веб-пакета, это сработает? Конечно можно, тогда надо выполнить следующую команду👇

npx webpack --config webpack.config.js
// --config 后面就是你自己配置的webpack文件信息

npm scripts

npm scriptsИногда, если вы использовали vue и React, вы часто используете форму npm run dev, поэтому можем ли мы настроить такую ​​информацию? Нам просто нужно настроить команду scripts в файле package.json👇

"scripts": {
    "dev": "webpack --config webpack.config.js"
  },

В это время вы запускаете npm run dev, он будет переведен в соответствующие инструкции, а также будут запакованы соответствующие файлы.

webpack упаковывает три команды

  • webpack index.js (глобальный)
  • npx webpack index.js
  • npm run dev

webpack-cli

В это время вы можете обнаружить, что webpack-cli работает.Если вы не загрузите этот пакет, команда webpack, которую вы запустите в командной строке, не вступит в силу, то естьРоль webpack-cli заключается в том, чтобы запускать команды webpack в командной строке и вступать в силу.

Использование команды webpack в командной строке без загрузки запрещено.

среда конфигурации веб-пакета

в основном разделеныdevelopmentиproductionЭти две среды по умолчанию являются производственной средой.Разница между ними заключается в том, что последняя будет сжимать упакованные файлы. **Тогда настроим👇

const path = require('path')
module.exports = {
    mode : 'development',
    entry : './index.js',
    output : {
        filename : 'bundle.js',
        path : path.join(__dirname, 'bundle')
    }
}

В это время, если вы посмотрите снова, вы обнаружите, что,файл bundle.js не имеет кода сжатия.


загрузчик основной концепции webpack

что такое загрузчик

Загрузчик — это пакетное решение, которое знает, как упаковать определенный файл.Webpack сам не умеет обращаться с некоторыми файлами, а загрузчик знает, как с ним обращаться, поэтому webpack обратится за помощью к загрузчику.

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

Затем перейдите в конфигурационный файл webpack.config.js для настройки соответствующей информации, настройте модуль👇

const path = require('path')
module.exports = {
    mode: 'production',
    entry: './src/index.js',
    module: {
        rules: [{
            test: /\.(png|jpg|gif)$/,
            use: {
                loader: 'file-loader'
            }
        }]
    },
    output: {
        filename: 'bundle.js',
        path: path.join(__dirname, 'dist')
    }
}

Если нам нужен файл-загрузчик, мы зависим от него, поэтому сначала скачайте его

npm install file-loader -D

Тогда давайте посмотрим, как пишется index.js👇

import acator from './头像.jpg'
console.log(acator)

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

3f16daf5233d30f46509b1bf2c4e08a5.jpg

Это означает, что файл-загрузчик помогает нам упаковать модуль изображения в каталог dist, а в index.js результатом этой переменной acator является имя, Таким образом, упаковка может быть завершена, и изображение должно быть легко получены позже.

Суммировать

Webpack не может распознавать модули, которые не заканчиваются на js, поэтому требуется загрузчик, чтобы webpack распознал его, чтобы можно было завершить упаковку.

  • При обнаружении модуля, который не заканчивается на js, веб-пакет перейдет к модулю, чтобы найти соответствующие правила, сопоставить соответствующие правила, а затем перейти к соответствующему загрузчику за помощью.
  • Соответствующий загрузчик упакует модуль в соответствующий каталог, в приведенном выше примере это каталог dist, и,Возвращает путь модуля, взяв пример выше, этоacatorЗначением переменной является путь.

Как настроить файл-загрузчик

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

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

			{
                loader: 'file-loader',
                options: {
                    // name就是原始名称,hash使用的是MD5算法,ext就是后缀
                    name: '[name]_[hash].[ext]'
                }
            }

Фотографии, которые мы импортировали, находятся ниже👇

import acator from './头像.jpg'

Тогда окончательное упакованное имя - это описание👇

头像_3f16daf5233d30f46509b1bf2c4e08a5.jpg

Например, если вы хотите упаковать модули изображений в изображения в каталоге dist, можете ли вы это настроить?

			{
                loader: 'file-loader',
                options: {
                    name: '[name]_[hash].[ext]',
                    outputPath: 'images/'
                }
            }

В этом случае соответствующие упакованные образы будут находиться в каталоге dist/images/.

Например, в разных средах расположение упакованных картинок тоже может быть разным, 👇

if (env === 'development') {
        return '[path][name].[ext]'
}

Остальные заходите на официальный сайт и настраивайте сами.

Как настроить URL-загрузчик

Для упаковки модулей изображений выше мы также можем использовать url-loader, так в чем же разница между ним и file-loader?

			{
                loader: 'url-loader',
                options: {
                    name: '[name]_[hash].[ext]',
                    outputPath: 'images/',
                    limit : 102400  //100KB
                }
            }

Единственная разница заключается в том, будут ли упакованные образы упакованы в каталог images или в файл bundle.js в формате Base64, что зависит от элемента конфигурации limit.

  • Когда размер образа, который вы упаковываете, больше, чем параметр, заданный параметром limit, он аналогичен файлу-загрузчику.
  • Когда изображение меньше, оно будет упаковано в файл bundle.js в Base64.

больше URL-загрузчиковсм. официальный сайт

Как настроить css-загрузчик

Например, если вы вводите модуль css, в это время вам необходимо загрузить соответствующий загрузчик модулей.

cnpm install css-loader style-loader -D   // 下载对应的模块

Тогда настройте модуль👇

		{
            test: /\.css$/,
            use: ['style-loader','css-loader']
        }

В этом случае вы можете импортировать стиль в index.js, чтобы он вступил в силу, давайте посмотрим, как импортировать👇

import acator from './头像.jpg'
import './index.css'
const img = new Image()
img.src = acator
img.classList.add('imgtitle')
document.body.appendChild(img)

Это imgtitle в следующем стиле👇

.imgtitle{
    width: 100px;
    height: 100px;
}

Через два загрузчика реализована упаковка css файлов вебпака, далее мы анализируем следующие две функции загрузчика.

  • Основная функция css-loader — объединить несколько файлов css вместе, чтобы сформировать файл css.
  • Загрузчик стилей смонтирует интегрированную часть css в тег head.

Тогда, если вы используете scss для прекомпиляции css, webpack не сможет упаковать файл, поэтому вам нужно установить новый загрузчик👇

Как настроить sass-загрузчик

Посмотрим, что нужно скачать официальному сайту scss-loader,кликните сюда

npm install sass-loader node-sass --save-dev

Вышеупомянутое для установки sass-loader, вам необходимо одновременно установить node-sass, а затем настроить соответствующий модуль

		{
            test: /\.scss$/,
            use: ['style-loader','css-loader','sass-loader']
        }

В этом случае вы можете импортировать файл стиля scss следующим образом, и его можно запаковать 👇

// index.js 
import acator from './头像.jpg'
// console.log(acator)
import './index.scss'   // 导入scss文件

const img = new Image()
img.src = acator
img.classList.add('imgtitle')
document.body.appendChild(img)

Загрузка модуля идет справа налево, поэтому сначала загрузите sass-loader и переведите его в css-файл, а затем с помощью css-loader запакуйте его в css-файл, а затем смонтируйте на странице через загрузчик стилей.

Далее новый вопрос.Если использовать css3 new и special в файле scss нужно ли добавлять префикс производителя? В это время, что нам нужно сделать? Какой загрузчик добавить? смотреть вниз

Как настроить postcss-загрузчик

Что решает этот загрузчик, так это добавить префикс производителя, давайте посмотрим, как это делает официальный сайт webpack 👉кликните сюда

npm i -D postcss-loader autoprefixer

Затем необходимо построитьpostcss.config.js, этот файл конфигурации (Расположение такое же, как и в webpack.config.js.) настроить следующую информацию👇

// postcss.config.js
// 需要配置这个插件信息
module.exports = {
    plugins: [
        require('autoprefixer')({
            overrideBrowserslist: [
                "Android 4.1",
                "iOS 7.1",
                "Chrome > 31",
                "ff > 31",
                "ie >= 8"
            ]
        })
    ]
};

Если я установлю его в начале, он не подействует, причина в том, чтоПоддерживаемые браузеры не установлены, тогда взгляните ниже👇

		{
            test: /\.scss$/,
            use: ['style-loader','css-loader','sass-loader','postcss-loader']
        }

Наконец, вы можете видеть, что, например, css3 добавит префикс производителя👇

-webkit-transform: translate(100px, 100px);
-ms-transform: translate(100px, 100px);
transform: translate(100px, 100px);

Некоторые другие проблемы, иногда вы столкнетесь с такой проблемой, вы не импортируете новый файл scss в определенный файл scss, в это время, если он запакован, это не поможет вам переустановить postcss-loader и начать упаковку, в на этот раз, как мы должны его установить, давайте сначала посмотрим на пример👇

// index.scss
@import './creare.scss';
body {
    .imgtitle {
        width: 100px;
        height: 100px;
        transform: translate(100px, 100px);
    }
}
  • Мы знаем, что настроенные нами правила загрузчика соответствуют ожиданиям, подобным этому
  • Когда модуль scss вводится в код js, он будет следовать таким правилам.
  • Так как внедрить в scss файл scss, то из postcss-загрузчика правила точно не будут запаковываться, поэтому надо настроить некоторую информацию.
		{
            test: /\.scss$/,
            use: ['style-loader',
                {
                    loader: 'css-loader',
                    options:{
                        importLoaders:2,
                        modules : true
                    }
                },
                'sass-loader',
                'postcss-loader'
            ]
        }

Нам нужно настроить параметры в css-loader, добавитьimportLoaders :2, для этого потребуется postcss-loader и sass-loader, такой синтаксис,Независимо от того, вводите ли вы файлы scss в js или файлы scss в scss, все загрузчики будут выполняться снова снизу вверх.

Такmodules:trueЧто делает эта конфигурация? Иногда вы хотите, чтобы ваш стиль css работал в текущем модуле, а не в глобальном, вам нужно добавить эту конфигурацию, см. пример ниже👇

// index.js
import acator from './头像.jpg'
import create from './create'

import style from './index.scss'  // 通过modules:true 避免了css作用域create中的模块
const img = new Image()
img.src = acator
img.classList.add(style.imgtitle)
document.body.appendChild(img)
create()

Так что же такое модуль создания👇

import acator from './头像.jpg'
import style from './index.scss'
function create() {
    const img = new Image()
    img.src = acator
    img.classList.add(style.imgtitle)
    document.body.appendChild(img)
}

export default create;

Видно, что этот модуль создания предназначен для создания тега img и установки отдельного стиля. даватьmodules : trueПосле этого нам нужно изменить синтаксис импорта.

import style from './index.scss'

Затем просмотрите переменную объекта стиля, чтобы найти имя, установленное в scss.

Суммировать

  • importLoaders:2Эта конфигурационная информация решает проблему введения файла scss в файл scss, и он снова будет запакован из postcss-загрузчика.
  • modules:trueВ текущей среде css области стили не будут импортированы глобально, и синтаксис также необходимо импортировать следующим образом.
  • import style from './index.scss'

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

		{
            test: /\.(woff|woff2|eot|ttf|otf)$/,
            use: [
                'file-loader'
            ]
        }

Для более подробной настройки упаковки статических ресурсов вы можете посмотреть, как используется официальный сайт, 👉(Статический загрузчик управляет ресурсами)


основные концептуальные плагины webpack

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

plugins: Он может кое-что сделать для вас, когда веб-пакет работает до определенного момента.

Как использовать HtmlWebpackPlugin

Функция этого плагина состоит в том, чтобы сгенерировать для вас файл HTML, а затем автоматически импортировать упакованный файл js в этот файл html.

Как настроить? можно смотретьофициальный сайт вебпака

Первый шаг — загрузить HtmlWebpackPlugin.

cnpm install --save-dev html-webpack-plugin

Затем настройте следующую информацию в webpack.config.js👇

var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');

var webpackConfig = {
  entry: 'index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'index_bundle.js'
  },
  plugins: [new HtmlWebpackPlugin({
            template: 'src/index.html'  // 以src/目录下的index.html为模板打包
        }
    )],
};

Затем запустите npm run dev, вы обнаружите, что в каталоге dist он автоматически сгенерирует для вас HTML-модуль и импортирует файл bundle.js.

template: 'src/index.html'Функция этой информации о конфигурации состоит в том, чтобы сообщить вам, какой конкретный index.html использовать в качестве шаблона для упаковки.

Как использовать CleanWebpackPlugin

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

cnpm i clean-webpack-plugin -D
//"clean-webpack-plugin": "^3.0.0",我的是这个版本

Затем, если вы настроите плагин clean-webpack, вам нужно перейти на веб-сайт, чтобы узнать, как его настроить, вы можете нажать здесь 👉на нпм

Информация о конфигурации следующая👇, это последняя конфигурация плагина clean-webpack

const {CleanWebpackPlugin} = require('clean-webpack-plugin');

// plugins新增加这一项,webpack4版本不需要配置路径
plugins: [ new CleanWebpackPlugin()]

В последней версии webpack4 не требуется настраивать путь, и она автоматически помогает нам очищать файлы в каталоге упакованного dist.


основные концепции веб-пакета

вход и выход базовая конфигурация

Иногда вам нужно несколько файлов ввода, так как же нам это сделать?На данный момент нам нужно взглянуть на элементы конфигурации ввода и вывода.

Конечно, на официальном сайте webpack тоже есть документация,нажмите здесьа такжезапись нажмите здесь

entry: {
        index :'./src/index.js',
        bundle : './src/create.js',
    },
output: {
        filename: '[name].js',
        publicPath: "https://cdn.example.com/assets/",
        path: path.join(__dirname, 'dist')
    }    

Суммировать

  • Конфигурация записи может принимать несколько записей упакованных файлов.В то же время имя выходного выходного файла должно использовать имя заполнителя.
  • Таким образом, будут сгенерированы два файла, и сообщение об ошибке не будет отправлено.Имя записи соответствует имени записи.
  • Если ресурс был смонтирован на cdn в фоновом режиме, тогда ваш publicPath будет изменен перед путем и добавит значение publicPath

Как настроить исходную карту с помощью devtool

Devtool настраивает исходную карту, проблема в том, что когда есть проблема с вашим кодом, она будет сопоставлена ​​с ошибкой в ​​​​вашем исходном каталоге файлов, а не с упакованной ошибкой, это также очевидно, если вы не установите его, только очень неблагоприятно найти ошибки в файле bundle.js после упаковки.

devtool:'inline-cheap-source-map'

В соответствии с различными средами необходимо установить devtool.В среде разработки нам нужно видеть, где наш код сообщает об ошибках, поэтому нам нужно настроить

На официальном сайте webpack есть введение в документацию

Тогда мы приходим к выводу 👇

  • В среде разработки настройтеdevtool:'cheap-module-eval-source-map'
  • В производственной среде настройтеdevtool:'cheap-module-source-map'
// development devtool:'cheap-module-eval-source-map'
// production  devtool:'cheap-module-source-map'

Как использовать webpack-dev-сервер

webpack-dev-server можно использовать для быстрой разработки приложений. Многие конфигурации доступны на официальном сайте webpack,кликните сюда

скачать его первым

cnpm i clean-webpack-plugin -D

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

devServer: {
        contentBase: path.join(__dirname, "dist"),   // dist目录开启服务器
        compress: true,    // 是否使用gzip压缩
        port: 9000,    // 端口号
        open : true   // 自动打开网页
    },

Многие элементы конфигурации, вы можете перейти к официальной документации для просмотра, например, прокси-сервер и другие элементы конфигурации, дополнительную документацию.кликните сюда

Тогда элемент конфигурации скриптов в package.json выглядит следующим образом

"start": "webpack-dev-server"

Этот devServer может определить, изменился ли файл в режиме реального времени.

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

Суммировать

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

горячая замена модуля

Функция замены горячего модуля (HMR — замена горячего модуля) заменяет, добавляет или удаляет приложение во время его работы.модуль, без перезагрузки всей страницы.

Как следует из названия, это говорит о том, что перед несколькими модулями, когда вы изменяете модуль без перезагрузки всей страницы, вы можете использоватьhot module replacement

Например, когда вы модифицируете некоторые стили в коде CSS и не настроите горячую замену модуля HMR, будет перерисована вся страница, что не нужно, тогда настроим дальше👇

devServer: {
        contentBase: path.join(__dirname, "dist"),
        compress: true,
        port: 9000,
        open: true,
        hot: true,   // 开启热更新
        // hotOnly: true,
    },

Этот hotOnly можно установить, самое главное установитьhot:true

Затем добавьте два плагина, этот плагин поставляется с веб-пакетом, поэтому его не нужно скачивать👇

const webpack = require('webpack')
plugins: [
        new webpack.NamedModulesPlugin(),  // 可配置也可不配置
        new webpack.HotModuleReplacementPlugin() // 这个是必须配置的插件
    ],

ДобавленNamedModulesPlugin, чтобы упростить просмотр зависимостей для исправления.

После настройки приведенной выше информации, если вы снова запустите команду, вы обнаружите, что она запущена.模块热替换, обновления файлов разных модулей, будет загружен только текущий файл модуля

Единственное, что нужно отметить, это то, что для модификации содержимого css нижний слой css-загрузчика поможет нам делать горячие обновления в режиме реального времени.Для модулей JS нам нужно настроить вручную👇

if(module.hot){
    module.hot.accept('./print',()=>{
        print()
    })
}

Этот официальный также дает синтаксис, module.hot.accept(module1,callback) означает принять модуль, который нуждается в горячем обновлении в реальном времени, когда содержимое изменится, это поможет вам обнаружить его, а затем выполнить функцию обратного вызова

Суммировать

  • Проблема, которую решает горячая замена модулей HMR, заключается в том, что она позволяет обновлять различные модули во время выполнения без необходимости полного обновления.
  • Это означает, что нет необходимости снова обращаться к локальному серверу, чтобы перезагрузить другие ресурсы, которые были изменены.
  • Следует отметить, что для горячих обновлений файлов js необходимо вручную определять содержимое обновления, то есть синтаксис module.hot.accept

Для получения дополнительной информации о конфигурации перейдите на официальный веб-сайт webpack, чтобы просмотреть,Нажмите здесь, чтобы просмотреть HMR

Babel обрабатывает синтаксис ES6

Далее мы настроим его 👇

npm install --save-dev babel-loader @babel/core
// @babel/core 是babel中的一个核心库

npm install --save-dev @babel/preset-env
// preset-env 这个模块就是将语法翻译成es5语法,这个模块包括了所有翻译成es5语法规则

npm install --save @babel/polyfill
// 将Promise,map等低版本中没有实现的语法,用polyfill来实现.

Настроить модуль👇

module: {
  rules: [
    {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader",
            options: {
                "presets": [
                    [
                        "@babel/preset-env",
                        {
                            "useBuiltIns": "usage"
                        }
                    ]
                ]
            }
        }
  ]
}
// exclude参数: node_modules目录下的js文件不需要做转es5语法,也就是排除一些目录
// "useBuiltIns"参数:
  • имеютpreset-envПосле этого модуля мы обнаружим, что написалисинтаксис const транслируется в var
  • Однако, если вы будете осторожны, вы обнаружите, что браузеры с низкими версиями не поддерживают синтаксис Promise и map.
  • так что нам нужно@babel/polyfillМодуль, который дополняет Promise и map для завершения этой функции, о чем я говорил ранее.polyfill

Тогда как мы его используем?Просто импортируйте его в начало js-файла👇

import "@babel/polyfill";

Однако внимательные студенты найдут проблему.После использования этого, размер упакованных файлов увеличился более чем в 10 раз в одно мгновение.Почему это?

Это потому что,@babel/polyfillЧтобы компенсировать функции Promise, map и других синтаксисов, этот модуль долженРеализуйте Promise, map и другие грамматики самостоятельно.функция, поэтому упакованный файл очень большой.

тогда нам нужно@babel/polyfillВы можете настроить некоторые параметры следующим образом👇

"useBuiltIns": "usage"

Функция этого синтаксиса такова: мы будем полифилить только тот синтаксис, который используется в файлах, которые мы сейчас упаковываем в index.js, например Promise и map, а также другие синтаксисы, которых нет в es6. , Таким образом, размер упакованного файла уменьшается.

Суммировать

  • Необходимо следить за загрузчиком babel @babel/core для этих библиотек, @babel/core — его основная библиотека.
  • @babel/preset-env Содержит правила синтаксиса для перевода es6 в es5.
  • @babel/polyfill решает часть синтаксиса es6, который не может быть реализован в браузерах с низкими версиями, и использует polyfill для самостоятельной реализации.
  • пройти черезimport "@babel/polyfill";Представлен в начале файла js для завершения полифилла синтаксиса es6.
  • Вышеупомянутые сценарии предназначены для решения проблемы Babel, возникающей в бизнесе.

Дополнительные сведения о настройке см. в официальной документации,кликните сюда

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

@babel/plugin-transform-runtimeЭта библиотека может решить нашу проблему, тогда мы сначала устанавливаем нужную библиотеку

npm install --save-dev @babel/plugin-transform-runtime

npm install --save @babel/runtime

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

{
    
    "plugins": [
      [
        "@babel/plugin-transform-runtime",
        {
          "corejs": 2,
          "helpers": true,
          "regenerator": true,
          "useESModules": false
        }
      ]
    ]
  }
// 当你的 "corejs": 2,需要安装下面这个
npm install --save @babel/runtime-corejs2

В этом случае при использовании синтаксиса нет необходимости передаватьimport "@babel/polyfill";Такого рода грамматика закончена, просто пишите нормально, и с точки зрения запакованного тома, это вообще-то приемлемо

Суммировать

  • С точки зрения бизнеса вы можете использовать@babel/preset-env
  • При создании сторонней библиотеки или пользовательского интерфейса от себя используйте@babel/plugin-transform-runtime, его роль состоит в том, чтобы изменить как помощник, так и полифилл, чтобы импортировать их из единого места, а импортированные объекты и глобальные переменные полностью изолированы, что позволяет избежать глобального загрязнения.

Расширенные концепции веб-пакетов

Как использовать встряхивание деревьев

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

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

Следует отметить, что встряска дерева будет выполняться по умолчанию при производстве webpack4.

optimization.usedExports

Заставьте веб-пакет определять использование экспорта каждого модуля. зависит отoptimization.providedExportsКонфигурация.optimization.usedExportsСобранная информация будет использована другими оптимизациями или кодом вывода (экспорты, не используемые модулем, не будут экспортированы, а имя экспорта будет запутано в один символ, если синтаксис полностью совместим). Чтобы свести к минимуму размер кода, неиспользуемые экспорты удаляются. Производство включено по умолчанию.

module.exports = {
  //...
  optimization: {
    usedExports: true
  }
};

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

Отметить файлы как не содержащие побочных эффектов

Иногда, когда наши модули не очень чистые, в это время веб-пакет не может определить, какой код нужно удалить, поэтому в это время необходимо предоставить компилятору веб-пакета подсказки, какой код является «чистой частью».

Этот путь через package.json"sideEffects"реализованы свойства.

{
  "name": "webpack-demo",
  "sideEffects": false
}

Как упоминалось выше, если весь код не содержит побочных эффектов, мы можем просто пометить свойство какfalse, чтобы сообщить веб-пакету, что он может безопасно удалить неиспользуемые экспорты.

Обратите внимание, что любые импортированные файлы подвержены встряхиванию дерева. Это означает, что если вы используете в своем проекте что-то вроде css-loader и импортируйте файл CSS, вам нужно добавить его в список побочных эффектов, чтобы избежать его непреднамеренного удаления в рабочем режиме:

{
  "name": "webpack-demo",
  "sideEffects": [
    "*.css"
  ]
}

Сжатый вывод

Вышеуказанным способом мы уже можем пройтиimportиexportсинтаксис, чтобы узнать "мертвый код", который необходимо удалить, однако мы не просто узнаем, нам также нужно удалить их в комплекте. Для этого мы будем использовать-p(производство) Этот флаг сборки веб-пакета для включения плагина минимизации uglifyjs.

Начиная с веб-пакета 4, также можно передать"mode"Параметры конфигурации для легкого переключения на сжатый вывод, просто установите на"production".

Суммировать

  • Чтобы использовать встряхивание дерева, вам необходимо использовать синтаксис модуля ES, который является синтаксисом модуля ES2015 (т.importиexport).
  • в проектеpackage.jsonфайл, добавьте запись «sideEffects».
  • Введите минификатор, который удаляет мертвый код (например,UglifyJSPlugin), и, конечно же, запускается webpack4 и поддерживает сжатый вывод.

Для основной статьи вы можете увидеть этоПрактика оптимизации производительности Tree-Shaking — принципы

developmentиproductionСборка среды

В среде разработки и производственной среде функции, на которые мы опираемся, разные, например👇

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

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

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

установка слияния веб-пакетов

Тогда первое, что вам нужно установить, этоwebpack-merge, а затем объединить их вместе.

cnpm install --save-dev webpack-merge

Тогда наш каталог выглядит так👇

 webpack-demo
  |- build
    |- webpack.common.js  //三个新webpack配置文件
    |- webpack.dev.js    //三个新webpack配置文件
    |- webpack.prod.js  //三个新webpack配置文件
  |- package.json
  |-postcss.config.js
  |-.babelrc
  |- /dist
  |- /src
    |- index.js
    |- math.js
  |- /node_modules

Так что учитесь сейчас, смотрите, какая информация настроена👇

webpack.common.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const commonConfig = {
    entry: {
        main: './src/index.js',
    },
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader"
        }, {
            test: /\.(jpg|gif|png)$/,
            use: {
                loader: 'url-loader',
                options: {
                    name: '[name]_[hash].[ext]',
                    outputPath: 'images/',
                    limit: 1024 //100KB
                }
            }
        }, {
            test: /\.css$/,
            use: ['style-loader', 'css-loader', 'postcss-loader']
        }, {
            test: /\.scss$/,
            use: ['style-loader',
                {
                    loader: 'css-loader',
                    options: {
                        importLoaders: 2,
                        modules: true
                    }
                },
                'sass-loader',
                'postcss-loader'
            ]
        }, {
            test: /\.(woff|woff2|eot|ttf|otf)$/,
            use: [
                'file-loader'
            ]
        }]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/index.html' // 以src/目录下的index.html为模板打包
        }),
        new CleanWebpackPlugin({
            // 不需要做任何的配置
        }),
    ],
    output: {
        filename: '[name].js',
        // publicPath: "https://cdn.example.com/assets/",
        path: path.join(__dirname, '../dist')
    }
}

module.exports = commonConfig

webpack.dev.js

const path = require('path')
const webpack = require('webpack')
const {merge} = require('webpack-merge')
const commonConfig = require('./webpack.common')

const devConfig = {
    mode: 'development',
    devtool: 'cheap-module-eval-source-map',
    devServer: {
        contentBase: path.join(__dirname, "dist"),
        compress: true,
        port: 9000,
        open: true,
        hot: true,
        // hotOnly: true,
    },
    plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin(),
    ],
    optimization:{
        usedExports: true
    }
}

module.exports = merge(commonConfig, devConfig)

webpack.prod.js

const {merge} = require('webpack-merge')
const commomConfig = require('./webpack.common')
const prodConfig = {
    mode: 'production',
    devtool: 'cheap-module-source-map',
}

module.exports = merge(commomConfig, prodConfig)

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

NPM Scripts

Теперь мы ставимscriptsПовторно указать на новую конфигурацию. мы будемnpm run devопределяется каксреда разработкисценарий и использовать в немwebpack-dev-server,будетnpm run buildопределяется какПроизводственная средасценарий:

  {
    "name": "webpack-demo",
    "scripts": {
    "dev": "webpack-dev-server --config ./build/webpack.dev.js",
    "build": "webpack --config ./build/webpack.prod.js",
    "start": "npx webpack --config ./build/webpack.dev.js"
  	},
  }

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

Еще одна вещь, которую следует отметить, это то, чтоclean-webpack-pluginКонфигурация этого плагина, когда вы помещаете его в каталог сборки, создается корневой каталог плагина, поэтому нам нужно его изменить👇

		new CleanWebpackPlugin({
            // 不需要做任何的配置
        }),

Новейшиеclean-webpack-plugin, нет необходимости задавать очистку каталога, автоматически очищается путь упаковки, то есть каталог dist.

SplitChunksPlugin Разделение кода

Если у вас есть несколько входных файлов или упакованные файлы необходимо разделить, например, сторонние библиотеки lodash, jquery и другие библиотеки необходимо упаковать в каталог, а ваш собственный код бизнес-логики необходимо упаковать в файл, это В то время необходимо извлечь общедоступные модули, и необходим плагин SplitChunksPlugin.

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

module.exports = {
  //...
  optimization: {
    splitChunks: {
        chunks: "async",
        minSize: 30000,
        minChunks: 1,
        maxAsyncRequests: 5,
        maxInitialRequests: 3,
        automaticNameDelimiter: '~',
        name: true,
        cacheGroups: {
            vendors: { 
                test: /[\\/]node_modules[\\/]/,  //匹配node_modules中的模块
                priority: -10   //优先级,当模块同时命中多个缓存组的规则时,分配到优先级高的缓存组
            },
        default: {
                minChunks: 2, //覆盖外层的全局属性
                priority: -20,
                reuseExistingChunk: true  //是否复用已经从原代码块中分割出来的模块
            }
        }
    }
  },
};

Итак, начнем с каждого параметра👇

  • Параметры атрибутов на внешнем уровне CacheGroups применяются ко всем группам кэша, но каждую группу кэша можносноваустановить их значения
  • chunks: "async"Это свойство установлено вкакой типКод разделен строкой и имеет три значения
    • initialблок кода входа
    • allвсе
    • asyncБлоки кода загружаются по запросу
  • minSize: 30000Будут извлечены только модули, размер которых превышает 30 КБ.
  • minChunks: 1, Когда на модуль ссылается хотя бы сколько модулей, он будет извлечен в новый фрагмент
  • maxAsyncRequests: 5, После разделения максимальное количество параллельных запросов, разрешенных для блоков кода, загружаемых по запросу.
  • maxInitialRequests: 3·После разделения максимальное количество параллельных запросов, разрешенных для блока кода входа
  • automaticNameDelimiter: "~"разделитель имен блоков кода
  • name: true, Имя блока кода, упакованного каждой группой кэша
  • cacheGroupsКэш группы, настроить соответствующие правила.

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

Вот статья о том, как разделить код в реальном проекте, если интересно, можете глянуть.Пример кода SplitChunk

Ленивая загрузка Ленивая загрузка и чанки

импорт загружает модули асинхронно

In WebPack, what is lazy loading, give an example, when I need to introduce a module on demand, then we can use lazy loading, in fact, the implementation plan is the Import grammar, when you reach a condition, we Will ask for Ресурсы.

Итак, давайте посмотрим, как реализовать ленивую загрузку👇

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

cnpm install --save-dev @babel/plugin-syntax-dynamic-import

после этого.babelrcКонфигурация файла, добавить плагин

{
  "plugins": ["@babel/plugin-syntax-dynamic-import"]
}

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

// create.js
async function create() {
    const {
        default: _
    } = await import(/*webpackChunkName:"lodash"*/'lodash')
    let element = document.createElement('div')
    element.innerHTML = _.join(['TianTian', 'lee'], '-')
    return element
}

function demo() {
    document.addEventListener('click', function () {
        create().then(element => {
            document.body.appendChild(element)
        })
    })
}

export default demo;

Функция моего модуля заключается в том, что при нажатии на страницу сработает функция создания, затем будет загружена библиотека loadsh, и, наконец, lodash будет лениво загружен на странице.Упаковка обычно упакована, но некоторые ресурсы могут срабатывать при срабатывании определенных условий.Затем перейти к загрузке, это тоже метод оптимизации.

Chunk

Чанк — это блок кода в Webpack. К какому типу блока кода он относится? 👇

Чанк — это набор модулей в процессе упаковки Webpack. Webpack упаковывает модули один за другим через ссылочное отношение, и эти модули образуют фрагмент.

Три способа сгенерировать чанк

  • Вход
  • Загружать модули асинхронно
  • разделение кода

Чанк — это просто концепция, понимание концепции чанка больше способствует определенному пониманию веб-пакета.

Сжатие и извлечение кода CSS

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

mini-css-extract-pluginизвлечение кода css

Извлеките css как отдельный файловый плагин, поддержите загрузку css и sourceMap по запросу, мы можем проверить официальный GitHub, чтобы увидеть егоДокументация

** В настоящее время функция HMR отсутствует. **Итак, мы можем применить его к среде сборки и начать установку👇

npm install --save-dev mini-css-extract-plugin

Для использования этого плагина рекомендуется настроить его в webpack.prod.js (производственная среда) Этот плагин пока не поддерживает HMR, а разработка в среде разработки требует HMR, поэтому на этот раз мы только настроим , Настраивается в webpack.prod.js.

Следует отметить, что если ваш веб-пакет версии 4, вам необходимо настроить его в package.json.sideEffectsсвойства, так чтоИзбегайте файлов css как Tree-shaking.

{
  "name": "webpack-demo",
  "sideEffects": [
  	"*.css"
  ]
}

Затем давайте посмотрим, как webpack.prod.js настраивает параметры.

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {
    merge
} = require('webpack-merge')
const commomConfig = require('./webpack.common')

const prodConfig = {
    mode: 'production',
    devtool: 'cheap-module-source-map',
    plugins: [
        new MiniCssExtractPlugin({
            filename:'[name].[hash].css',
            chunkFilename: '[id].[hash].css',
        })
    ],
    module: {
        rules: [{
            test: /\.(sa|sc|c)ss$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                'postcss-loader',
                'sass-loader',
            ],
        }]
    }
}

module.exports = merge(commomConfig, prodConfig)

Когда вы вводите модуль css в js, и, наконец, в каталоге dist, если вы видите отдельный Chunk css, это означает, что извлечение кода css прошло успешно, следующим шагом является исправлениеСжатие css-кода.

По умолчанию webpack4 не сжимает css-код в рабочей среде, поэтому нам нужно скачать плагин для

optimize-css-assets-webpack-pluginсжатие кода css

optimize-css-assets-webpack-pluginОфициальная документация GitHub

Это сожмет упакованный код css по строчному коду, скачиваем этот пакет👇

npm install --save-dev optimize-css-assets-webpack-plugin

Далее идет настройкаoptimization.minimizer, здесь следует отметить, что в настоящее время настройкаOptimizer.minimizer переопределяет правила, предоставляемые веб-пакетом по умолчанию, такие какJS-код больше не будет сжиматься.

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const {
    merge
} = require('webpack-merge')
const commomConfig = require('./webpack.common')

const prodConfig = {
    mode: 'production',
    devtool: 'cheap-module-source-map',
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                sourceMap: true,
                parallel: true, // 启用多线程并行运行提高编译速度
            }),
            new OptimizeCSSAssetsPlugin({}),
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            // 类似 webpackOptions.output里面的配置 可以忽略
            filename: '[name].[hash].css',
            chunkFilename: '[id].[hash].css'
        })
    ],
    module: {
        rules: [{
            test: /\.(sa|sc|c)ss$/,
            use: [{
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        // 这里可以指定一个 publicPath
                        // 默认使用 webpackOptions.output中的publicPathcss
                        // 举个例子,后台支持把css代码块放入cdn
                        publicPath: "https://cdn.example.com/css/"
                    },
                },
                'css-loader',
                'postcss-loader',
                'sass-loader',
            ],
        }]
    },

}

module.exports = merge(commomConfig, prodConfig)

Однако в это время будет обнаружено, что в производственной среде JS-сжатие также будет иметь проблемы, поэтому для решения проблемы мы разберемся ниже👇

сжатие кода плагина uglifyjs-webpack-plugin

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

npm install -D uglifyjs-webpack-plugin

Затем настройте указанную выше информацию в webpack.prod.js, см. дополнительные сведения о его конфигурации.Официальная документация сайта

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const {
    merge
} = require('webpack-merge')
const commonConfig = require('./webpack.common')

const prodConfig = {
    mode: 'production',
    devtool: 'cheap-module-source-map',
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                sourceMap: true,
                parallel: true,  // 启用多线程并行运行提高编译速度
            }),
            new OptimizeCSSAssetsPlugin({}),
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            // 类似 webpackOptions.output里面的配置 可以忽略
            filename: '[name].[hash].css',
            chunkFilename: '[id].[hash].css'
        })
    ],
    module: {
        rules: [{
            test: /\.(sa|sc|c)ss$/,
            use: [{
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        // 这里可以指定一个 publicPath
                        // 默认使用 webpackOptions.output中的publicPathcss
                        // 举个例子,后台支持把css代码块放入cdn
                        publicPath: "https://cdn.example.com/css/"
                    },
                },
                'css-loader',
                'postcss-loader',
                'sass-loader',
            ],
        }]
    },

}

module.exports = merge(commonConfig, prodConfig)

Для среды разработчика извлекать и упаковывать css-код бессмысленно, а унификация снизит эффективность сжатия js-кода, а так делать не рекомендуется, поэтому в среде разработки код для них пропускаем.

contenthash решает кеш браузера

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

В webpack есть три вида хэшей, это 👇

hash

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

chunkhash

Это связано с упакованным чанком, в частностиwebpackосновывается на входеentryконфигурационный файл для анализа его зависимостей и сборкиentry的chunk, и сгенерируйте соответствующийhashценность. разныеchunkбудет другимhashценность.

В рабочей среде стороннюю или публичную библиотеку классов мы упакуем отдельно, поэтому код публичной библиотеки не изменится.chunkизhashОн не изменится, и кеш браузера можно использовать разумно.

Однако на самом деле в этом есть проблема с методом хеширования.В производственной среде мы будем использоватьwebpackплагин, который будетcssКод извлекается и упаковывается отдельно. В этот моментchunkhashметод недостаточно гибкий, потому что пока один и тот жеchunkПосле того, как js внутри изменен,cssизchunkизhashИзменения последуют. Поэтому нам нужноcontenthash.

contenthash

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

Для веб-пакета, более старых версий, даже каждый раз, когда вы запускаете сборку npm,Если содержимое не изменено, значение contenthash все равно изменится., это потому, что, когда у вас есть взаимосвязь между модулями, существуетфайл манифеста.

Файл манифеста используется для руководства взаимодействием всех модулей.Файл манифеста содержит логику для загрузки и обработки модулей.Например, упакованный файл вашей сторонней библиотеки называется vendors, а код вашей логики называется main.Когда если веб-пакет создает пакет, он также будет поддерживать файл манифеста.Вы можете понять, что каждый файл пакета содержит эту информацию, поэтому информация манифеста для каждого пакета отличается, поэтому нам нужно предоставить файл манифеста для извлечения.

В это время необходимоoptimizationДобавьте конфигурацию в 👇

module.exports = {
  optimization: {
    splitChunks: {
      // ...
    },
    runtimeChunk: {// 解决的问题是老版本中内容不发生改变的话,contenthash依旧会发生改变
      name: 'manifest'
    }
  }
}

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

Сказав это, давайте посмотрим, как мы должны настроить вывод.Давайте сначала посмотрим на конфигурацию webpack.prod.js

output: {
        filename: '[name].[contenthash].js',
        chunkFilename:'[vendors].[contenthash].js',
        // publicPath: "https://cdn.example.com/assets/",
        path: path.join(__dirname, '../dist')
    }

Для webpack.dev.js вам нужно только изменить хеш контента на хэш, поэтому при разработке таким образом повышается эффективность разработки.

шимминговая глобальная переменная

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

нам нужно использоватьProvidePluginПлагин, этот веб-пакет встроен, и шимминг зависит от этого плагина.

использоватьProvidePluginПосле этого пакет package можно получить, обратившись к переменной в каждом модуле, скомпилированном webpack.

Добавьте конфигурацию плагина👇

new webpack.ProvidePlugin({
			// 这里设置的就是你相应的规则了
			// 等价于在你使用lodash模块中语句👇
			// import _ from 'lodash'
            _: 'lodash'
})

Например👇

// array_add.js
export const Arr_add = arr=>{
    let str = _.join(arr,'++');
    return str;
}

Таким образом, если библиотека lodash не импортируется нормально, будет сообщено об ошибке, но мы используем подключаемый модуль ProvidePlugin, чтобы он предоставил соответствующий пакет lodash.Обратите внимание, что во избежание многократной упаковки нескольких пакетов lodash, ты можешь использоватьCommonsChunkPluginплагин, webpack4 отказался от него, используяsplitChunksPluginЕго заменяет плагин, который я прошерстил в предыдущем месте.

Больше использования можно посмотретьрегулировочная прокладка


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

закуска

❤️ Всем спасибо

Если вы считаете этот контент полезным:

  1. Поставьте лайк и поддержите его, чтобы больше людей увидело этот контент
  2. Обратите внимание на публичный аккаунт前端UpUp, регулярно публиковать хорошие статьи для вас.
  3. Если вы считаете, что это хорошо, вы также можете прочитать последние статьи TianTian (спасибо за вашу поддержку и поддержку 🌹🌹🌹):