What is loader?
Loader is a function that is executed during compilation of WebPack. Webpack does not recognize modules that do not end with JS and tells Webpack how to package certain files
Replace a string
Here I want to use loader to replace WORD with XXX, but I find there is no loader I want to use, so I have to write one myself
console.log('hello word');
Copy the code
// module.exports = function (source, map, export) meta) { return source.replace('word', 'xxx'); }Copy the code
// webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
entry: {
main: './src/index.js'
},
module: {
rules: [{
test: /.js/,
use: [
{
loader: path.resolve(__dirname, './loaders/replaceLoader.js'),
},
]
}]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
}
}
Copy the code
Build result, custom loader implements our effect
Is it possible to pass the substitution as an argument?
The options of the Loader configuration are obtained from the loader function this.query
// loader
module.exports = function (source, map, meta) {
const options = this.query;
return source.replace('word', options.name);
}
Copy the code
Obtain the value from loader-utils
const loaderUtils = require('loader-utils');
module.exports = function(source) {
const options = loaderUtils.getOptions(this);
return source.replace('dell', options.name);
}
Copy the code
const path = require('path'); module.exports = { mode: 'development', entry: { main: './src/index.js' }, module: { rules: [ { test: /.js/, use: [{loader: path. Resolve (__dirname, '. / loaders/replaceLoader. Js'), / / the loader function is equivalent to pass parameters options: {name: '123123123' } } ] } ] }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, };Copy the code
We import loader through path. Can we write loader name directly like less-loader? ResolveLoader can configure loader folder
const path = require('path'); Module.exports = {mode: 'development', entry: {main: './ SRC /index.js'}, // Custom loader folder resolveLoader: {modules: ['node_modules', './loaders'] }, module: { rules: [ { test: /.js/, use: [{// node_modules or loaders find replaceloader. js loader: 'replaceLoader', options: {name: '123123123' } } ] } ] }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, };Copy the code
this.callback
In addition to returning the value of the loader compilation, this. Callback can also be used
this.callback( err: Error | null, content: string | Buffer, sourceMap? : SourceMap, meta? : any );Copy the code
const loaderUtils = require('loader-utils');
module.exports = function(source) {
const options = loaderUtils.getOptions(this);
callback(null, source.replace('word', options.name));
}
Copy the code
Asynchronous loader (blocking)
Async loader, using this.async(), returns the value through the return value callback of this.async()
const loaderUtils = require('loader-utils');
module.exports = function(source) {
const options = loaderUtils.getOptions(this);
const callback = this.async();
setTimeout(() => {
const result = source.replace('word', options.name);
callback(null, result);
}, 1000);
}
Copy the code
What should I pay attention to when defining a loader
- Commonjs style
- It’s a function
- This cannot be the arrow function. There are a lot of arguments on this. See the webpack documentation
See more loader configurations
Webpack is definitely a huge system. This article only introduces how to define a loader completely. If you want to know more, you can see webpack Loader-API