webpack
Webpack is a front-end resource packaging tool. It performs static analysis according to the dependencies of modules, and then generates corresponding static resources according to the specified rules.
Basic use
Install webpack locally
yarn add webpack webpack-cli --dev
File directory, createwebpack.config.js
Configuration file (in webpack V4, no configuration is required, but most projects require complex settings).
const path = require("path");
module.exports = {
/**
*The default value is production
*Development optimizes the packaging speed and adds some assistance required by the debugging process
*Production optimization packaging results
**/
mode: "development",
Entry: ". / SRC / main. JS", // entry file
output: {
Filename: "bundle. JS", // output filename
path: path. Join (_dirname, "dist"), // output file path
},
};
Run package command
yarn webpack
Resource module loading
Webpack can only process JS files by default, and non JS files can be loaded and processed through loader
File resources
Loader corresponding to installation file resource
yarn add css-loader style-loader --dev
File import
// main.js
import createHeading from "./heading.js";
import "./main.css";
const heading = createHeading();
document.body.append(heading);
Webpack profile
adoptcss-loader
To complete the processing of CSS files, you need tostyle-loader
Bring the packaged CSS file into the page
Note: the recording mechanism of the loader is from back to front, so the CSS loader in the array is used first, and the style loader is used later
const path = require("path");
module.exports = {
mode: "none",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.join(__dirname, "dist"),
},
module: {
rules: [
{
test: /.css$/,
use: ["style-loader", "css-loader"],
},
],
},
};
Picture resources
becauseindex.html
Not generated todist
Instead, it is placed in the root directory of the project, so the project root directory is taken as the root directory of the website, and webpack will default that all packaging results are placed under the root directory of the website, resulting in finding image resources in the root directory. Solution configurationpublicPath: 'dist/'
。
The image file encountered during webpack packaging is matched to the file loader according to the configuration file configuration. The file loader starts to work. First copy the imported file to the output directory, and then copy the file to the path after the output directory, which is returned as the return value of the current module, so that the resource is published.
Install the loader corresponding to the picture resource
yarn add file-loader --dev
File import
import createHeading from "./heading.js";
import "./main.css";
import icon from "./icon.png";
const heading = createHeading();
document.body.append(heading);
const img = new Image();
img.src = icon;
document.body.append(img);
Webpack profile
const path = require("path");
module.exports = {
mode: "none",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.join(__dirname, "dist"),
publicPath: "dist/",
},
module: {
rules: [
{
test: /.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /.png$/,
use: "file-loader",
},
],
},
};
URL resource
data urls
It’s specialurl
Protocols can be used to directly represent a file, traditionalurl
The server is required to have a corresponding file, and then we get the corresponding file by requesting this address. anddata url
Is a currenturl
It can directly represent the content of the fileurl
The text in contains the contents of the file and will not send any HTTP requests when used.
HTML content:data:text/html;charset=UTF-8,<h1>xxx</h1>
Png type file:data:image/png;base64,iVBORw0KGgoAAAANSUhE...
Install the loader corresponding to the resource
yarn add url-loader --dev
Webpack profile
...
module: {
rules: [
{
test: /.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /.png$/,
use: {
loader: "url-loader",
options: {
Limit: 10 * 1024, // use URL loader for image resources less than 10KB, and file loader for image resources greater than 10KB
},
},
},
],
},
Common loader classification
- Compile conversion class
- File operation class
- Code check class
Webpack and es2015
Webpack handles import and export because the module needs to be packaged, but it cannot convert other ES6 features in the code
Install the loader corresponding to the resource
yarn add babel-loader @babel/core @babel/preset-env --dev
module: {
rules: [
{
test: /.js$/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
},
{
test: /.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /.png$/,
use: {
loader: "url-loader",
options: {
Limit: 10 * 1024, // use URL loader for image resources less than 10KB, and file loader for image resources greater than 10KB
},
},
},
],
},
Module loading mode
Modules are loaded in accordance with ES modules standardsimport
Declaration, following the common JS standardrequire
Function, following amd standarddefine
Function sumrequire
function
In addition to the above methods, the trigger module loading method also includes the methods in CSS style codeurl
Function sum@import
Instruction, image tag in HTML codesrc
attribute
HTMLsrc
Property triggers module loading
yarn add html-loader --dev
{
test:/.html$/,
use:{
loader:'html-loader'
}
}
However, HTML loader can only handle img: SRC attributes under HTML, and other additional attributes are configured through attrs
{
test:/.html$/,
use:{
Loader: 'HTML loader', // only the HTML img SRC attribute can be processed by default, and other additional attributes can be configured through attrs
options:{
attrs:['img:src','a:href']
}
}
}
Develop a loader
The resource loading process of webpack is similar to the work pipeline. Multiple loaders can be used in turn during the loading process, but the final result must be JS code.
Each webpack loader needs to export a function. The input is the content of the loaded resource file, and the output is the result of this processing.
const marked = require("marked");
module.exports = (source) => {
const html = marked(source);
return html;
};
module: {
rules: [
{
test: /.md$/,
use: [
"html-loader",
".. / MD loader", // module name or file path, similar to nodejs require
],
},
];
}
Plug in mechanism
Loader focuses on loading resource modules, plugin solves other automation work, and enhances the automation ability of webpack
Auto clear directory plugin
Install expansion pack
yarn add clean-webpack-plugin --dev
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
mode: "none",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.join(__dirname, "dist"),
publicPath: "dist/",
},
module: {
rules: [
...
],
},
plugins: [new CleanWebpackPlugin()],
};
Automatically generate HTML
Install expansion pack
yarn add html-webpack-plugin --dev
Generate HTML under dist to solve the problem that the introduction path in the HTML under the root needs to be hard coded through the public path declaration.
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "none",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.join(__dirname, "dist"),
// publicPath: "dist/",
},
plugins: [new CleanWebpackPlugin(), new HtmlWebpackPlugin()],
};
user-defined metadata
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "none",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.join(__dirname, "dist"),
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: "webpack plugin sample",
meta: {
viewport: "width=device-width",
},
template: "./src/index.html",
}),
],
};
template file
<!--./src/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Webpack</title>
</head>
<body>
<div class="container">
<!-- Accessing plug-in configuration data -- >
<h1><%= htmlWebpackPlugin.options.title %></h1>
</div>
</body>
</html>
Output multiple page files at the same time
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "none",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.join(__dirname, "dist"),
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: "webpack plugin sample",
meta: {
viewport: "width=device-width",
},
template: "./src/index.html",
}),
new HtmlWebpackPlugin({
filename: "about.html",
}),
],
};
Static file copy plug-in
yarn add copy-webpack-plugin --dev
const CopyWebpackPlugin = require("copy-webpack-plugin");
plugins: [
//Parameter array, specifying the copied file path (wildcard, directory, relative path)
new CopyWebpackPlugin({
patterns: ["public"],
}),
];
How the plug-in mechanism works
The webpack plugin is implemented through the hook mechanism.
The hook mechanism is similar to events in the web. There are many links in the working process of webpack. In order to facilitate the extension of plug-ins, webpack has buried hooks in almost every link, so that when developing plug-ins, we can easily expand the ability of webpack by loading different tasks on these different nodes.
Develop a plug-in
Webpack requires that the plug-in must be a function or an object containing an apply method. Generally, we will define the plug-in as a type and then define an apply method in this type
Define a plug-in to mount tasks on the hook. This plug-in is used to clear the bundle Useless comments in JS
Myplugin file
module.exports = class MyPlugin {
apply(compiler) {
//This method is automatically called when the webpack is started. Compile configuration object and configuration information
console. Log ("myplugin startup");
//Access the hook emit through the hooks property
//Reference: https://webpack.docschina.org/api/compiler-hooks/
//The tap method registers the hook function (parameter 1: plug-in name, parameter 2: function attached to the hook)
compiler.hooks.emit.tap("MyPlugin", (compilation) => {
//Compilation can be understood as the context of this packaging, and all the results of the packaging process will be put into this object
// compilation. The assets property is an object used to obtain the information of the resource file to be written to the directory
for (const name in compilation.assets) {
// console. Log ("file name:", name); As shown in the figure
// console. Log ("file content:", compilation. Assets [name]. Source());
if (name.endsWith(".js")) {
//Get content
const contents = compilation.assets[name].source();
//Replace content
const withoutComments = contents.replace(/\/\*\*+\*\//g, "");
//Overwrite old content
compilation.assets[name] = {
source: () => withoutComments,
size: () => withoutComments. Length, // returns the size of the content. Webpack must be added
};
}
}
});
}
};
configuration file
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const myPlugin = require("./MyPlugin.js");
module.exports = {
mode: "none",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.join(__dirname, "dist"),
// publicPath: "dist/",
},
plugins: [new CleanWebpackPlugin(), new myPlugin()],
};