Что такое вебпак-загрузчик?
Загрузчик — это функция, один параметр — это содержимое исходного файла, есть внутренний this, окончательный загрузчик должен иметь возвращаемое значение, иначе будет сообщено об ошибке: Окончательный загрузчик не вернул буфер или строку
причина:
Если это последний загрузчик в порядке обработки, его возвращаемое значение в конечном итоге будет передано в запрос веб-пакета, другими словами, это должна быть строка для хранения исполняемых сценариев JavaScript.
Как настроить webpack-загрузчик?
Настройка одного загрузчика
{
test: /\.js$/
use: [
{
loader: path.resolve(__dirname, 'src', 'loaders', 'first-loader.js'),
options: {/*这里是给loader传入的参数会有一个专门的库来处理这个参数,待会下面会讲到*/}
}
]
}
Настроить несколько загрузчиков
Если мы загрузим свой собственный загрузчик как модуль, вебпак по умолчанию будет искать модули в node_modules, но наш собственный загрузчик не находится в node_modules.Как мы можем заставить его искать наш собственный загрузчик?Шерстяная ткань? В это время нам нужно установить атрибут resolveLoader, который является объектом с атрибутом модулей. Значение этого атрибута представляет собой массив. Каждое значение в массиве представляет собой место хранения загрузчика, который нужно найти.
resolveLoader: {
modules: [
path.resolve('node_modules'),
path.resolve(__dirname, 'src', 'loaders')
]
},
Перенастроить загрузчик
{
test: /\.less$/,
use: ['style-loader','less-loader']
}
рекомендации по использованию загрузчика
Единственная ответственность, загрузчик делает только одну вещь, причина такой конструкции в том, что чем больше одиночная ответственность, тем сильнее композиция и лучше конфигурируемость.
Справа налево, цепочка выполнения, результат обработки предыдущего загрузчика передается следующему загрузчику для обработки
Модульный, загрузчик — это модуль, который существует сам по себе и не зависит ни от каких других модулей. Без гражданства, как и чистые функции.
Загрузчик имеет утилиту loader-utils для разбора параметров загрузчика и schema-utils для проверки формата.
зависимости загрузчика
API, связанный с загрузчиком
1. Кэш Webpack полностью использует кэширование для повышения эффективности компиляции.
this.cacheable();
2. Асинхронный Когда загрузчик не имеет зависимостей и может быть асинхронным, я думаю, он должен сделать его асинхронным без блокировки.
// 让 Loader 缓存
module.exports = function(source) {
var callback = this.async();
// 做异步的事
doSomeAsyncOperation(content, function(err, result) {
if(err) return callback(err);
callback(null, result);
});
};
3. Входящий исходный файл находится в виде буфера
По умолчанию исходный файл передается Загрузчику в виде строки UTF-8.Установка module.exports.raw=true может обрабатываться в виде буфера
module.exports.raw = true
4. Получить параметры загрузчика
const loaderUtils = require('loader-utils');
module.exports = function (source) {
// 获取当前用户给当前loader传入的参数对象options
const options = loaderUtils.getOptions(this);
return source;
}
5. Проверить, соответствует ли значение входящих опций требованиям
const loaderUtils = require('loader-utils');
const validate = require('schema-utils');
let json = {
"type": "object",
"properties": {
"content": {
"type": "string",
}
}
}
module.exports = function (source) {
const options = loaderUtils.getOptions(this);
// 第一个参数是校验的json 第二个参数是loader传入的options 第三个参数是当前loader的名称
validate(json, options, 'first-loader');
console.log(options.content)
}
// 当前规定 传入的options必须是一个对象 他里面的content的值必须是一个字符串 如果不满足要求则会有好的报错 xxx应该是一个什么类型
6. Загрузчик возвращает другие результаты
В некоторых сценариях загрузчик также должен возвращать что-то кроме содержимого.
module.exports = function(source) {
// 通过 this.callback 告诉 Webpack 返回的结果
this.callback(null, source, sourceMaps);
// 当你使用 this.callback 返回内容时,该 Loader 必须返回 undefined,
// 以让 Webpack 知道该 Loader 返回的结果在 this.callback 中,而不是 return 中
return;
};
this.callback(
// 当无法转换原内容时,给 Webpack 返回一个 Error
err: Error | null,
// 原内容转换后的内容
content: string | Buffer,
// 用于把转换后的内容得出原内容的 Source Map,方便调试
sourceMap?: SourceMap,
// 如果本次转换为原内容生成了 AST 语法树,可以把这个 AST 返回,
// 以方便之后需要 AST 的 Loader 复用该 AST,以避免重复生成 AST,提升性能
abstractSyntaxTree?: AST
);
7. Синхронный и асинхронный
Загрузчики делятся на синхронные и асинхронные.Описанные выше Загрузчики являются синхронными Загрузчиками, потому что их процессы преобразования синхронны, и результаты возвращаются после завершения преобразования. Однако в некоторых сценариях этапы преобразования могут выполняться только асинхронно. Например, для получения результата необходимо сделать сетевой запрос. Если вы используете синхронный метод, сетевой запрос заблокирует всю сборку, что приведет к очень медленная сборка.
module.exports = function(source) {
// 告诉 Webpack 本次转换是异步的,Loader 会在 callback 中回调结果
var callback = this.async();
someAsyncOperation(source, function(err, result, sourceMaps, ast) {
// 通过 callback 返回异步执行后的结果
callback(err, result, sourceMaps, ast);
});
};
8. Обработка бинарных данных
По умолчанию исходный контент, передаваемый Webpack в Loader, представляет собой строку, закодированную в формате UTF-8. Однако в некоторых сценариях загрузчик обрабатывает не текстовые файлы, а двоичные файлы, такие как загрузчик файлов, который требует, чтобы Webpack передал данные двоичного формата в загрузчик. Для этого нужно написать Loader так:
module.exports = function(source) {
// 在 exports.raw === true 时,Webpack 传给 Loader 的 source 是 Buffer 类型的
source instanceof Buffer === true;
// Loader 返回的类型也可以是 Buffer 类型的
// 在 exports.raw !== true 时,Loader 也可以返回 Buffer 类型的结果
return source;
};
// 通过 exports.raw 属性告诉 Webpack 该 Loader 是否需要二进制数据
module.exports.raw = true;
9. Кэш
В некоторых случаях некоторые операции преобразования требуют много времени в вычислительном отношении, и если повторяющиеся операции преобразования повторно выполнять для каждой сборки, сборка станет очень медленной. По этой причине Webpack будет кэшировать результаты обработки всех загрузчиков по умолчанию, то есть, когда файлы, подлежащие обработке, или их зависимые файлы не изменились, соответствующий загрузчик не будет снова вызываться для выполнения операции преобразования.
module.exports = function(source) {
// 关闭该 Loader 的缓存功能
this.cacheable(false);
return source;
};
10, другой API загрузчика
this.context: каталог, в котором находится обрабатываемый в данный момент файл.Если файл, обрабатываемый в данный момент загрузчиком, называется /src/main.js, тогда this.context равен /src.
this.resource: полный путь запроса к обрабатываемому в данный момент файлу, включая строку запроса, например, /src/main.js?name=1.
this.resourcePath: путь к обрабатываемому в данный момент файлу, например /src/main.js.
this.resourceQuery: строка запроса обрабатываемого файла.
this.target: равно Target в конфигурации Webpack
this.loadModule: Но когда загрузчик обрабатывает файл, если он зависит от результатов обработки других файлов для получения результата текущего файла, он может передать this.loadModule(request: string, callback: function(err, source, sourceMap , модуль )) для получения результата обработки файла, соответствующего запросу.
this.resolve: получить полный путь к указанному файлу, как оператор require, с помощью разрешения (контекст: строка, запрос: строка, обратный вызов: функция (ошибка, результат: строка)).
this.addDependency: добавить зависимый файл к текущему обрабатываемому файлу, чтобы при изменении зависимого файла загрузчик вызывался снова для обработки файла. Метод использования — addDependency(file:string).
this.addContextDependency: аналогично addDependency, но addContextDependency добавляет весь каталог к зависимостям обрабатываемого в данный момент файла. Метод использования — addContextDependency (каталог: строка).
this.clearDependencies: очищает все зависимости обрабатываемого файла с помощью метода clearDependencies().
this.emitFile: выведите файл, используйте метод emitFile(name: string, content: Buffer|string, sourceMap: {...}). Полный API
Рукописный простой загрузчик стилей и менее загрузчик
// 创建一个style标签里面放上源文件的样式字符串 插到页面上
module.exports = function (source) {
let script = (`
let style = document.createElement("style");
style.innerText = ${JSON.stringify(source)};
document.head.appendChild(style);
`);
return script;
}
let less = require('less');
module.exports = function (source) {
this.cacheable();
less.render(source, (err,result)=>{
console.log(result.css);
this.callback(err,result.css)
})
}
Не надоедайте знакомыми вещами, совершенствуйтесь каждый день понемногу, не бойтесь незнакомых вещей, учитесь каждый день понемногу;