автор:JowayYoung
склад:Github,CodePen
Блог:Официальный сайт,Наггетс,думаю нет,Знай почти
Нет публики:Интерфейс IQ
Специальное: оригинал не просто, или скопирован без разрешения не должен быть воспроизведен, для перепечатки, пожалуйста, свяжитесь с автором авторизации
предисловие
Однажды опубликовал статью по оптимизации производительностиРуководство по оптимизации производительности внешнего интерфейса, автор обобщает некоторый опыт оптимизации производительности, использованный в процессе разработки проекта. Честно говоря, оптимизация производительности может быть полезна в процессе собеседования, ведь мало кто из студентов может обратить внимание на детали этой оптимизации производительности в процессе разработки проекта.
Если вы часто обращаете внимание на тему оптимизации производительности, то можете найти无论怎样对代码做最好的优化也不及对一张图片做一次压缩好
. Таким образом, сжатие изображений стало наиболее распространенной операцией при оптимизации производительности.Будь то ручное сжатие изображений или автоматическое сжатие изображений, оно должно выполняться в процессе разработки проекта.
Автоматическое сжатие изображения обычноwebpack
Доступ к некоторым третьим сторонам при создании проектаLoader&Plugin
обрабатывать. ОткрытьGithub
,поискwebpack image
Ожидание ключевых слов, Звезда не болееimage-webpack-loader
а такжеimagemin-webpack-plugin
эти двоеLoader&Plugin
. Многие студенты могут выбрать их, поскольку они удобны, быстры, просты в использовании и имеют простой доступ.
Однако эти дваLoader&Plugin
Есть некоторые особые проблемы, все они основаны наimagemin
развивающийся.imagemin
Некоторые зависимости размещены на внешних серверах, вnpm i xxx
Установите их по умолчаниюGitHub Releases
Если у вас нет стандартного доступа в Интернет, вы не сможете его установить, и даже если вы сможете стандартизировать доступ в Интернет, вы не сможете его установить. Поэтому автор опубликовал статью об обработке зеркал NPM.«Поговорим об опасных ямах зеркалирования NPM», специально для решения этих проблем, связанных с сбоем установки из-за сетевого окружения. Помимо этой проблемы с установкой,imagemin
Есть еще одна большая проблема, то есть потеря текстуры сжатия серьезно.Чем больше размер изображения, тем это более очевидно.Всегда есть несколько сжатых изображений, которые искажены, и общая степень сжатия не очень высока. Таким образом, когда проект будет сдан, его может поймать осторожная сестра QA, как это может быть четко не сравнимо с чертежом дизайна!
инструмент
инструмент сжатия изображений
В настоящее время некоторые учащиеся, возможно, перешли на ручное сжатие изображений. Простые в использовании инструменты сжатия изображений — это не что иное, как следующее: Если у вас есть инструмент получше, добавьте его в комментарии! В то же время автор также разобрал их различия для вашего ознакомления.
инструмент | Открытый исходный код | потери | API | Бесплатная пробная версия |
---|---|---|---|---|
QuickPicture | ✖️ | ✔️ | ✖️ | Есть много сжимаемых типов, текстура сжатия лучше, есть ограничения по объему, а есть ограничения по количеству |
ShrinkMe | ✖️ | ✖️ | ✖️ | Есть много сжимаемых типов, текстура сжатия общая, нет ограничения по количеству и есть ограничение по объему. |
Squoosh | ✔️ | ✖️ | ✔️ | Есть несколько сжимаемых типов, текстура сжатия общая, нет ограничения по количеству и есть ограничение по объему. |
TinyJpg | ✖️ | ✔️ | ✔️ | Типов сжимаемых мало, текстура сжатия очень хорошая, есть ограничения по количеству, есть ограничения по объему |
TinyPng | ✖️ | ✔️ | ✔️ | Типов сжимаемых мало, текстура сжатия очень хорошая, есть ограничения по количеству, есть ограничения по объему |
Zhitu | ✖️ | ✖️ | ✖️ | Сжимаемый тип является общим, текстура сжатия является общей, существуют ограничения по количеству и объему. |
Как видно из приведенного сравнения таблиц, свободный опыт будет существовать体积限制
, это и понятно, даже если заряд одинаков, ведь все заливают одну картинку больше 10 М, какой сервер это выдержит. тогда есть数量限制
,вы можете загружать только 20 изображений за раз.Кажется есть правило.Если качество сжатия хорошее,количество будет ограничено.В противном случае количество не будет ограничено.Конечно после зарядки ограничений не будет . тогда есть可压缩类型
, тип изображения обычноjpg
,png
,gif
,svg
а такжеwebp
,gif
Как правило, он будет искажен после сжатия.svg
Обычно используется на векторных иконках и редко используется на изображениях сцен,webp
Сжатие возможно из-за редко используемых проблем совместимостиjpg
а такжеpng
Будет достаточно. Конечно压缩质感
Это лучшее соображение. Таким образом, большинство студентов выберутTinyJpgа такжеTinyPng, по сути они братья, от одного производителя.
Было запущено простое голосование в группе обсуждения WeChat официального аккаунта автора, и, наконец,TinyJpgа такжеTinyPngпобедить.
Проблема с TinyJpg/TinyPng
- загружать и скачивать
手动
- только сжатый
jpg
а такжеpng
- сжимать только за один раз
20
открытым - Максимальный размер каждого листа не может превышать
5M
- Информация о визуальной обработке не является особенно полной
Принцип сжатия TinyJpg/TinyPng
TinyJpg/TinyPngИспользуйте интеллектуальную технологию сжатия с потерями, чтобы уменьшить размер изображения, выборочно уменьшить количество похожих цветов в изображении и сохранить данные всего несколькими байтами. Визуальное воздействие почти незаметно, но разница в размере файла большая. при использовании智能有损压缩技术
называетсяколичественно.
TinyJpg/TinyPngпри сжатииpng文件
эффект более выражен. Сканируйте изображения на наличие похожих цветов и комбинируйте их, уменьшая количество цветов.24位png文件
Преобразовать в меньший размер8位png文件
, отбрасывая все ненужные метаданные.
наиболееpng文件
имеют50%~70%
Степень сжатия трудно различить даже при хорошем зрении. Использование оптимизированных изображений снижает нагрузку на полосу пропускания и время загрузки, а изображения, используемые на сайте,TinyJpg/TinyPngСжав его один раз, эффект заключается в том, что никакая оптимизация кода не может наверстать упущенное.
API разработки TinyJpg/TinyPng
Ознакомьтесь с соответствующей информацией и найдитеTinyJpg/TinyPngЕго алгоритм сжатия еще не открыт, но предоставляется API, подходящий для разработчиков. Заинтересованные студенты могут перейти кРазрабатывать документацию по APIПроверьте это.
существуетNode
аспект,TinyJpg/TinyPngофициально предоставленtinifyЯвляясь основной библиотекой JS для сжатия изображений, она очень проста в использовании, см.ДокументацияБар. Однако, если вы перейдете на API разработки, вы все равно не сможете избежать платы. Хотите ежемесячную подписку или бесплатно? Если вы хотите быть свободным, продолжайте смотреть вниз, местные тираны свободны!
выполнить
я тоже часто пользуюсьTinyJpg/TinyPngПрограммист не может брать плату. Поиск прорывов и решение проблем — самые основные качества программиста.我们需明确什么问题,需解决什么问题
.
анализировать
Из вышеизложенного необходимо толькоTinyJpg/TinyPngИсходная функция была преобразована в следующие функции.
- Автоматическая загрузка и загрузка
- сжимаемый
jpg
а такжеpng
- без ограничений по количеству
- Существует ограничение громкости, максимальная громкость не может превышать
5M
- Успешное сжатие или не вывод подробной информации
автоматическая обработка
Для фронтенд-разработчиков эта безмозглая операция загрузки и выгрузки должна быть автоматизирована, что избавит от проблем и усилий. Но эту операцию надо совмещатьwebpack
иметь дело, в конце концов превращается вLoader
ещеPlugin
, который будет проанализирован позже. Однако внимательные учащиеся узнают, как с этим справиться, прочитав заголовок.
Тип сжатия
gif
Как правило, он будет искажен после сжатия.svg
Обычно используется на векторных иконках и редко используется на изображениях сцен,webp
Сжатие возможно из-за редко используемых проблем совместимостиjpg
а такжеpng
Будет достаточно. При фильтрации изображений используйтеpath模块
Определите, является ли тип файлаjpg
а такжеpng
, если да, продолжить обработку, иначе не обрабатывать.
Количественные ограничения
Конечно, ограничения по количеству быть не может.Если в проекте более 20 картинок, то это не пакетный пакетный процесс.Такого быть не может. Для такого веб-сайта, который может обрабатывать некоторые пользовательские файлы без входа в систему, количество пользовательских операций обычно ограничивается IP. Некоторые студенты могут сказать, что достаточно обновить страницу, сжать каждый раз 20 картинок, обновить и снова сжать, если есть 500 картинок, вы обновляете 25 раз, это очень весело, правда!
Поскольку большинство веб-архитектур редко предоставляют серверы приложений напрямую внешнему миру, обычно настраивается слой.Nginx
В качестве прокси-серверов и балансировщиков нагрузки некоторые из них могут даже иметь несколько уровней прокси-серверов. Учитывая, что большинство веб-архитектур используютNginx
В качестве обратного прокси-сервера пользовательский запрос не запрашивает напрямую сервер приложений, а перенаправляет пользовательский запрос на сервер через унифицированный уровень доступа, установленный Nginx, поэтому его можно установить, задав поле заголовка HTTP-запроса.X-Forwarded-For
для подделки IP.
X-Forwarded-Forсредство, используемое для идентификации代理
или负载均衡
Поле заголовка HTTP-запроса самого исходного IP-адреса клиента при подключении к веб-серверу. Конечно, этот IP не является статическим, и каждый запрос должен менять IP случайным образом, обманывая сервер приложений. Если сервер приложений добавляет фальшивую идентификацию IP, возможно, он не сможет продолжать использовать случайные IP-адреса.
ограничение громкости
Ограничение объема понятно, и нет необходимости создавать такой большой образ, который тратит впустую пропускную способность, трафик и время загрузки. При загрузке изображения используйтеfs模块
Определить, превышает ли размер файла5M
, если да, не загружать, иначе продолжить загрузку. Конечно, чтобыTinyJpg/TinyPngОценка интерфейса также работает.
выходная информация
Сообщите другим, было ли сжатие успешным или нет, выведите исходный размер, сжатый размер, степень сжатия и сообщения об ошибках и т. д., чтобы другие могли понять информацию об обработке.
кодирование
Благодаря приведенному выше анализу мы начнем кодирование.
Произвольно генерировать заголовки HTTP-запросов
Так как можно пройтиX-Forwarded-For
Чтобы подделать IP, должна быть функция, которая случайным образом генерирует поля заголовка HTTP-запроса, а соответствующие поля заголовка запроса генерируются случайным образом каждый раз, когда запрашивается интерфейс. Открытьtinyjpg.comилиtinypng.comзагрузить изображение черезChrome DevTools
анализироватьNetwork
Обнаружено, что его интерфейс запросаweb/shrink
. Кроме того, каждый запрос не должен концентрироваться на одномhostname
, распределяется случайным образом поtinyjpg.com
илиtinypng.com
будет лучше. путем инкапсуляцииRandomHeader
Функция случайным образом генерирует информацию заголовка запроса для последующего использования.https模块
кRandomHeader()
Сгенерированная конфигурация запрашивается в качестве входного параметра.
trample
разрабатывается авторомWeb/Node
Библиотека инструментов общих функций, включая общие функции инструментов, помогает писать менее общий код. Для получения подробной информации, пожалуйста, проверьтеДокументация, кстати Звезде за поощрение.
const { RandomNum } = require("trample/node");
const TINYIMG_URL = [
"tinyjpg.com",
"tinypng.com"
];
function RandomHeader() {
const ip = new Array(4).fill(0).map(() => parseInt(Math.random() * 255)).join(".");
const index = RandomNum(0, 1);
return {
headers: {
"Cache-Control": "no-cache",
"Content-Type": "application/x-www-form-urlencoded",
"Postman-Token": Date.now(),
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
"X-Forwarded-For": ip
},
hostname: TINYIMG_URL[index],
method: "POST",
path: "/web/shrink",
rejectUnauthorized: false
};
}
Загружать и скачивать изображения
использоватьPromise
упаковка上传图片
а также下载图片
функция, которая удобна для последующего использованияAsync/Await
Синхронизируйте асинхронный код. Отладка конкретных точек останова следующих функций обсуждаться не будет.Заинтересованные студенты могут самостоятельно отлаживать входные и выходные параметры функции!
const Https = require("https");
const Url = require("url");
function UploadImg(file) {
const opts = RandomHeader();
return new Promise((resolve, reject) => {
const req = Https.request(opts, res => res.on("data", data => {
const obj = JSON.parse(data.toString());
obj.error ? reject(obj.message) : resolve(obj);
}));
req.write(file, "binary");
req.on("error", e => reject(e));
req.end();
});
}
function DownloadImg(url) {
const opts = new Url.URL(url);
return new Promise((resolve, reject) => {
const req = Https.request(opts, res => {
let file = "";
res.setEncoding("binary");
res.on("data", chunk => file += chunk);
res.on("end", () => resolve(file));
});
req.on("error", e => reject(e));
req.end();
});
}
Сжать изображение
пройти через上传图片
Функция получает информацию о сжатом изображении, а затем передает下载图片
Функция генерирует локальные файлы.
const Fs = require("fs");
const Path = require("path");
const Chalk = require("chalk");
const Figures = require("figures");
const { ByteSize, RoundNum } = require("trample/node");
async function CompressImg(path) {
try {
const file = Fs.readFileSync(path, "binary");
const obj = await UploadImg(file);
const data = await DownloadImg(obj.output.url);
const oldSize = Chalk.redBright(ByteSize(obj.input.size));
const newSize = Chalk.greenBright(ByteSize(obj.output.size));
const ratio = Chalk.blueBright(RoundNum(1 - obj.output.ratio, 2, true));
const dpath = Path.join("img", Path.basename(path));
const msg = `${Figures.tick} Compressed [${Chalk.yellowBright(path)}] completed: Old Size ${oldSize}, New Size ${newSize}, Optimization Ratio ${ratio}`;
Fs.writeFileSync(dpath, data, "binary");
return Promise.resolve(msg);
} catch (err) {
const msg = `${Figures.cross} Compressed [${Chalk.yellowBright(path)}] failed: ${Chalk.redBright(err)}`;
return Promise.resolve(msg);
}
}
Сжать целевое изображение
После выполнения функций, соответствующих вышеперечисленным шагам, вы можете свободно сжимать изображения.Следующее использует изображение в качестве демонстрации.
const Ora = require("ora");
(async() => {
const spinner = Ora("Image is compressing......").start();
const res = await CompressImg("src/pig.png");
spinner.stop();
console.log(res);
})();
Видите ли, после сжатия глупые свиньи стали красивыми свинками, а свиньи с электрическими глазами — хорошие свиньи. Пожалуйста, проверьте исходный кодcompress-img.
Если вы сжимаете все изображения, соответствующие условиям в указанной папке, вы можете использоватьfs模块
получить изображение и использоватьmap()
Сопоставьте путь к одному изображению какCompressImg(path)
, затем пройтиPromise.all()
Просто сделай это. Я не буду публиковать код здесь, просто примите это как мысленный вопрос и завершите его самостоятельно.
Вышеупомянутая функция сжатия изображений заключена вLoader
ещеPlugin
Шерстяная ткань? Далее будет пошаговый анализ.
Loader&Plugin
webpack
Это интерфейсный инструмент упаковки ресурсов, который выполняет статический анализ на основе зависимостей модулей, а затем генерирует соответствующие статические ресурсы из этих модулей в соответствии с заданными правилами.
много онлайнwebpack
В туториале автор больше не будет тратить много времени и болтать.Я считаю,что все студенты стандартWebpack配置工程师
. Краткий обзор следующегоwebpack
композиция, строительный механизм и строительный процесс, я полагаю, что также могут быть расположены из этих точек знанияLoader
а такжеPlugin
существуетWebpack构建流程
В какой он роли?
本文所说的webpack都是基于webpack v4
сочинение
- Entry:Вход
- Output: выход
- Loader:конвертер
- Plugin: Расширитель
- Mode:модель
- Module: модуль
- Target:Цель
механизм сборки
- Преобразование кода с помощью Babel и создание зависимостей в одном файле
- Запустите рекурсивный анализ из входного файла и сгенерируйте граф зависимостей
- Упакуйте каждый упомянутый модуль в немедленно выполняемую функцию
- Запишите окончательный файл пакета в
bundle.js
середина
Процесс сборки
-
исходный
-
初始参数
: объединить аргументы командной строки и файла конфигурации.
-
-
компилировать
-
执行编译
: инициализируется в соответствии с параметрамиCompiler对象
, загрузить всеPlugin
,воплощать в жизньrun()
-
确定入口
: найти все входные файлы в соответствии с файлом конфигурации -
编译模块
: найти все отношения зависимых модулей в соответствии с файлом ввода, вызвать всеLoader
для преобразования -
生成图谱
: получить преобразованное содержимое каждого модуля и его зависимостей.
-
-
выход
-
输出资源
: Собрать модули в блоки, а затем в пакеты в соответствии с зависимостями (module → chunk → bundle
) -
生成文件
: Записать содержимое вывода подтверждения в файловую систему в соответствии с файлом конфигурации.
-
Loader
LoaderИспользуется для преобразования исходного кода модуля, автор переводит его как转换器
.Loader
Преобразование всех типов файлов вwebpack
Действительный модуль, способный обрабатывать, а затем использоватьwebpack
Упаковочные возможности их перерабатываются во второй раз.
Loader
Имеет следующие характеристики:
- Принцип единой ответственности (
只完成一种转换
) - Конвертировать полученный контент
- вернуть результат преобразования
- Поддержка связанных вызовов
Loader
Преобразуйте все типы файлов в модули, на которые может напрямую ссылаться граф зависимостей приложения, поэтомуLoader
Может использоваться для компиляции некоторых файлов, таких какpug → html
,sass → css
,less → css
,es5 → es6
,ts → js
Ждать.
Обработка файла может использовать несколькоLoader
,Loader
Порядок выполнения и порядок конфигурации меняются местами, то есть конецLoader
Сначала выполнить, начатьLoader
Наконец выполнить. первый казненныйLoader
Получить содержимое исходного файла в качестве параметра, другиеLoader
получить предыдущее исполнениеLoader
Возвращаемое значение используется как параметр, а последнее выполненноеLoader
Будет возвращен результат преобразования файла. Вкратце в одном предложении:Работник сборочной линии Futu Kang.
Loader
Идеи развития сводятся к следующему:
- пройти через
module.exports
экспортировать один函数
- Первый параметр по умолчанию функции
source
(содержимое исходного файла) - Ресурсы процесса в теле функции (можно ввести функцию расширения стороннего модуля)
- пройти через
return
Возвращает окончательный результат преобразования (в виде строки)
编写Loader时要遵循单一职责原则,每个Loader只做一种转换工作
Plugin
PluginИспользуется для расширения для выполнения более широкого круга задач, автор переводит как扩展器
.Plugin
широкий ассортимент, вWebpack构建流程
Вы можете найти время в качестве точки вставки от начала до конца, пока вы не можете думать об этом, вы не можете этого сделать. Так что я думаю, чтоPlugin
коэффициент функцииLoader
более могущественный.
Plugin
Имеет следующие характеристики:
- монитор
webpack
События, транслируемые в жизненном цикле среды выполнения - проходить в нужное время
webpack
Предоставленный API для изменения результата вывода -
webpack
Механизм потока событий Tapable обеспечивает упорядоченность плагинов.
существуетwebpack
Многие события транслируются в течение жизненного цикла среды выполнения.Plugin
Вы можете слушать эти события и передавать их в нужное времяwebpack
Предоставленный API изменяет результат вывода. существуетwebpack
После запуска выполнить во время чтения конфигурацииnew MyPlugin(opts)
инициализация自定义Plugin
Получить его экземпляр при инициализацииCompiler对象
После этого черезcompiler.hooks.event.tap(PLUGIN_NAME, callback)
мониторwebpack
Широковещательные события, когда указанное событие будет перехвачено, оно пройдетCompilation对象
Управляйте связанной бизнес-логикой. Вкратце в одном предложении:посмотреть на себя.
Plugin
Идеи развития сводятся к следующему:
- пройти через
module.exports
экспортировать один函数或类
- существует
函数原型或类
привязатьapply()
доступCompiler对象
- существует
apply()
указывает привязку кwebpack
собственный хук событий - в хуке событий через
webpack
Предоставленные ресурсы обработки API (могут быть введены функции расширения сторонних модулей) - пройти через
webpack
Предоставленный метод возвращает этот ресурс
传给每个Plugin的Compiler和Compilation都是同一个引用,若修改它们身上的属性会影响后面的Plugin,所以需谨慎操作
Разница между загрузчиком и плагином
- Природа
-
Loader
Суть в функции, которая конвертирует полученный контент и возвращает результат конвертации -
Plugin
По сути, класс, который слушаетwebpack
Запускать события, транслируемые в жизненном цикле, и проходить в нужное времяwebpack
Предоставленный API для изменения результата вывода
-
- настроить
-
Loader
существуетmodule.rule
Средняя конфигурация, тип — массив, и каждому элементу соответствует правило разбора модуля. -
Plugin
существуетplugin
конфигурация, тип — массив, каждый элемент соответствует экземпляру расширителя, а параметры передаются через конструктор
-
упаковка
анализировать
Из вышеизложенного видно, чтоLoader
а такжеPlugin
Различий в позиционировании ролей и механизме исполнения много, как выбрать? У каждого есть свои достоинства, конечно, его еще нужно проанализировать и выбрать.
Loader
существуетwebpack
Он играет роль преобразователя в модуле, который используется для преобразования исходного кода модуля.Простое понимание состоит в том, чтобы преобразовать файл в другую форму файла, и тема этой статьи压缩图片
,jpg
Еще после сжатияjpg
,png
Еще после сжатияpng
, по-прежнему нет изменений в типах файлов.Loader
Процесс конвертации прилагается повсюдуWebpack构建流程
, что означает, что время упаковки включает в себя затраты времени на сжатие изображения.webpack
Что касается оптимизации производительности, то это немного противоречит принципу. а такжеPlugin
случается, слушаетwebpack
Запускать события, транслируемые в жизненном цикле, и проходить в нужное времяwebpack
Предоставленный API изменяет вывод, поэтому его можно использовать повсюду.Webpack构建流程
Операция вставки сжатых картинок после завершения (после вывода всех упакованных файлов). Другими словами, время упаковки больше не включает временные затраты на сжатие картинок.После завершения упаковки вы можете делать то, что можете, и что еще можете делать, сжимать картинки.
Поэтому, в зависимости от потребностей,Plugin
как первый выбор.
кодирование
Согласно вышеизложенномуPlugin
Развивайте идеи, а затем начинайте программировать.
Автор поместил это сжатое изображениеPlugin
по имениtinyimg-webpack-plugin,tinyimg
иметь в видуTinyJpgа такжеTinyPngкомбинированный.
Создайте новый проект со следующей структурой каталогов.
tinyimg-webpack-plugin
├─ src
│ ├─ index.js
│ ├─ schema.json
├─ util
│ ├─ getting.js
│ ├─ setting.js
├─ .gitignore
├─ .npmignore
├─ license
├─ package.json
├─ readme.md
Основные файлы следующие.
-
src
- index.js: функция входа
- schema.json: проверка параметров
-
util
- get.js: постоянная коллекция
- settings.js: коллекция функций
Установите необходимые модули для проекта, и вышеcompress-imgЗависимости согласованы, дополнительная установкаschema-utils
для подтвержденияPlugin
Соответствуют ли параметры требованиям.
npm i chalk figures ora schema-utils trample
Инкапсулирует наборы констант и функций
поставить вышеcompress-img
изTINYIMG_URL
а такжеRandomHeader()
Инкапсулирован в набор инструментов, где постоянный набор увеличиваетсяIMG_REGEXP
а такжеPLUGIN_NAME
две константы.
// getting.js
const IMG_REGEXP = /\.(jpe?g|png)$/;
const PLUGIN_NAME = "tinyimg-webpack-plugin";
const TINYIMG_URL = [
"tinyjpg.com",
"tinypng.com"
];
module.exports = {
IMG_REGEXP,
PLUGIN_NAME,
TINYIMG_URL
};
// setting.js
const { RandomNum } = require("trample/node");
const { TINYIMG_URL } = require("./getting");
function RandomHeader() {
const ip = new Array(4).fill(0).map(() => parseInt(Math.random() * 255)).join(".");
const index = RandomNum(0, 1);
return {
headers: {
"Cache-Control": "no-cache",
"Content-Type": "application/x-www-form-urlencoded",
"Postman-Token": Date.now(),
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
"X-Forwarded-For": ip
},
hostname: TINYIMG_URL[index],
method: "POST",
path: "/web/shrink",
rejectUnauthorized: false
};
}
module.exports = {
RandomHeader
};
пройти через
module.exports
Экспорт функции или класса
// index.js
module.exports = class TinyimgWebpackPlugin {};
существует
函数原型或类
привязатьapply()
доступCompiler对象
// index.js
module.exports = class TinyimgWebpackPlugin {
apply(compiler) {
// Do Something
}
};
существует
apply()
указывает привязку кwebpack
собственный хук событий
Из вышеприведенного анализа видно, что операция вставки сжатых картинок после вывода всех упакованных файлов, поэтому следует выбрать обработчик событий, соответствующий этому таймингу. отДокументация API хуков компилятора Webpackможно найти в,emit
именно этоPlugin
Обязательные обработчики событий.emit
существуетВыполнить перед генерацией ресурсов в выходной каталог, теперь можно получить данные и пути вывода всех файлов изображений.
Для удобства при определенных условиях启用功能
а также打印日志
, поэтому установите соответствующую конфигурацию.
- enabled: включить ли функцию
- logged: распечатывать ли журнал
существуетapply()
Бизнес-логика, связанная с процессами, вPlugin
входные параметры, то параметры должны быть проверены. определитьPlugin
изSchema
,пройти черезschema-utils
проверитьPlugin
ввод.
// schema.json
{
"type": "object",
"properties": {
"enabled": {
"description": "start plugin",
"type": "boolean"
},
"logged": {
"description": "print log",
"type": "boolean"
}
},
"additionalProperties": false
}
// index.js
const SchemaUtils = require("schema-utils");
const { PLUGIN_NAME } = require("../util/getting");
const Schema = require("./schema");
module.exports = class TinyimgWebpackPlugin {
constructor(opts) {
this.opts = opts;
}
apply(compiler) {
const { enabled } = this.opts;
SchemaUtils(Schema, this.opts, { name: PLUGIN_NAME });
enabled && compiler.hooks.emit.tap(PLUGIN_NAME, compilation => {
// Do Something
});
}
};
Интегрировать
compress-img
прибытьPlugin
В процессе интеграции будут внесены незначительные изменения, и вы сможете сравнить и посмотреть, какие детали изменились.
// index.js
const Fs = require("fs");
const Https = require("https");
const Url = require("url");
const Chalk = require("chalk");
const Figures = require("figures");
const { ByteSize, RoundNum } = require("trample/node");
const { RandomHeader } = require("../util/setting");
module.exports = class TinyimgWebpackPlugin {
constructor(opts) { ... }
apply(compiler) { ... }
async compressImg(assets, path) {
try {
const file = assets[path].source();
const obj = await this.uploadImg(file);
const data = await this.downloadImg(obj.output.url);
const oldSize = Chalk.redBright(ByteSize(obj.input.size));
const newSize = Chalk.greenBright(ByteSize(obj.output.size));
const ratio = Chalk.blueBright(RoundNum(1 - obj.output.ratio, 2, true));
const dpath = assets[path].existsAt;
const msg = `${Figures.tick} Compressed [${Chalk.yellowBright(path)}] completed: Old Size ${oldSize}, New Size ${newSize}, Optimization Ratio ${ratio}`;
Fs.writeFileSync(dpath, data, "binary");
return Promise.resolve(msg);
} catch (err) {
const msg = `${Figures.cross} Compressed [${Chalk.yellowBright(path)}] failed: ${Chalk.redBright(err)}`;
return Promise.resolve(msg);
}
}
downloadImg(url) {
const opts = new Url.URL(url);
return new Promise((resolve, reject) => {
const req = Https.request(opts, res => {
let file = "";
res.setEncoding("binary");
res.on("data", chunk => file += chunk);
res.on("end", () => resolve(file));
});
req.on("error", e => reject(e));
req.end();
});
}
uploadImg(file) {
const opts = RandomHeader();
return new Promise((resolve, reject) => {
const req = Https.request(opts, res => res.on("data", data => {
const obj = JSON.parse(data.toString());
obj.error ? reject(obj.message) : resolve(obj);
}));
req.write(file, "binary");
req.on("error", e => reject(e));
req.end();
});
}
};
в хуке событий через
webpack
Предоставляемые ресурсы обработки API
пройти черезcompilation.assets
Получить объекты всех упакованных файлов, отфильтроватьjpg
а такжеpng
,использоватьmap()
Сопоставьте данные одного изображения какthis.compressImg(file)
, затем пройтиPromise.all()
Просто сделай это.
Вся бизнес-логика объединяетPromise
а такжеAsync/Await
Две общие фичи ES6, с ними крайне интересно играть в асинхронное программирование вместе, подробнее о них можно прочитать в статье автора4000 лайкова также140 000 просмотровстатья«15 000 слов, описывающих все возможности ES6».
// index.js
const Ora = require("ora");
const SchemaUtils = require("schema-utils");
const { IMG_REGEXP, PLUGIN_NAME } = require("../util/getting");
const Schema = require("./schema");
module.exports = class TinyimgWebpackPlugin {
constructor(opts) { ... }
apply(compiler) {
const { enabled, logged } = this.opts;
SchemaUtils(Schema, this.opts, { name: PLUGIN_NAME });
enabled && compiler.hooks.emit.tap(PLUGIN_NAME, compilation => {
const imgs = Object.keys(compilation.assets).filter(v => IMG_REGEXP.test(v));
if (!imgs.length) return Promise.resolve();
const promises = imgs.map(v => this.compressImg(compilation.assets, v));
const spinner = Ora("Image is compressing......").start();
return Promise.all(promises).then(res => {
spinner.stop();
logged && res.forEach(v => console.log(v));
});
});
}
async compressImg(assets, path) { ... }
downloadImg(url) { ... }
uploadImg(file) { ... }
};
пройти через
webpack
Предоставленный метод возвращает этот ресурс
Поскольку операция сжатия изображений выполняется в целомWebpack构建流程
После завершения так возвращать нечего, поэтому и не обрабатывается.
контроль
webpack
Версия зависимости
из-заtinyimg-webpack-plugin
на основеwebpack v4
, так и должно бытьpackage.json
добавлено вpeerDependencies
, используемый для сообщения установке, чтоPlugin
Модуль должен существоватьpeerDependencies
зависимости в.
{
"peerDependencies": {
"webpack": ">= 4.0.0",
"webpack-cli": ">= 3.0.0"
}
}
Суммировать
На самом деле довольно просто выполнить кодирование шаг за шагом в соответствии с идеями разработки, изложенными выше. Если вам нужно разработать что-то, связанное с вашим собственным проектомPlugin
, надо еще ознакомитьсяДокументация API хуков компилятора Webpack, я считаю, что все учащиеся могут сделать идеальноеPlugin
публично заявить.
tinyimg-webpack-plugin
Пожалуйста, нажмите на исходный кодздесьПроверить,StarКак насчет одного, хи-хи.
тестовое задание
весьPlugin
Разработка завершена, а затем нам нужно пройти процесс тестирования, чтобы увидеть, сможем ли мы поставить это压缩图片的扩展器
пробежать. Я считаю, что все студенты соответствуют стандартуWebpack配置工程师
, вы можете написать собственную тестовую демонстрацию, чтобы проверитьPlugin
.
Создать в корневом каталогеtest文件夹
и добавьте файлы в соответствии со следующей структурой каталогов.
tinyimg-webpack-plugin
├─ test
│ ├─ src
│ │ ├─ img
│ │ │ ├─ favicon.ico
│ │ │ ├─ gz.jpg
│ │ │ ├─ pig-1.jpg
│ │ │ ├─ pig-2.jpg
│ │ │ ├─ pig-3.jpg
│ │ ├─ index.html
│ │ ├─ index.js
│ │ ├─ index.scss
│ │ ├─ reset.css
│ └─ webpack.config.js
Установите и протестируйте демо-версиюwebpack
соответствующие модули конфигурации.
npm i -D @babel/core @babel/preset-env babel-loader clean-webpack-plugin css-loader file-loader html-webpack-plugin mini-css-extract-plugin node-sass sass sass-loader style-loader url-loader webpack webpack-cli webpackbar
После завершения установки приступайте к улучшениюwebpack.config.js
Код, количество кода немного велико, просто вставьте ссылку напрямую, пожалуйста, ткнитездесь.
Наконец вpackage.json
серединаscripts
вставить следующееnpm scripts
, затем выполнитеnpm run test
Отладьте и протестируйте демо.
{
"scripts": {
"test": "webpack --config test/webpack.config.js"
}
}
выпускать
Опубликовать вNPM仓库
Это очень просто, всего несколько строк команд. Если вы еще не зарегистрированы, перейдите наNPM
Зарегистрируйте аккаунт. Если текущее изображение淘宝镜像
, нужно выполнитьnpm config set registry https://registry.npmjs.org/
Вернитесь к исходному зеркалу.
Следующая волна операций может завершить выпуск.
- Войдите в каталог:
cd my-plugin
- Вход в учетную запись:
npm login
- Проверь состояние:
npm whoami
- Опубликовать модуль:
npm publish
- Выйти из аккаунта:
npm logout
Если вы не хотите запоминать такое количество команд, вы можете использовать разработанную авторомpkg-master
Публикация в один клик. Если есть какие-то ошибки, публикация будет немедленно прервана, и будет отображаться сообщение об ошибке. Это очень простой в использовании инструмент управления модулями NPM, который объединяет создание и публикацию. Для получения подробной информации, пожалуйста, проверьтеДокументация, кстати Звезде за поощрение.
Установить
npm i -g pkg-master
использовать
Заказ | Сокращенное название | Функция | описывать |
---|---|---|---|
pkg-master create |
pkg-master c |
Создать модуль | модуль сборки基础文件
|
pkg-master publish |
pkg-master p |
опубликовать модуль | обнаружить нпм运行环境 а также账号状态 , модуль автоматически освобождается при передаче |
доступ
Установить
npm i tinyimg-webpack-plugin
использовать
настроить | Функция | Формат | описывать |
---|---|---|---|
enabled |
Включить ли функцию | true/false |
Рекомендуется включать только в производственной среде |
logged |
распечатывать ли журнал | true/false |
распечатать информацию об обработке |
существуетwebpack.config.js
илиwebpack配置
Вставьте следующий код.
Использование в CommonJS
const TinyimgPlugin = require("tinyimg-webpack-plugin");
module.exports = {
plugins: [
new TinyimgPlugin({
enabled: process.env.NODE_ENV === "production",
logged: true
})
]
};
Использование в ЕСМ
Должен бытьbabel
Используется в среде Node по благословению
import TinyimgPlugin from "tinyimg-webpack-plugin";
export default {
plugins: [
new TinyimgPlugin({
enabled: process.env.NODE_ENV === "production",
logged: true
})
]
};
Рекомендовать готовый каркас сборки React/Vue для автоматизации приложений с нулевой конфигурацией.
bruce-cli
ЯвляетсяReact/VueАвтоматизация приложений для создания строительных лесов, его преимущество в нулевой конфигурации «из коробки» очень подходит для студентов начального уровня, младших-средних и передовых студентов проектов быстрой разработки.Его также можно использовать при созданииbrucerc.js
файл, чтобы переопределить его конфигурацию по умолчанию, вам нужно сосредоточиться только на написании бизнес-кода, не обращая внимания на написание кода сборки, что делает структуру проекта более лаконичной. Не забудьте проверить документацию при его использовании и поставить звезду, если вам это нравится.
Конечно, у автораtinyimg-webpack-plugin
Р Гbruce-cli
, с нулевой конфигурацией из коробки.
- Адрес Github: пожалуйста, отметьтездесь
- Официальный документ веб-сайта: пожалуйста, нажмитездесь
- Документация по самородкам: пожалуйста, отметьтездесь
Суммировать
В общем, разработайтеWebpack Plugin
Это не сложно, просто хорошо проанализируйте потребности и поймитеwebpack
Чтобы запускать события, транслируемые в жизненном цикле, напишите自定义Plugin
проходить в нужное времяwebpack
Предоставленный API изменяет результат вывода.
Если ты чувствуешьtinyimg-webpack-plugin
чтобы помочь вам, доступны по адресуIssueначальство提出你的宝贵建议
, автор внимательно прочитает и объединит ваши предложения. подобноtinyimg-webpack-plugin
пожалуйста, дайте одинStar,илиForkэтот проект для себяGithub
и настроить функции в соответствии с вашими потребностями.
Эпилог
❤️Подписаться + Нравится + Избранное + Комментарий + Переслать ❤️, оригинальность это не просто, поощряйте автора к созданию более качественных статей
Обратите внимание на общедоступный номерIQ前端
, внешний общедоступный аккаунт, ориентированный на навыки разработки CSS / JS, вас ждут другие галантереи переднего плана
- Ответить после подписки
资料
Получите бесплатные учебные материалы - Ответить после подписки
进群
Втяните вас в группу технического обмена - Добро пожаловать, чтобы следовать
IQ前端
,БолееНавыки разработки на CSS/JSНажимайте только на публичный аккаунт