Preface: the author study webpack knowledge from the foundation to the principle to write a series, in order to review. Hope to help more friends who are learning Webpack.
Webpack series learning – First experience
Webpack series learning – Basic Usage one
Webpack series learning – various loaders to use
Webpack series learning – hot update and compression
Webpack series learning – Using ESLint and publishing NPM packages
Webpack series learning – Building webPack configurations
Webpack series learning – detailed implementation of easy Webpack
define
Loader is simply a JS module exported as a function
structure
The simplest loader code structure is:
module.exports = function(source){
return source;
}
Copy the code
Execution sequence of multiple Loaders
The execution sequence is sequential, from right to left
An example is used to verify the loader execution order
- 1. Configure a-loader and B-loader in webpack.config.js
// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js'.output: {
path: path.join(__dirname, 'dist'),
filename: 'main.js',},module: {
rules: [{test: /\.js$/,
use: [path.resolve('./loaders/a-loader.js'), path.resolve('./loaders/b-loader.js'],},],},};Copy the code
- 2. Write a-loader.js and b-loader.js respectively
// a-loader.js
module.exports = function a(source) {
console.log('loader a is used; ');
return source;
};
// b-loader.js
module.exports = function b(source) {
console.log('loader b is used; ');
return source;
};
Copy the code
- 3. Run web Pack, it can be seen that B was printed first, and then A
Loader debugger: loader-runner
Definition:
Loader-runner allows loaders to run without installing webpack
Function:
As a dependency of WebPack, it is used in Webpack to execute loader, develop and debug loader
The use of loader – runner
import { runLoaders } from "loader-runner";
runLoaders({
resource: "/abs/path/to/file.txt? query".// String: The absolute path to the resource (you can add a query String)
loaders: ["/abs/path/to/loader.js? query"].// String[]: absolute path of loader (can add query String)
context: { minimize: true },
// Additional Loader context in addition to the base context
readResource: fs.readFile.bind(fs)
// A function that reads resources
}, function(err, result) {
// err: Error?
})
Copy the code
Use loader-runner to develop a raw-loader (convert the contents of a file to string)
1. Write raw-loader and test cases
// src/raw-loader.js
module.exports = function (source) {
const json = JSON.stringify(source)
.replace(/\u2028/g.'\\u2028')
.replace(/\u2029/g.'\\u2029');
return `export default ${json}`;
};
// src/demo.txt
aaa
Copy the code
2. Using the run – loader
// /run-loader.js
const { runLoaders } = require('loader-runner');
const fs = require('fs');
const path = require('path');
runLoaders(
{
resource: path.join(__dirname, './src/demo.txt'),
loaders: [path.join(__dirname, './src/raw-loader.js')].context: {
minimize: true,},readResource: fs.readFile.bind(fs),
},
(err, res) = > {
err ? console.log(err) : console.log(res); });Copy the code
3. Run node run-loader.js to view the result
Obtaining Loader parameters
Use the loader-utils package. Let’s just install it.
npm i loader-utils -S
Copy the code
Add a parameter to run-loader.js as follows:
loaders: [
{
loader: path.join(__dirname, './src/raw-loader.js'),
options: {
name: 'test',
},
},
],
Copy the code
Then use loader-utils in raw-loader.js to get the parameters
const loaderUtils = require('loader-utils');
module.exports = function (source) {
const { name } = loaderUtils.getOptions(this);
console.log(name);
const json = JSON.stringify(source)
.replace(/\u2028/g.'\\u2028')
.replace(/\u2029/g.'\\u2029');
return `export default ${json}`;
};
Copy the code
Print name and view the result
Loader exception handling
1. Use the throw function in the loader
2. Pass an error through this.callback
this.callback(
err: Error | null.content: string | Buffer, sourceMap? : SourceMap, meta? : any )Copy the code
How to develop an asynchronous loader
Return an asynchronous function via this.async. The first argument is Error, and the second argument is the result of the processing
const fs = require('fs');
const path = require('path');
module.exports = function (source) {
const callback = this.async();
fs.readFile(path.join(__dirname, './async.txt'), 'utf-8'.(err, data) = > {
callback(null, data);
});
};
Copy the code
Run the print, and you can see that the result is asynchronous
Using cache in loader:
1. Loader cache is enabled by default in webpack. You can use this.cacheable(false) to disable cache
2. Cache condition: The loader result has a certain output under the same input. A dependent loader cannot use the cache.