aboutsummaryrefslogtreecommitdiffstats
path: root/webpack.config.js
diff options
context:
space:
mode:
authorArpit Chakladar <arpitchakladar+git@gmail.com>2026-07-13 23:32:26 +0530
committerGitHub <noreply@github.com>2026-07-13 23:32:26 +0530
commitce401d03e75bcbfd1cdfa963954e0807219fb80d (patch)
tree52a813c1705a952312c20c328b00fa845a3453f9 /webpack.config.js
parent98e7019c61ea0ffe344ef7ce809d38d62254a9fc (diff)
parentdfba7ff6fff7bde33b40a343a2318b35c429b40f (diff)
downloadbanglar-bhumi-utils-ce401d03e75bcbfd1cdfa963954e0807219fb80d.tar.gz
banglar-bhumi-utils-ce401d03e75bcbfd1cdfa963954e0807219fb80d.zip
Merge pull request #6 from arpitchakladar/adding-documentation-comments
Adding documentation comments
Diffstat (limited to 'webpack.config.js')
-rw-r--r--webpack.config.js249
1 files changed, 249 insertions, 0 deletions
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..f75afa3
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,249 @@
+/**
+ * Webpack configuration for the Banglar Bhumi Utils Chrome extension.
+ *
+ * Produces four separate bundles:
+ * 1. **Background script** – service worker entry point.
+ * 2. **Uninjected scripts** – content scripts that run as-is.
+ * 3. **Injected scripts** – content scripts that are further processed
+ * so they can be injected into the page DOM.
+ * 4. **Shared modules** – libraries compiled as standalone files and
+ * referenced via global variables (`$<hash>`).
+ *
+ * Custom loaders and plugins handle dependency ordering, import counting,
+ * asset-URL rewriting, manifest generation, and declarative-net-rule creation.
+ */
+import fs from "fs";
+import path from "path";
+import { fileURLToPath } from "url";
+
+import CopyPlugin from "copy-webpack-plugin";
+import webpack from "webpack";
+import { merge } from "webpack-merge";
+
+import CreateInjectedSharedModulesPlugin from "./config/webpack/plugins/create-injected-shared-modules-webpack-plugin.js";
+import CreateManifestPlugin from "./config/webpack/plugins/create-manifest-webpack-plugin/index.js";
+import CreateRulesPlugin from "./config/webpack/plugins/create-rules-webpack-plugin.js";
+import InjectScriptPlugin from "./config/webpack/plugins/inject-script-webpack-plugin.js";
+import { getFileName } from "./config/webpack/utils/build-file.js";
+import { inlineJavascript } from "./config/webpack/utils/inline-javascript.js";
+import scripts from "./config/webpack/utils/scripts.js";
+import sharedModules from "./config/webpack/utils/shared-modules.js";
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+global.ROOT_DIR = path.resolve(__dirname);
+global.CONFIG_DIR = path.resolve(ROOT_DIR, "config");
+global.SOURCE_DIR = path.resolve(ROOT_DIR, "src");
+global.production = process.env.NODE_ENV === "production";
+
+const sharedModulesImportedCount = {};
+
+for (const sharedModule of sharedModules) {
+ sharedModulesImportedCount[sharedModule] = 0;
+}
+
+const injectedSharedModulesImportedCount = {};
+
+for (const sharedModule of sharedModules) {
+ injectedSharedModulesImportedCount[sharedModule] = 0;
+}
+
+const backgroundScriptEntries = {};
+const uninjectedScriptEntries = {};
+const injectedAfterScriptEntries = {};
+const sharedModuleEntries = {};
+const sharedModuleExternals = {};
+
+const backgroundScriptImports = fs.readdirSync(path.resolve(SOURCE_DIR, "background"))
+ .map((scriptName) => `import "${path.resolve(SOURCE_DIR, "background", scriptName)}";`)
+ .join("\n");
+backgroundScriptEntries["background script"] = {
+ import: inlineJavascript(backgroundScriptImports),
+ filename: "background.js"
+};
+
+for (const scriptPath in scripts) {
+ for (const scriptType in scripts[scriptPath]) {
+ const currentScripts = scripts[scriptPath][scriptType];
+ let scriptEntries;
+ let destinationFolder = "scripts";
+
+ switch (scriptType) {
+ case "injected":
+ scriptEntries = injectedAfterScriptEntries;
+ destinationFolder = "scripts/injected";
+ break;
+
+ default:
+ scriptEntries = uninjectedScriptEntries;
+ }
+
+ scriptEntries[`${scriptType} - "${scriptPath}"`] = {
+ import: inlineJavascript(currentScripts.map((script) => `import "${path.resolve(SOURCE_DIR, "scripts", script)}";`).join("\n")),
+ filename: `${destinationFolder}/${getFileName(scriptType, scriptPath)}.js`
+ };
+ }
+}
+
+for (const sharedModule of sharedModules) {
+ const sharedModuleNameHash = getFileName(sharedModule, "shared");
+ const sharedModuleGlobalVariableName = `$${sharedModuleNameHash.substring(sharedModuleNameHash.length - 16)}`;
+ sharedModuleEntries[sharedModule] = {
+ import: path.resolve(SOURCE_DIR, "shared", sharedModule),
+ filename: `shared/${sharedModuleNameHash}.js`,
+ library: {
+ name: sharedModuleGlobalVariableName,
+ type: "var"
+ }
+ };
+ sharedModuleExternals[`@/shared/${sharedModule}`] = sharedModuleGlobalVariableName;
+}
+
+const commonOptions = {
+ mode: "production",
+ target: "web",
+ resolve: {
+ extensions: [".ts", ".js", ".html"],
+ alias: {
+ "@": global.SOURCE_DIR
+ }
+ },
+ module: {
+ rules: [
+ {
+ test: /\.ts$/,
+ loader: "ts-loader",
+ options: {
+ configFile: "tsconfig.json"
+ }
+ },
+ {
+ test: /\.html$/,
+ loader: path.resolve(CONFIG_DIR, "webpack/loader/to-string-loader.js")
+ }
+ ]
+ },
+ optimization: {
+ minimize: process.env.NODE_ENV === "production",
+ runtimeChunk: false
+ },
+ output: {
+ iife: true
+ },
+ plugins: [
+ new webpack.optimize.LimitChunkCountPlugin({
+ maxChunks: 1
+ })
+ ]
+};
+
+const sharedModuleOptions = {
+ externals: sharedModuleExternals,
+ externalsType: "var",
+ module: {
+ rules: [
+ {
+ test: /banglar-bhumi-utils\/src\/.*.(^.?|\.[^d]|[^.]d|[^.][^d])\.(t|j)s$/,
+ loader: path.resolve(CONFIG_DIR, "webpack/loader/count-imports-loader.js"),
+ options: {
+ sharedModulesImportedCount
+ },
+ enforce: "post"
+ }
+ ]
+ }
+};
+
+const backgroundScriptConfiguration = merge(
+ commonOptions,
+ sharedModuleOptions,
+ {
+ entry: backgroundScriptEntries
+ }
+);
+
+const uninjectedScriptConfiguration = merge(
+ commonOptions,
+ sharedModuleOptions,
+ {
+ entry: uninjectedScriptEntries
+ }
+);
+
+const injectedScriptConfiguration = merge(
+ commonOptions,
+ {
+ externals: sharedModuleExternals,
+ externalsType: "var",
+ module: {
+ rules: [
+ {
+ test: /banglar-bhumi-utils\/src\/.*.(^.?|\.[^d]|[^.]d|[^.][^d])\.(t|j)s$/,
+ loader: path.resolve(CONFIG_DIR, "webpack/loader/count-imports-loader.js"),
+ options: {
+ sharedModulesImportedCount: injectedSharedModulesImportedCount
+ },
+ enforce: "post"
+ }
+ ]
+ },
+ entry: injectedAfterScriptEntries,
+ plugins: [
+ new InjectScriptPlugin()
+ ]
+ }
+);
+
+const sortedSharedModules = [];
+
+const sharedModulesConfiguration = merge(
+ commonOptions,
+ sharedModuleOptions,
+ {
+ entry: sharedModuleEntries,
+ plugins: [
+ new CopyPlugin({
+ patterns: [
+ {
+ from: path.resolve("static"),
+ to: "./"
+ },
+ {
+ from: path.resolve("src/offscreen"),
+ to: "./offscreen"
+ }
+ ]
+ }),
+ new CreateInjectedSharedModulesPlugin({
+ injectedSharedModulesImportedCount,
+ sortedSharedModules
+ }),
+ new CreateRulesPlugin(),
+ new CreateManifestPlugin({
+ sharedModulesImportedCount,
+ injectedSharedModulesImportedCount,
+ sortedSharedModules
+ })
+ ],
+ module: {
+ rules: [
+ {
+ test: /banglar-bhumi-utils\/src\/.*.(^.?|\.[^d]|[^.]d|[^.][^d])\.(t|j)s$/,
+ loader: path.resolve(CONFIG_DIR, "webpack/loader/arrange-shared-module-loader.js"),
+ options: {
+ sortedSharedModules
+ },
+ enforce: "post"
+ }
+ ]
+ }
+ }
+);
+
+export default [
+ backgroundScriptConfiguration,
+ uninjectedScriptConfiguration,
+ injectedScriptConfiguration,
+ sharedModulesConfiguration
+];