-
Notifications
You must be signed in to change notification settings - Fork 1
/
webpack.config.js
124 lines (107 loc) · 2.72 KB
/
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { readFile } from "node:fs/promises";
import path from "path";
import sharp from "sharp";
import CopyPlugin from "copy-webpack-plugin";
import CleanPlugin from "webpack-clean-plugin";
import HtmlWebpackPlugin from "html-webpack-plugin";
const ICON_SIZES = [16, 24, 32, 48, 64, 96, 128];
function isProd() {
return process.env.NODE_ENV === "production";
}
async function patchManifest(manifestContent) {
const packageJson = JSON.parse(
await readFile(path.join(import.meta.dirname, "package.json")),
);
const manifest = JSON.parse(manifestContent);
let darkIcons = ICON_SIZES.map((size) => [
String(size),
pngIconPath("dark", size),
]);
darkIcons = Object.fromEntries(darkIcons);
const themeIcons = ICON_SIZES.map((size) => ({
size,
light: pngIconPath("light", size),
dark: pngIconPath("dark", size),
}));
manifest.version = packageJson.version;
manifest.icons = darkIcons;
manifest.action.default_icon = darkIcons;
manifest.action.theme_icons = themeIcons;
return JSON.stringify(manifest);
}
function pngIconPath(type, size) {
return `icon/icon-${type}-${size}.png`;
}
function copyPluginIconPatterns() {
const res = ["dark", "light"].flatMap((type) =>
ICON_SIZES.map((size) => {
return {
from: `icon/${type}-icon.svg`,
to: pngIconPath(type, size),
async transform(content) {
return sharp(content).resize(size).png().toBuffer();
},
};
}),
);
return res;
}
export default async () => ({
mode: isProd() ? "production" : "development",
context: path.resolve(import.meta.dirname, "src"),
entry: {
"content-script": "./content-script",
background: "./background",
popup: "./popup",
},
plugins: [
new CleanPlugin(),
new CopyPlugin({
patterns: [
{
from: "manifest.json",
to: "manifest.json",
async transform(content) {
return await patchManifest(content);
},
},
...copyPluginIconPatterns(),
],
}),
new HtmlWebpackPlugin({
chunks: ["popup"],
filename: "popup.html",
title: "Prod Guard Settings",
}),
],
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: "babel-loader",
},
{
test: /\.svg$/,
type: "asset/source",
},
{
test: /\.svg$/,
resourceQuery: /data-uri/,
type: "asset/inline",
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
type: "asset/resource",
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
resolve: {
extensions: [".js", ".jsx", ".ts", ".tsx"],
},
devtool: "source-map",
});