Webpack идет глубже и резюмирует

интервью внешний интерфейс Webpack
Webpack идет глубже и резюмирует

предисловие

Эта статья является вторым углубленным и практическим углубленным знанием Webpack автором и обобщает результаты, основанные на понимании и практике;

Содержание статьи относится к книге «Введение в Webpack», так как книга основана на версии Webpack 3.4.0, а практика этой статьи основана на версии Webpack 4.28.2, поэтому она также наступила на многие питы из-за проблемы с версией модуля, которая была кратко изложена в главе 6. Резюме питов, все помните, чтобы не наступать на питы, это также подтверждает философию: то, что вы получите на бумаге, будет поверхностным, и вы должны это сделать, если вы знай это...

Адрес блога на github:GitHub.com/ревматизм123/…, обобщает все блоги автора, и приглашаем подписаться и отметиться ~

В этой статье практикуется демонстрациягитхаб-адрес

1. Принцип вебпака

1. Строительство

Инструмент сборки преобразует исходный код в исполняемый код JavaScript, CSS и HTML, включая следующее:

  • Преобразование кода: компиляция TypeScript в JavaScript, SCSS в CSS и т.д.;

  • Оптимизация файлов: сжатие JavaScript, CSS, HTML-кода, сжатие и объединение изображений и т. д.;

  • Сегментация кода: извлеките общий код нескольких страниц, извлеките код, который не нужно выполнять на первом экране, и дайте ему загрузиться асинхронно;

  • Слияние модулей: в модульном проекте будет много модулей и файлов, и модули необходимо классифицировать и объединить в один файл с помощью функции сборки;

  • Автоматическое обновление: отслеживайте изменения локального исходного кода, автоматически перестраивайте и обновляйте браузер;

  • Проверка кода: перед отправкой кода на склад необходимо проверить, соответствует ли код спецификации и проходит ли модульный тест;

  • Автоматический выпуск: после обновления кода код онлайн-релиза автоматически создается и передается в систему выпуска;

2. Основные концепции

Webpack имеет следующие основные концепции:

  • Вход : Вход, первый шаг построения Webpack начнется с входа, который можно абстрагировать на ввод;

  • Module: модуль, который настраивает правила обработки модулей, в Webpack все является модулем, и одному модулю соответствует один файл, Webpack будет рекурсивно находить все зависимые модули от настроенного Entry;

  • Загрузчик: преобразователь модулей, который используется для преобразования исходного содержимого модуля в новое содержимое по мере необходимости;

  • Решаем: настроить правила поиска модулей;

  • Плагин: плагины расширения, которые транслируют соответствующие события в определенное время в процессе создания Webpack, плагины могут отслеживать возникновение этих вещей и выполнять соответствующие действия в определенное время;

  • Вывод: Выведите результат после того, как Webpack пройдет серию обработок и получит окончательный желаемый код;

  • Чанк: блок кода, чанк состоит из нескольких модулей для слияния и разделения кода;

3. Обзор процесса

(1) Параметры инициализации: чтение и объединение параметров из файла конфигурации и инструкции Shell для получения окончательных параметров;

(2) Начать компиляцию: Инициализируйте объект Compiler с параметрами, полученными на предыдущем шаге, загрузите все настроенные плагины и начните компиляцию, выполнив метод запуска объекта;

(3) Определите запись: найдите все файлы записей в соответствии с записью в конфигурации;

(4) Скомпилируйте модуль: начиная с файла записи, вызовите все настроенные загрузчики для преобразования модуля, затем найдите модули, от которых зависит модуль, а затем повторите этот шаг, пока все файлы, зависящие от записи, не будут обработаны в этом шаг;

(5) Завершение компиляции модуля: после перевода всех модулей с помощью загрузчика на шаге 4 получается окончательное содержимое каждого модуля после перевода и зависимости между ними;

(6) Выходные ресурсы: в соответствии с зависимостями между записью и модулем собрать фрагменты, содержащие несколько модулей, а затем преобразовать каждый фрагмент в отдельный файл и добавить его в выходной список, что может изменить выходное содержимое в последнюю очередь;

(7) Вывод завершен: после определения содержимого вывода определите путь вывода и имя файла в соответствии с конфигурацией и запишите содержимое файла в файловую систему;

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

2. Конфигурация веб-пакета

1. Инициализация проекта Webpack

1. Создайте новый веб-проект

Создайте новый каталог, затем войдите в корневой каталог проекта и выполните npm init для инициализации простейшего модульного проекта разработки, наконец, сгенерируйте файл package.json;

$ npm init

2. Установите Webpack в этот проект

(1) Проверьте версию Webpack

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

$ npm view webpack versions

(2) Установить веб-пакет

Вы можете выбрать номер версии Webpack, указанный в шаге (1), или вы можете установить последнюю стабильную версию и последнюю рабочую версию. просто хочу установить версию 4.x );

// 安装指定版本
npm i -D webpack@4.28.2

// 安装最新稳定版
npm i -D webpack

// 安装最新体验版本
npm i -D webpack@beta

(3) Установите каркас Webpack

Чтобы выполнить команду Webpack в командном окне, необходимо установить скаффолдинг Webpack.Выполните следующую команду, чтобы установить скаффолдинг Webpack;

$ npm i -D webpack-cli

3. Используйте веб-пакет

Используйте Webpack для создания проекта, написанного на модульной основе CommonJS;

(1) Создайте новый файл входа страницы index.html.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Webpack</title>
</head>
<body>
<!--导入 Webpack 输出的 JavaScript 文件-->
<script src="./dist/bundle.js"></script>  
</body>
</html>

(2) Создайте новый файл JS, который необходимо использовать.

файл show.js

// 操作 DOM 元素,把 content 显示到网页上
function show(content) {
  window.document.getElementById('app').innerText = 'Hello,' + content;
}

// 通过 CommonJS 规范导出 show 函数
module.exports = show;

файл main.js

// 通过 CommonJS 规范导入 show 函数
const show = require('./show.js');
// 执行 show 函数
show('Webpack');

(3) Создайте новый файл конфигурации Webpack webpack.config.js.

const path = require('path');

module.exports = {
  // JavaScript 执行入口文件
  entry: './main.js',
  output: {
    // 把所有依赖的模块合并输出到一个 bundle.js 文件
    filename: 'bundle.js',
    // 输出文件都放到 dist 目录下
    path: path.resolve(__dirname, './dist'),
  }
};

(4) Выполните команду webpack для сборки

Настройте команду компиляции в файле package.json следующим образом:

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

Выполните следующую команду, чтобы скомпилировать Webpack проекта. После успешного завершения каталог компиляции dist будет создан в корневом каталоге проекта;

$ npm run build

(5) Запустите index.html

После успешной компиляции мы используем браузер, чтобы открыть файл index.html, и мы видим, что страница успешно отображает «Hello Webpack»;

2. Конфигурация загрузчика

В этом разделе делается попытка использовать загрузчики, добавляя стили к предыдущим примерам;

(1) Создайте новый файл стиля main.css

#app{
  text-align: center;
  color:'#999';
}

(2) Вставьте файл main.css в файл ввода main.js следующим образом:

// 通过 CommonJS 规范导入 CSS 模块
require('./main.css');

// 通过 CommonJS 规范导入 show 函数
const show = require('./show.js');
// 执行 show 函数
show('Webpack');

(3) Конфигурация загрузчика

После вышеуказанной модификации будет сообщено об ошибке при выполнении сборки Webpack, поскольку Webpack изначально не поддерживает синтаксический анализ файлов CSS. Для поддержки файлов, отличных от JavaScript, вам необходимо использовать механизм загрузчика Webpack;

(3.1) Запустите следующие команды, чтобы установить загрузчик стилей и загрузчик css, где:

  • css-loader используется для чтения файлов CSS;
  • style-loader вставляет содержимое CSS в JavaScript;
$ npm i -D style-loader css-loader

(3.2) Сделайте следующую конфигурацию

module:{
rules:[
  {
	// 用正则去匹配要用该 loader 转换的 CSS 文件
	test:/\.css$/,
	use:['style-loader','css-loader']
  }
 ]
}

(4) Просмотр результатов

После компиляции обновите index.html, чтобы увидеть, что только что загрузчик стилей работал;

1

3. Настройка плагина

(1) Установите плагин для извлечения стилей extract-text-webpack-plugin

$ npm i -D extract-text-webpack-plugin@next

(2) Конфигурация файла плагина выглядит следующим образом

  module:{
    rules:[
      {
        // 用正则去匹配要用该 loader 转换的 CSS 文件
        test:/\.css$/,
        use:ExtractTextPlugin.extract({
          use:['css-loader']
        }),
      }
    ]
  },
  plugins:[
    new ExtractTextPlugin({
       // 从 .js 文件中提取出来的 .css 文件的名称
       filename:`[name]_[hash:8].css`
    }),
  ]

(3) Просмотр результатов

После приведенной выше конфигурации выполните команду выполнения Webapack и обнаружите, что соответствующий файл css создается в каталоге dist; существующие питы:

  • Нам нужно вручную импортировать сгенерированный файл css в index.html;
  • После изменения файла css будет сгенерирован новый файл css, а исходный не будет удален;

4. Использование DevServer

(1) Выполните следующую команду, чтобы установить webpack-dev-server

$ npm i -D  webpack-dev-server

Настройте команды запуска в package.json

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

После запуска команды вы можете запустить службу HTTP

$ npm run dev

Результат запуска следующий, мы можем пройтиhttp://localhost:8080/Посетите демонстрацию нашего index.html

1

(2) Предварительный просмотр в реальном времени

Мы добавляем параметр --watch после запущенной команды для достижения предварительного просмотра в реальном времени.Конфигурация выглядит следующим образом:

  "scripts": {
    "dev": "webpack-dev-server --watch"
  },

Затем мы изменили входящие параметры main.js и обнаружили, что предварительного просмотра в реальном времени не было, и об ошибках не сообщалось! ! ! Зачем?

Ступайте на яму:

В index.html вам нужно изменить путь js на:

<script src="bundle.js"></script>  

Он не может быть предыдущим (потому что он компилируется и генерируется, а не генерируется devServer и помещается в память)

<script src="./dist/bundle.js"></script> 

(3) Горячая замена модуля

Модули можно заменять в горячем режиме, настроив --hot;

3. Оптимизация веб-пакета

Практика оптимизации уже практиковалась ранее, и я не буду повторять ее здесь. Заинтересованные детской обувью могут ознакомиться с другой статьей, написанной автором"Практика оптимизации Webpack проекта Vue, эффективность сборки увеличена на 50%

В-четвертых, напишите Loader

1. Сводка баллов погрузчика

(1) загрузчик — это преобразователь модулей, который используется для преобразования исходного содержимого модуля в новое содержимое по мере необходимости;

(2) Обязанности погрузчика едины, необходимо выполнить только одно преобразование, и соблюдается принцип единой ответственности;

(3) Webpack предоставляет Loader ряд API для вызова Loader, например:

  • loader-utils.getOptions( this ) Получить параметры, переданные пользователем,
  • this.callback() настроить возвращаемый результат,
  • this.async() поддерживает асинхронные операции;
  • this.context Каталог, в котором находится текущий файл;
  • this.resource Полный путь запроса обрабатываемого в данный момент файла;
  • другое и т.д.

2. Напишите исходный код загрузчика

Напишите исходный код загрузчика вручную. Его функция заключается в преобразовании /hello/gi в HELLO. Конечно, этот загрузчик не имеет практического значения. Он предназначен исключительно для написания загрузчика. Конечно, если ваш реальный бизнес требует написания требований к загрузчику, Вам нужно задуматься о рациональности этого дела, ведь огромное комьюнити, в общем-то под разумные нужды может найти соответствующий загрузчик.

(1) Компиляция исходного кода

В исходном проекте создайте новый каталог custom-loader в качестве имени нашего загрузчика, выполните команду npm init, создайте новый модульный проект, а затем создайте новый файл index.js Соответствующий исходный код выглядит следующим образом:

function convert(source){
  return source && source.replace(/hello/gi,'HELLO');
}

module.exports = function(content){
  return convert(content);
}

(2) Регистрация модуля ссылки Npm

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

В каталоге custom-loader выполните следующую команду, чтобы зарегистрировать локальный модуль в глобальном:

$ npm link

Успешный результат выглядит следующим образом:

1

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

$ npm link custom-loader

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

1

3. Загрузчик, настроенный в Webpack

Эта конфигурация ничем не отличается от конфигурации Webpack в первой главе и подробно описываться здесь не будет.Справочник по конфигурации выглядит следующим образом:

  module:{
    rules:[
      {
        test:/\.js/,
        use:['custom-loader'],
        include:path.resolve(__dirname,'show')
      }
    ]
  }

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

5. Написать плагин

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

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

1. Резюме точек плагина

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

2. Напишите исходный код плагина

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

(1) Компиляция исходного кода

В исходном проекте создайте новый каталог custom-plugin в качестве имени плагина, который мы написали, выполните команду npm init, создайте новый модульный проект, а затем создайте новый файл index.js, Соответствующий исходный код выглядит следующим образом. :

class CustomPlugin{
  constructor(doneCallback, failCallback){
     // 保存在创建插件实例时传入的回调函数
     this.doneCallback = doneCallback;
     this.failCallback = failCallback;
  }
  apply(compiler){
    // 成功完成一次完整的编译和输出流程时,会触发 done 事件
    compiler.plugin('done',(stats)=>{
      this.doneCallback(stats);
    })
    // 在编译和输出的流程中遇到异常时,会触发 failed 事件
    compiler.plugin('failed',(err)=>{
      this.failCallback(err);
    })
  }
}
module.exports = CustomPlugin;

(2) Регистрация модуля ссылки Npm

Как и при регистрации загрузчика, мы используем ссылку npm для регистрации;

В каталоге custom-plugin выполните следующую команду, чтобы зарегистрировать локальный модуль в глобальном:

$ npm link

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

$ npm link custom-plugin

Если все пойдет хорошо, вы можете найти соответствующий плагин в каталоге node_modules;

3. Плагин настроен в Webpack

Эта конфигурация ничем не отличается от конфигурации Webpack в первой главе и подробно описываться здесь не будет.Справочник по конфигурации выглядит следующим образом:

  plugins:[
    new CustomPlugin(
     stats => {console.info('编译成功!')},
     err => {console.error('编译失败!')}
   ),
  ],

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

Шесть, наступив на яму

1. Следующая конфигурация css-загрузчика

rules:[
  {
	// 用正则去匹配要用该 loader 转换的 CSS 文件
	test:/\.css$/,
	use:['style-loader','css-loader?minimize']
  }
]

Сообщается о следующей ошибке:

 - options has an unknown property 'minimize'. These properties are valid:
   object { url?, import?, modules?, sourceMap?, importLoaders?, localsConventio               n?, onlyLocals?, esModule? }

причина:

Атрибут минимизации был удален в новой версии,

решать:

Сначала удалите опцию минимизации;

2. ExtractTextPlugin компилирует следующие ошибки:

1

причина:

Проблема с номером версии Extract-text-webpack-plugin

Ссылка на ссылку:GitHub.com/Webpack/Веб…

решать:

Переустановите экстракт-текст-вебпак-плагин

$ npm i -D extract-text-webpack-plugin@next

3. После исправления второй ямки компиляция ExtractTextPlugin продолжает выдавать следующую ошибку:

1

причина:

Переменная contenthash не существует

решать:

Измените конфигурацию extract-text-webpack-plugin:

  plugins:[
    new ExtractTextPlugin({
       // 从 .js 文件中提取出来的 .css 文件的名称
       filename:`[name]_[hash:8].css`
    }),
  ]

4. После добавления HappyPack при компиляции файла CSS сообщается о следующей ошибке:

1

причина:

Проблема с версией css-загрузчика

решать:

Переустановите css-loader@3.2.0

7. Резюме

Эта статья в основном основана на роли, основных концепциях и процессах Webpack, базовой конфигурации Webpack, оптимизации Webpack, написании загрузчика, написании плагина, от теории к практике, от простого к сложному, чтобы обобщить и освоить Webpack, я надеюсь, что это поможет и вам. Та же фраза: на бумаге это поверхностно, и если ты этого не знаешь, ты должен это сделать... Если ты раньше не стучал, ты должен больше двигаться!

Адрес блога на github:GitHub.com/ревматизм123/…, обобщает все блоги автора, и приглашаем подписаться и отметиться ~

В этой статье практикуется демонстрациягитхаб-адрес