Skip to content

Commit fb4073a

Browse files
committed
feat: webpack-plugin
1 parent 9651ff5 commit fb4073a

File tree

10 files changed

+658
-40
lines changed

10 files changed

+658
-40
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
<tr>
1717
<td><a href="https://juejin.cn/post/7265516154847313954">初探webpack之编写plugin</a></td>
18+
<td><a href="./packages/webpack-plugin">packages/webpack-plugin</a></td>
1819
</tr>
1920

2021
<tr>

package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
{
2-
"name": "react-rspack-template",
2+
"name": "webpack-simple-environment",
33
"version": "1.0.0",
44
"scripts": {
55
"lint-es": "eslint --fix --ext .js,.jsx,.ts,.tsx --ignore-path .gitignore .",
66
"lint-style": "stylelint \"**/*.{css,scss,sass}\" --fix --ignore-path .gitignore"
77
},
88
"repository": {
99
"type": "git",
10-
"url": "https://github.com/WindrunnerMax/ReactRspackTemplate"
10+
"url": "https://github.com/WindrunnerMax/webpack-simple-environment"
1111
},
1212
"keywords": [],
1313
"author": "",
1414
"license": "MIT",
1515
"bugs": {
16-
"url": "https://github.com/WindrunnerMax/ReactRspackTemplate/issues"
16+
"url": "https://github.com/WindrunnerMax/webpack-simple-environment/issues"
1717
},
18-
"homepage": "https://github.com/WindrunnerMax/ReactRspackTemplate",
18+
"homepage": "https://github.com/WindrunnerMax/webpack-simple-environment",
1919
"devDependencies": {
2020
"@types/jest": "29.4.0",
2121
"@types/node": "20.11.10",

packages/webpack-plugin/package.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "webpack-plugin",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"license": "MIT",
6+
"scripts": {
7+
"build": "cross-env NODE_ENV=production webpack --config webpack.config.js"
8+
},
9+
"devDependencies": {
10+
"cross-env": "7.0.3",
11+
"html-webpack-plugin": "5.3.2",
12+
"webpack": "5.56.1",
13+
"webpack-cli": "4.8.0"
14+
}
15+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
7+
<title><%= htmlWebpackPlugin.options.title %></title>
8+
</head>
9+
<body>
10+
<!-- inject:name="header" -->
11+
<div id="app"></div>
12+
<!-- inject:name="footer" -->
13+
<!-- built files will be auto injected -->
14+
</body>
15+
</html>

packages/webpack-plugin/src/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { add } from "./sum";
2+
3+
console.log(add(1, 1));

packages/webpack-plugin/src/sum.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const add = (a, b) => a + b;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
const simulateRemoteData = key => {
2+
const data = {
3+
header: "<div>HEADER</div>",
4+
footer: "<div>FOOTER</div>",
5+
};
6+
return Promise.resolve(data[key]);
7+
};
8+
9+
class StaticPageSlice {
10+
constructor(options) {
11+
this.options = options || {}; // 传递参数
12+
}
13+
apply(compiler) {
14+
compiler.hooks.thisCompilation.tap("StaticPageSlice", compilation => {
15+
compilation.hooks.processAssets.tapPromise(
16+
{
17+
name: "StaticPageSlice",
18+
stage: compilation.constructor.PROCESS_ASSETS_STAGE_ADDITIONS,
19+
additionalAssets: true,
20+
},
21+
assets => this.replaceAssets(assets, compilation)
22+
);
23+
});
24+
}
25+
26+
replaceAssets(assets, compilation) {
27+
return new Promise(resolve => {
28+
const cache = {};
29+
const assetKeys = Object.keys(assets);
30+
for (const key of assetKeys) {
31+
const isLastAsset = key === assetKeys[assetKeys.length - 1];
32+
if (!/.*\.html$/.test(key)) {
33+
if (isLastAsset) resolve();
34+
continue;
35+
}
36+
let target = assets[key].source();
37+
const matchedValues = target.matchAll(/<!-- inject:name="(\S*?)" -->/g); // `matchAll`函数需要`Node v12.0.0`以上
38+
const tags = [];
39+
for (const item of matchedValues) {
40+
const [tag, name] = item;
41+
tags.push({
42+
tag,
43+
name,
44+
data: cache[name] ? cache[name] : simulateRemoteData(name),
45+
});
46+
}
47+
Promise.all(tags.map(item => item.data))
48+
.then(res => {
49+
res.forEach((data, index) => {
50+
const tag = tags[index].tag;
51+
const name = tags[index].name;
52+
if (!cache[name]) cache[name] = data;
53+
target = target.replace(tag, data);
54+
});
55+
})
56+
.then(() => {
57+
compilation.assets[key] = {
58+
source() {
59+
return target;
60+
},
61+
size() {
62+
return this.source().length;
63+
},
64+
};
65+
})
66+
.then(() => {
67+
if (isLastAsset) resolve();
68+
});
69+
}
70+
});
71+
}
72+
}
73+
74+
module.exports = StaticPageSlice;
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const path = require("path");
2+
const HtmlWebpackPlugin = require("html-webpack-plugin");
3+
const StaticPageSlice = require("./static-page-slice");
4+
5+
module.exports = {
6+
mode: process.env.NODE_ENV,
7+
entry: "./src/index.js",
8+
output: {
9+
filename: "index.js",
10+
path: path.resolve(__dirname, "dist"),
11+
},
12+
plugins: [
13+
new HtmlWebpackPlugin({
14+
title: "Webpack Template",
15+
filename: "index.html", // 打包出来的文件名 根路径是`module.exports.output.path`
16+
template: path.resolve("./public/index.html"),
17+
hash: true, // 在引用资源的后面增加`hash`戳
18+
minify: {
19+
collapseWhitespace: true,
20+
removeAttributeQuotes: true,
21+
minifyCSS: true,
22+
minifyJS: true,
23+
},
24+
inject: "body", // `head`、`body`、`true`、`false`
25+
scriptLoading: "blocking", // `blocking`、`defer`
26+
}),
27+
new StaticPageSlice({
28+
url: "https://www.example.com/",
29+
}),
30+
],
31+
};

0 commit comments

Comments
 (0)