Webpack style of loader – loader
Webpack itself can only process JS files, and the files that JS files in our project will rely on also include HTML, CSS, JPG and other types. Since then, Loader is specially used to convert non-JS modules into JS modules. Also recommend its single responsibility (a loader is only responsible for one transformation)
loader
Official documentation – Loaders
Loader Basic Knowledge
Loader Interface
The above three documents have basically explained loader knowledge in a comprehensive way. The following lists some common knowledge points and personal understanding:
define
A loader is essentially a JavaScript module exported as a function. The Loader Runner calls this function and passes in the results or resource files generated by the previous loader.
/ * * * *@param {string|Buffer} Content Indicates the content of the source file *@param {object} (map) can be used by https://github.com/mozilla/source-map SourceMap data *@param {any} [meta] Meta data, can be any content */
module.exports = function (content, map, meta) {
// Your WebPack Loader code
// Here we just print a sentence and return the content (or custom content) to the next loader
console.log("This is my first custom loader");
return content;
};
/ * * *@remainingRequest Remaining requests: request string * for the loader following itself in the loader chain@precedingRequest The request string * of the loader that precedes it in the loader chain@data Data object */
module.exports.pitch = function (remainingRequest, precedingRequest, data) {
// Your WebPack Loader code
// This. Data can be updated in the normal method
data.value = 66;
// return something;
};
Copy the code
category
Rule.enforce
There are four types: pre, normal, inline, and post. The execution sequence is different
Inline is available through! To disable loader:
// Disable plain loaders
import { a } from ! "" ./file1.js";
// Disable preloading and plain loaders
import { b } from "-! ./file2.js";
Disable all laoders
import { c } from "!!!!! ./file3.js";
Copy the code
Inline loader and! Should not be used Prefix, because it’s non-standard. They may be used by loader-generated code
-
Pitching phase (left-to-right): Pitch method on the loader called in post-(post), inline (inline), normal (normal), pre (pre) order. For more detailed information, please see [Pitching Loader] (webpack.docschina.org/api/loaders…
Use: In some cases, the loader only cares about the metadata following the request and ignores the results of the previous loader
-
Normal phase (from right to left): A Normal method on the Loader, called in the order pre, Normal, inline, and post. Conversion of module source code occurs in this phase.
For example:
module.exports = {
/ /...
module: {
rules: [{/ /...
use: ["a-loader"."b-loader"."c-loader"],},],},};Copy the code
Its execution sequence is:
|- a-loader `pitch`
|- b-loader `pitch`
|- c-loader `pitch`
|- requested module is picked up as a dependency
|- c-loader normal execution
|- b-loader normal execution
|- a-loader normal execution
Copy the code
If the pitch of the B-loader returns something in the above configuration, the order of execution will be:
|- a-loader `pitch`
|- b-loader `pitch` returns something
|- a-loader normal execution
Copy the code
So when the Loader’s pitch method has a return value, it skips the rest of the Loader methods (even if they all have pitch methods), and then goes back to itself and ends
model
- Synchronous:
this.callback
- Asynchronous:
this.async
// callback
module.exports = function (content, map, meta) {
const output = someSyncOperation(content);
return output;
// or
this.callback(null, output, map, meta);
return;
};
// async
module.exports = function (content, map, meta) {
const callback = this.async();
someAsyncOperation(content, function (err, result, sourceMaps, meta) {
if (err) return callback(err);
callback(null, result, sourceMaps, meta);
});
};
Copy the code
Write your own loader
The official suggested that follows the principle: webpack.docschina.org/contribute/…
style-loader
Basic knowledge of
Webpack style – loader documentation
Inserting CSS into the DOM is typically used with csS-loader (which loads CSS files and parses imported CSS files, eventually returning CSS code)
use
example
npm init -y
yarn add webpack webpack-cli style-loader css-loader file-loader --save-dev
Copy the code
Create several CSS test files:
/* assets/a.css */
.a {
font-size: 16px;
}
Copy the code
/* assets/b.css */
.b {
font-size: 16px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
Copy the code
/* assets/c.css */
@import url(./a.css);
.c {
display: inline-block;
font-weight: 600;
}
Copy the code
Entry file:
// src/index.js
export const add = (num1, num2) = > {
return num1 + num2;
};
import ".. /assets/c.css";
import ".. /assets/b.css";
// import bCSS from '.. /assets/b.css';
// bCSS.use();
// bCSS.unuse();
console.log("this is index.js");
console.log(add(66.99));
Copy the code
<! -- dist/index.html -->
<! DOCTYPEhtml>
<html>
<head>
<meta charset="utf-8" />
<title>start</title>
<! -- <link rel="stylesheet" type="text/css" href="./assets/b.css" /> -->
</head>
<body>
<div class="b">This is webpack loader example</div>
</body>
<script src="main.js"></script>
</html>
Copy the code
Webpack configuration file: webpack.config.js
const path = require("path");
module.exports = {
mode: "development".entry: "./src/index.js".output: {
filename: "main.js".path: path.resolve(__dirname, "dist"),},module: {
rules: [{test: /\.css$/i,
use: [
// 'style-loader',
{
loader: "style-loader".options: {
injectType: "styleTag"./ / the default value
// injectType: "singletonStyleTag"
// injectType: "lazyStyleTag"
// injectType: "lazySingletonStyleTag"
InjectType: "linkTag" injectType: "linkTag" injectType: "linkTag" injectType: "linkTag}},"css-loader".// 'file-loader'],},],},};Copy the code
Then run webpack (you can also configure a shortcut command XXX, yarn XXX in the scripts of package.json) to package, and open index.html in a browser to view the package result
injectType
Optional value: styleTag(default value), singletonStyleTag, autoStyleTag, lazyStyleTag, lazySingletonStyleTag, lazyAutoStyleTag, or linkTag
- styleTag
Styles are automatically inserted into the DOM by using multiple
, that is, an import generates a style tag
<style>
.a {
font-size: 16px;
}
</style>
<style>
.c {
display: inline-block;
font-weight: 600;
}
</style>
<style>
.b {
font-size: 16px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
</style>
Copy the code
- singletonStyleTag
Corresponds to styleTags, but it incorporates them into a style tag. Duplicate style names are not processed
<style>
.a {
font-size: 16px;
}
.c {
display: inline-block;
font-weight: 600;
}
.a {
font-size: 16px;
}
.b {
font-size: 16px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
</style>
Copy the code
- linkTag
Use multiple inserts of styles into the DOM
<link
rel="stylesheet"
href="file:///D:/testCodes/webpack-style-loder/dist/d06ed220ba698dc21e8270035e104dce.css"
/>
<link
rel="stylesheet"
href="file:///D:/testCodes/webpack-style-loder/dist/ada3b1108d67c1ded7467f095ae0a549.css"
/>
Copy the code
insert
Type:
String
|Function
, Default:head
By default, style-loader adds/to the end of the page tag unless insert is specified.
This gives the STYle-loader created CSS a higher priority than the CSS that already exists within the tag. You can use other values when the default behavior doesn’t meet your needs, but we don’t recommend this.
In addition to injectType and insert parameters, there are attributes and esModule parameters, as described in the above official documentation
Thanks for the cover image: Po Go – Understand WebPack-Loader
Preview: style-loader source view loader principle