«Кровавая рвота» и еще дюжина вопросов интервью Webpack

Webpack опрос
«Кровавая рвота» и еще дюжина вопросов интервью Webpack

"Видимость: 🌟🌟🌟🌟🌟"

"Вкус: Морской окунь на пару"

"Время приготовления: 15 мин."


Эта статья была включена вGithub github.com/Geekhyt, добро пожаловать в Звезду.

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

Похоже, вы хорошо знакомы с Webpack, тогда я вас протестирую

0. Каковы общие загрузчики? Какие загрузчики вы использовали?

(Я начал знакомы с отчетом от имени блюда)

  • raw-loader: загрузить необработанное содержимое файла (utf-8)

  • file-loader: вывод файла в папку, ссылка на выходной файл в коде через относительный URL (обработка изображений и шрифтов)

  • url-loader: Аналогично файл-загрузчику, разница в том, что пользователь может установить порог, если он больше порога, он будет передан на обработку файл-загрузчику, а если меньше порога, файл будет кодироваться в формате base64 (обработка картинок и шрифтов)

  • source-map-loader: загружать дополнительные файлы исходной карты для упрощения отладки точек останова.

  • svg-inline-loader: Вставка сжатого содержимого SVG в код.

  • image-loader: загружать и сжимать файлы изображений

  • json-loaderЗагрузить файл JSON (включен по умолчанию)

  • handlebars-loader: Скомпилируйте шаблон Handlebars в функцию и верните

  • babel-loader: конвертировать ES6 в ES5

  • ts-loader: конвертировать TypeScript в JavaScript

  • awesome-typescript-loader: Конвертируйте TypeScript в JavaScript с большей производительностью, чем ts-loader.

  • sass-loader: преобразование кода SCSS/SASS в CSS.

  • css-loader: загрузка CSS, поддержка таких функций, как модульность, сжатие, импорт файлов и т. д.

  • style-loader: вставка кода CSS в JavaScript и загрузка CSS с помощью манипуляций с DOM.

  • postcss-loader: Расширьте синтаксис CSS, используйте CSS следующего поколения и автоматически заполняйте префиксы CSS3 с помощью плагина autoprefixer.

  • eslint-loader: проверить код JavaScript через ESLint

  • tslint-loader: Проверить код TypeScript через TSLint.

  • mocha-loader: Код для загрузки тестовых случаев Mocha

  • coverjs-loader: вычисляет тестовое покрытие

  • vue-loader: загружает однофайловые компоненты Vue.js.

  • i18n-loader: глобализация

  • cache-loader: может быть добавлен перед некоторыми загрузчиками с высокой производительностью, целью является кеширование результатов на диск

Дополнительные загрузчики см.Официальный сайт

(Интервьюер: Очень хорошо, я много знаю)

1. Каковы общие плагины? Какие плагины вы использовали?

(Этот старший брат, кажется, пристрастился слушать его, продолжайте открывать нормальную работу)

  • define-plugin: определить переменные среды (режим будет автоматически настроен после Webpack4)

  • ignore-plugin: игнорировать некоторые файлы

  • html-webpack-plugin: Упрощенное создание файла HTML (зависит от html-загрузчика)

  • web-webpack-plugin: Простой вывод HTML для одностраничных приложений, лучше, чем html-webpack-plugin.

  • uglifyjs-webpack-plugin: минификация ES6 не поддерживается (до Webpack4)

  • terser-webpack-plugin: Поддерживает минимизированный ES6 (Webpack4)

  • webpack-parallel-uglify-plugin: Сжатие кода выполнения нескольких процессов, скорость сборки модернизации

  • mini-css-extract-plugin: Отдельные файлы стилей, извлечение CSS в отдельные файлы, поддержка загрузки по требованию (заменяет Extract-Text-Webpack-плагин)

  • serviceworker-webpack-plugin: добавить функцию автономного кэширования в веб-приложение.

  • clean-webpack-plugin: очистка каталога

  • ModuleConcatenationPlugin: Включить подъем области

  • speed-measure-webpack-plugin: Вы можете увидеть время выполнения каждого загрузчика и плагина (все время упаковки, время каждого плагина и загрузчика)

  • webpack-bundle-analyzer: визуализировать объем выходных файлов Webpack (бизнес-компоненты, зависимости от сторонних модулей)

Дополнительные плагины см.Официальный сайт

(Double Kill)

2. Тогда можете ли вы сказать мне разницу между загрузчиком и плагином?

(Зная, что вы спросите об этом, я прикрыл рукой улыбку в уголке рта)

LoaderСуть в функции, в которой происходит преобразование полученного контента и возврат преобразованного результата. Поскольку Webpack понимает только JavaScript, Loader становится переводчиком, предварительно обрабатывая другие типы ресурсов.

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

LoaderНастроенный в module.rules как правила синтаксического анализа модуля, тип представляет собой массив. Каждый элемент представляет собой объект, который содержит такие свойства, как тест (файл типа), загрузчик и параметры (параметры).

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

3. Кратко о процессе сборки Webpack

Работающий процесс Webpack является последовательным процессом, и следующие процессы выполняются последовательно от начала до конца:

  • 初始化参数: Чтение и объединение параметров из файлов конфигурации и операторов оболочки для получения окончательных параметров.

  • 开始编译: Инициализируйте объект Compiler с параметрами, полученными на предыдущем шаге, загрузите все настроенные плагины и выполните метод запуска объекта, чтобы начать компиляцию.

  • 确定入口: Найти все файлы ввода на основе записи в конфигурации

  • 编译模块: Начиная с файла записи, вызовите все настроенные загрузчики для перевода модуля, затем найдите модули, от которых зависит модуль, а затем повторите этот шаг, пока все файлы, от которых зависит запись, не будут обработаны на этом шаге.

  • 完成模块编译: После перевода всех модулей с помощью Loader на шаге 4 мы получаем окончательный контент каждого модуля после перевода и зависимости между ними

  • 输出资源: В соответствии с зависимостями между записью и модулем соберите их в чанки, содержащие несколько модулей, а затем преобразуйте каждый чанк в отдельный файл и добавьте его в список вывода.Этот шаг — последний шанс изменить содержимое вывода.

  • 输出完成: После определения выходного содержимого определите выходной путь и имя файла в соответствии с конфигурацией и запишите содержимое файла в файловую систему.

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

просто скажи

  • Инициализация: запустите сборку, прочитайте и объедините параметры конфигурации, загрузите плагин, создайте экземпляр компилятора.

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

  • Вывод: объедините скомпилированные модули в чанки, преобразуйте чанки в файлы и выведите их в файловую систему.

Учащиеся, интересующиеся исходным кодом, могут перейти в другую мою колонку.Шпионить по принципу Webpack4.x из исходников

4. Что может повысить эффективность используемых вами подключаемых модулей при разработке веб-пакетов?

(Вопрос вполне практический, а пользовательский опыт все-таки нужно начинать с детства)

  • webpack-dashboard: он может отображать соответствующую информацию об упаковке более удобно.

  • webpack-merge: Извлечение общей конфигурации и сокращение повторяющегося кода конфигурации.

  • speed-measure-webpack-plugin: для краткости SMP анализирует время, отнимаемое загрузчиком и плагином в процессе упаковки Webpack, что помогает найти узкие места производительности в процессе сборки.

  • size-plugin: Отслеживайте изменения объема ресурсов, чтобы обнаруживать проблемы как можно раньше.

  • HotModuleReplacementPlugin: Горячая замена модуля

5. Что такое исходная карта? Как использовать производственную среду?

source mapЭто процесс сопоставления скомпилированного, упакованного и сжатого кода с исходным кодом. Упакованный и сжатый код не имеет хорошей читабельности.Если вы хотите отладить исходный код, вам нужна карта soucre.

Файл карты не будет загружен браузером, пока не открыты инструменты разработчика.

Обычно в онлайн-среде есть три решения для обработки:

  • hidden-source-map: Используйте с Sentry, сторонней платформой для мониторинга ошибок.

  • nosources-source-map: Будут отображаться только конкретный номер строки и стек ошибок для просмотра исходного кода. Безопаснее, чем исходная карта

  • sourcemap: открывать файл .map только в белый список через настройки nginx (внутренняя сеть компании)

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

6. Знаете ли вы принцип упаковки модулей?

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

7. Каков принцип мониторинга файлов?

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

Webpack открывает режим прослушивания, есть два способа:

  • При запуске команды webpack внесите параметр --watch
  • Установите watch:true в конфигурации webpack.config.js

Недостаток: каждый раз приходится вручную обновлять браузер

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

module.export = {
// 默认false,也就是不开启
watch: true,
// 只有开启监听模式时,watchOptions才有意义
watchOptions: {
// 默认为空,不监听的文件或者文件夹,支持正则匹配
ignored: /node_modules/,
// 监听到变化发生后会等300ms再去执行,默认300ms
aggregateTimeout:300,
// 判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的,默认每秒问1000次
poll:1000
}
}

8. Расскажите о принципе горячего обновления Webpack

(постучать по доске, этот вопрос надо проверить)

WebpackГорячее обновление также известно как горячая замена (Hot Module Replacement), сокращенноHMR. Этот механизм позволяет заменять старые модули новыми модулями без обновления браузера.

Суть HMR заключается в том, что клиент извлекает с сервера обновленный файл, который и представляет собой чанк diff (часть чанка, которую необходимо обновить) На самом деле файл поддерживается между WDS и браузером.Websocket, при изменении локального ресурса WDS отправит обновление в браузер и принесет хэш во время построения, чтобы клиент мог сравнить его с предыдущим ресурсом. После того, как клиент сравнит различия, он отправит сообщение в WDS.AjaxЗапрос на получение измененного содержимого (список файлов, хэш), чтобы клиент мог использовать эту информацию для продолжения запуска WDS.jsonpЗапрос на получение добавочных обновлений для этого фрагмента.

Последующая часть (как быть с инкрементными обновлениями после их получения? Какие состояния нужно сохранить? Какие нужно обновить?) состоит изHotModulePluginдля завершения, предоставляя соответствующие API-интерфейсы разработчикам для обработки их собственных сценариев, таких какreact-hot-loaderа такжеvue-loaderВсе эти API используются для реализации HMR.

Пожалуйста, обратитесь кПринципиальный анализ Webpack HMR

(Интервьюер: Неплохо, у молодого человека хорошие выразительные способности.)

(базовое упражнение, не 6)

9. Как контролировать и анализировать объем бандла?

VSCodeесть плагинImport CostЭто может помочь нам отслеживать размер импортируемого модуля в режиме реального времени, а также может использоватьwebpack-bundle-analyzerгенерироватьbundleСхема состава модуля, показывающая занимаемый объем.

bundlesizeИнструментарий обеспечивает автоматизированный мониторинг объема ресурсов.

10.文件指纹是什么? как использовать?

Отпечаток файла — это суффикс имени выходного файла после упаковки.

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

  • Chunkhash: что касается чанка, упакованного Webpack, разные записи будут генерировать разные хэши чанка.

  • Contenthash: определите хеш в соответствии с содержимым файла.Если содержимое файла не изменилось, хэш содержимого останется неизменным.

Настройки отпечатка файла JS

Установите имя выходного файла, используйте chunkhash.

module.exports = {
entry: {
app: './scr/app.js',
search: './src/search.js'
},
output: {
filename: '[name][chunkhash:8].js',
path:__dirname + '/dist'
}
}

Настройки снятия отпечатков файлов CSS

Установите имя файла MiniCssExtractPlugin и используйте contenthash.

module.exports = {
entry: {
app: './scr/app.js',
search: './src/search.js'
},
output: {
filename: '[name][chunkhash:8].js',
path:__dirname + '/dist'
},
plugins:[
new MiniCssExtractPlugin({
filename: `[name][contenthash:8].css`
})
]
}

Файл настроек отпечатков пальцев для изображений

Установите имя файла-загрузчика и используйте хэш.

Имена заполнителей и их значения

  • дополнительный суффикс ресурса
  • имя файла имя
  • path относительный путь к файлу
  • папка Папка, в которой находится файл
  • contenthash Хэш содержимого файла, который генерируется md5 по умолчанию.
  • Хэш содержимого хэш-файла, по умолчанию генерация md5
  • emoji Случайный emoji, относящийся к содержимому файла.
const path = require('path');

module.exports = {
entry: './src/index.js',
output: {
filename:'bundle.js',
path:path.resolve(__dirname, 'dist')
},
module:{
rules:[{
test:/\.(png|svg|jpg|gif)$/,
use:[{
loader:'file-loader',
options:{
name:'img/[name][hash:8].[ext]'
}
}]
}]
}
}

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

можно использоватьenforceобеспечивать соблюдениеloaderпорядок действий,preозначает выполнение перед всеми нормальными загрузчиками,postвыполняется после всех загрузчиков. (встроенный официально не рекомендуется)

12. Как оптимизировать скорость сборки Webpack?

(Этот вопрос похож на могу ли я говорить о"От ввода URL-адреса до страницы, показывающей, что произошло"Такой же)

(Я просто хочу сказать: как долго ты хочешь, чтобы я говорил?)

(Интервьюер:...)

  • использовать高版本Веб-пакет и Node.js

  • 多进程/多实例构建: HappyPack (не поддерживается), загрузчик потоков

  • 压缩代码

    • Многопроизводительный параллельный сжатие
      • webpack-paralle-uglify-plugin
      • uglifyjs-webpack-plugin включает параллельный параметр (ES6 не поддерживается)
      • terser-webpack-plugin открывает параллельный параметр
    • Извлеките код CSS из фрагмента в отдельный файл с помощью плагина mini-css-extract-plugin и включите cssnano для сжатия CSS с помощью опции минимизации css-loader.
  • 图片压缩

    • Используйте imagemin на основе библиотеки Node (множество параметров настройки, может обрабатывать несколько форматов изображений)
    • Настроить загрузчик изображений-webpack
  • 缩小打包作用域:

    • исключить/включить (определить область действия правил загрузчика)
    • resolve.modules указывает абсолютный путь к сторонним модулям (уменьшает ненужные поиски)
    • resolve.mainFields использует только основное поле в качестве поля описания файла ввода (уменьшает количество шагов поиска и требует учета полей описания файла ввода всех сторонних модулей, которые зависят от времени выполнения)
    • разрешить.extensions, чтобы свести к минимуму возможность попыток суффикса
    • noParse игнорирует библиотеки, которые вообще не нужно анализировать (не анализируются, но все равно будут упакованы в пакеты, обратите внимание, что игнорируемые файлы не должны содержать модульные операторы, такие как импорт, требование, определение)
    • IgnorePlugin (для полного исключения модулей)
    • добросовестное использование псевдонимов
  • 提取页面公共资源:

    • Базовое разделение пакетов:
      • Используйте html-webpack-externals-plugin для импорта базового пакета через CDN, а не в пакет.
      • Используйте SplitChunksPlugin для разделения (общие сценарии, базовые пакеты, общие файлы страниц) (встроенный Webpack4), заменяя плагин CommonsChunkPlugin.
  • DLL:

    • Используйте DllPlugin для подпакета и используйте DllReferencePlugin (ссылка на индекс) для ссылки на manifest.json, чтобы некоторый код, который не изменится, был сначала упакован в статические ресурсы, чтобы избежать повторной компиляции и пустой траты времени.
    • HashedModuleIdsPlugin может решить проблему идентификатора номера модуля
  • 充分利用缓存提升二次构建速度:

    • babel-loader включает кеширование
    • terser-webpack-plugin включает кеширование
    • Используйте cache-loader или hard-source-webpack-plugin
  • Tree shaking

    • Обнаружение и пометка неиспользуемых модулей в проекте во время процесса упаковки и удаление их из окончательного пакета при сжатии ресурсов (действительно только для ES6 Modlue) Максимально используйте модули модуля ES6 при разработке, чтобы повысить эффективность встряхивания дерева
    • Отключите синтаксический анализ зависимостей модулей для babel-loader, в противном случае все, что получает Webpack, являются преобразованными модулями CommonJS, которые не могут встряхивать дерево.
    • Используйте PurifyCSS (не поддерживается) или uncss для удаления бесполезного кода CSS.
      • Используйте плагин purgecss-webpack-plugin с плагином mini-css-extract-plugin (рекомендуется)
  • Scope hoisting

    • Построенный код будет иметь большое количество замыканий, что увеличит размер, создаст больше областей действия при выполнении кода и увеличит нагрузку на память. Подъем области действия помещает код всех модулей в область действия функции в порядке ссылки, а затем соответствующим образом переименовывает некоторые переменные, чтобы предотвратить конфликты имен переменных.
    • Это должен быть синтаксис ES6, потому что многие сторонние библиотеки все еще используют синтаксис CommonJS.Чтобы в полной мере использовать роль подъема Scope, необходимо настроить mainFields, чтобы отдать приоритет модульному синтаксису ES6, указанному в jsnext:main. для сторонних модулей.
  • 动态Polyfill

    • Рекомендуется использовать сервис полифиллов, чтобы возвращать пользователям только необходимые полифилы для обслуживания сообщества. (Некоторые отечественные экзотические браузеры UA могут не распознаваться, но их можно понизить, чтобы вернуться ко всем необходимым полифилам)

Дополнительные сведения об оптимизации см.Официальный веб-сайт — Повышение производительности

13. Вы только что упомянули о разделении кода, в чем суть разделения кода? В чем смысл?

Суть разделения кода на самом деле заключается в源代码直接上线а также打包成唯一脚本main.bundle.jsПромежуточное состояние между этими двумя крайними сценариями больше подходит для практических сценариев.

阿卡丽:荣耀剑下取,均衡乱中求

"Поменяйте приемлемое увеличение нагрузки на сервер на лучшее взаимодействие с пользователем."

Исходный код находится непосредственно в сети: хотя процесс управляем, существует много HTTP-запросов и высокая производительность.

Упаковано в уникальный скрипт: после шаттла круто, нагрузка на сервер небольшая, но период пустых страниц долгий, а пользовательский опыт не очень хороший.

(Easy peezy right)

14. Вы написали Loader? Кратко опишите идею написания загрузчика?

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

API загрузчикаВы можете перейти на официальный сайт, чтобы проверить

  • Загрузчик работает в Node.js, мы можем вызвать любой API, который поставляется с Node.js, или установить сторонние модули для вызова
  • Исходный контент, передаваемый Webpack загрузчику, представляет собой строку, закодированную в формате UTF-8.Когда загрузчик обрабатывает двоичные файлы в некоторых сценариях, необходимо сообщить Webpack, нужны ли загрузчику двоичные данные, через exports.raw = true
  • Максимально асинхронный загрузчик, если объем вычислений небольшой, синхронизацию тоже можно
  • Загрузчик не имеет состояния, мы не должны хранить состояние в загрузчике
  • Используйте утилиты, предоставляемые loader-utils и schema-utils
  • Загрузить метод локального загрузчика
    • Npm link
    • ResolveLoader

15. Вы написали плагин? Кратко опишите идею написания Plugin?

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

Плагин APIВы можете перейти на официальный сайт, чтобы проверить

  • Компилятор предоставляет хуки, связанные со всем жизненным циклом Webpack.
  • компиляция предоставляет более детализированные обработчики событий, связанные с модулями и зависимостями.
  • Плагины должны привязать метод применения к своему прототипу, чтобы получить доступ к экземпляру компилятора.
  • Объекты компилятора и компиляции, передаваемые каждому плагину, являются одной и той же ссылкой. Если вы измените их свойства в одном плагине, это повлияет на следующие плагины.
  • Найдите правильную точку события для выполнения желаемой функции
    • Когда происходит событие эммита, конечные выходные ресурсы, блоки кода, модули и их зависимости могут быть прочитаны и изменены (событие эммита — это последняя возможность изменить выходные ресурсы Webpack).
    • watch-run срабатывает при изменении зависимого файла
  • Асинхронные события должны вызывать функцию обратного вызова, когда плагин завершает обработку задачи, чтобы уведомить Webpack о переходе к следующему процессу, иначе он зависнет.

16. Давайте поговорим о принципе Бабеля

Большинство парсеров JavaScript следуетestreeспецификация, Вавилон изначально был основан наacornProject (легкий современный анализатор JavaScript) Вавилон условно делится на три части:

  • Разбор: преобразование кода в AST
    • Лексический анализ: разбить код (строку) на поток токенов, то есть массив грамматических единиц
    • Разбор: проанализируйте поток токенов (массив, сгенерированный выше) и сгенерируйте AST.
  • Преобразование: посетите узлы AST, чтобы выполнить операции преобразования для создания нового AST.
    • TaroЭто небольшое преобразование синтаксиса программы, выполненное Babel.
  • Генерировать: генерировать код на основе нового AST.

Студенты, которые хотят знать, как шаг за шагом реализовать компилятор, могут перейти к проектам с открытым исходным кодом, рекомендованным на официальном сайте Babel.the-super-tiny-compiler

Интервьюер: (Я хочу пить, давайте сделаем перерыв, и мы начнем вторую половину)

Интервьюер взял рядом с собой холодный «Лунцзин» и сделал глоток.

(У этого парня что-то есть)

"Постоянно обновляется……"

Ссылаться на

  • Углубленный веб-пакет

  • Вебпак в действии

  • Поэкспериментируйте с Webpack

❤️Любовное тройное комбо

1. Нажмите здесь, чтобы увидеть поддержку, вашу"смотреть в"Это то, что побуждает меня творить.

2. Подпишитесь на официальный аккаунт前端食堂,"Ваша передняя столовая, не забывайте есть вовремя"!

3. github.com/Geekhyt, спасибо Стар.