Что такое загрузчик
в вебпакеloader
Это очень важная концепция, загрузчик можно просто понимать как файловый процессор, веб-пакет используетloader
для обработки различных типов файлов, таких как.scss
превратиться вcss
файлы, небольшие изображения преобразуются в изображения base64.
По сути,loader
Это просто модуль JavaScript, экспортированный как функция. Когда веб-пакет упаковывается, он вызывает эту функцию и передает результат или файл ресурсов, сгенерированный предыдущим загрузчиком.
На этот раз я собираюсь разработать программу, которая преобразует обычные изображения в.webp
Загрузчик форматов для достижения цели уменьшения размера изображения.
Библиотека инструментов загрузчика
Прежде чем разрабатывать загрузчик, вы должны сначала разобраться с двумя инструментами разработки загрузчика:loader-utils
а такжеschema-utils
-
loader-utils
Используется для получения загрузчикаoptions
. -
schema-utils
используется для проверки загрузчикаoptions
а такжеJSON Schema
Является ли определение структуры непротиворечивым.
import { getOptions } from 'loader-utils';
import { validateOptions } from 'schema-utils';
const schema = {
// ...
}
export default function(source) {
// 获取 options
const options = getOptions(this);
// 检验loader的options是否合法
validateOptions(schema, options, 'Demo Loader');
// 在这里写转换 loader 的逻辑
// ...
};
Руководство по разработке загрузчика
- Единая ответственность: загрузчик обрабатывает только одну задачу, что обеспечивает простоту и удобство сопровождения, а сложные сценарии можно выполнять, комбинируя несколько загрузчиков.
- Модульность: Убедитесь, что загрузчик является модульным. Модуль, сгенерированный загрузчиком, должен следовать тем же принципам проектирования, что и обычные модули.
- Без сохранения состояния: мы не должны сохранять состояние в загрузчике между несколькими переходами модуля. Каждая среда выполнения загрузчика должна обеспечивать независимость от других скомпилированных модулей, а также должна быть независима от результатов компиляции того же модуля, скомпилированного предыдущими загрузчиками.
Одним словом, когда мы пишем загрузчик, мы ограничиваем его обязанности и заботимся только о вводе и выводе.
Синхронные и асинхронные загрузчики
Причина, по которой загрузчик разделен на синхронный и асинхронный, заключается в том, что обработка некоторых ресурсов занимает много времени и требует обработки асинхронно, а затем продолжить выполнение после ожидания завершения обработки. для погрузчикаthis.callback()
Вернуть результат обработки следующим образом:
this.callback(
err: Error | null,
content: string | Buffer,
sourceMap?: SourceMap,
meta?: any
);
- Первый параметр должен быть Error или null
- Второй параметр — это строка или буфер.
- Необязательно: третий аргумент должен быть исходной картой, которую может разрешить этот модуль.
- Необязательно: четвертый параметр, игнорируемый веб-пакетом, может быть чем угодно (например, некоторыми метаданными).
// 同步loader 返回多个处理结果
module.exports = function(content, map, meta) {
this.callback(null, someSyncOperation(content), map, meta);
};
В синхронном режиме, если возвращается только один результат, его также можно использовать напрямую.return
Вернуть результат.
// 同步loader 只返回一个处理结果
module.exports = function(content, map, meta) {
return someSyncOperation(content);
};
Использование в асинхронном режимеthis.async
получитьcallback
функция
module.exports = function(content, map, meta) {
var callback = this.async();
someAsyncOperation(content, function(err, result, sourceMaps, meta) {
if (err) return callback(err);
callback(null, result, sourceMaps, meta);
});
};
Разработайте свой собственный загрузчик
Структура каталогов проекта
|--src
| |--cjs.js //общая записьJs
| |--index.js // основной файл загрузчика
| |--options.json // файл определения опций загрузчика
|--babel.config.js
|--package.json
|--readme.md
определить параметры
options
только одно свойствоquality
, используется для управления генерацией.webp
Качество документа определяется следующим образом:
{
"additionalProperties": true,
"properties": {
"quality": {
"description": "quality factor (0:small..100:big), default=75",
"type": "number"
}
},
"type": "object"
}
Преобразование формата изображения
cwebp
Этот модуль js предоставляет обычные изображения и.webp
функция для преобразования между ними.
const CWebp = require('cwebp').CWebp
/**
* 普通图片转 .webp图片
* @param {string | buffer} img 图片绝对路径或二进制流
* @param {number} quality 生成 webp 图片的质量,默认75
* @returns .webp 文件流
*/
async function convertToWebp (img, quality = 75) {
let encoder = new CWebp(img)
encoder.quality = quality
let buffer = await encoder.toBuffer()
return buffer
}
загрузчик записи
import schema from './options.json'
export default async function loader (content) {
// 异步模式
let callback = this.async()
// 获取 options
const options = loaderUtils.getOptions(this) || {}
// 验证 options
validateOptions(schema, options, {
name: 'webp Loader',
baseDataPath: 'options'
})
try {
// 普通图片转 .webp
let buffer = await convertToWebp(content, options.quality)
callback(null, buffer)
} catch (err) {
callback(err)
}
}
// loader 接收文件流
export const raw = true
На этом загрузчик в основном готов.
использовать
// webpack.config.js
module.exports = {
// 其他配置
// ...
module: {
rules: [{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext].webp'
}
},{
loader: 'webp-loader',
options: {
quality: 70
}
}]
}]
}
}
Суммировать
На самом деле написать загрузчик не так сложно, как вы думаете, пока вы освоите базовые моменты, вы также сможете иметь свой собственный загрузчик.