diff options
| author | Arpit Chakladar <54011232+arpitchakladar@users.noreply.github.com> | 2023-02-05 22:57:54 +0530 |
|---|---|---|
| committer | Arpit Chakladar <54011232+arpitchakladar@users.noreply.github.com> | 2023-02-05 22:57:54 +0530 |
| commit | 1a301791bb621fa01fa76e9403b23fe1f4a120af (patch) | |
| tree | ebfff3e1b7c366c738750644f4fdefaa4fef21b7 /config | |
| parent | c690f47a786eef27900873ac9fe75134995f156a (diff) | |
| download | banglar-bhumi-utils-1a301791bb621fa01fa76e9403b23fe1f4a120af.tar.gz banglar-bhumi-utils-1a301791bb621fa01fa76e9403b23fe1f4a120af.zip | |
Added a more extensive way to automate script development.
Diffstat (limited to 'config')
| -rw-r--r-- | config/tsconfig.json | 22 | ||||
| -rw-r--r-- | config/webpack.config.js | 71 | ||||
| -rw-r--r-- | config/webpack/plugins/create-manifest-webpack-plugin/index.js | 52 | ||||
| -rw-r--r-- | config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json | 9 | ||||
| -rw-r--r-- | config/webpack/plugins/inject-script-webpack-plugin.js | 55 |
5 files changed, 209 insertions, 0 deletions
diff --git a/config/tsconfig.json b/config/tsconfig.json new file mode 100644 index 0000000..081a105 --- /dev/null +++ b/config/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "outDir": "dist", + "sourceMap": true, + "strict": true, + "noImplicitReturns": true, + "noImplicitAny": true, + "module": "es6", + "moduleResolution": "node", + "target": "es2021", + "allowJs": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true, + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } + }, + "exclude": [ + "./node_modules/**/*" + ] +} diff --git a/config/webpack.config.js b/config/webpack.config.js new file mode 100644 index 0000000..1796aa8 --- /dev/null +++ b/config/webpack.config.js @@ -0,0 +1,71 @@ +const fs = require("fs"); +const path = require("path"); +const CopyPlugin = require("copy-webpack-plugin"); + +process.env.ROOT_DIR = path.resolve(__dirname, ".."); +process.env.SOURCE_DIR = path.resolve(process.env.ROOT_DIR, "src"); +process.env.STATIC_DIR = path.resolve(process.env.ROOT_DIR, "static"); + +const InjectScriptPlugin = require("./webpack/plugins/inject-script-webpack-plugin"); +const CreateManifestPlugin = require("./webpack/plugins/create-manifest-webpack-plugin"); + +const manifest = require(path.resolve(process.env.SOURCE_DIR, "manifest.json")); + +const generateScriptBuildConfig = (script, scriptType) => { + const scriptName = script.substring(0, script.length - 3); + let entry = path.resolve(process.env.SOURCE_DIR, `scripts/${scriptName}.ts`); + if (!fs.existsSync(entry)) { + entry = path.resolve(process.env.SOURCE_DIR, `scripts/${scriptName}/index.ts`); + if (!fs.existsSync(entry)) { + entry = path.resolve(process.env.SOURCE_DIR, `scripts/${scriptName}.js`); + } + } + + return { + entry, + mode: "production", + output: { + filename: `${scriptName}.js` + }, + resolve: { + extensions: ["", ".ts", ".js"], + alias: { + "@": process.env.SOURCE_DIR + } + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: "ts-loader", + options: { + configFile: "config/tsconfig.json" + } + } + ] + }, + plugins: scriptType.startsWith("injected") + ? [new InjectScriptPlugin({ onload: scriptType === "injected_and_loaded" })] + : undefined + }; +}; + +let scripts = []; + +for (const scriptType in manifest) { + for (const scriptName in manifest[scriptType]) { + scripts.push(generateScriptBuildConfig(scriptName, scriptType)); + } +} + +scripts[scripts.length - 1].plugins = (scripts[scripts.length - 1].plugins || []).concat([ + new CopyPlugin({ + patterns: [{ + from: process.env.STATIC_DIR, + to: "./" + }] + }), + new CreateManifestPlugin(manifest) +]); + +module.exports = scripts; diff --git a/config/webpack/plugins/create-manifest-webpack-plugin/index.js b/config/webpack/plugins/create-manifest-webpack-plugin/index.js new file mode 100644 index 0000000..2ab2721 --- /dev/null +++ b/config/webpack/plugins/create-manifest-webpack-plugin/index.js @@ -0,0 +1,52 @@ +const path = require("path"); + +const { version } = require(path.resolve(process.env.ROOT_DIR, "package.json")); + +const scriptTypeRunAtMap = { + injected: "document_start", + rendered: "document_end", + loaded: "document_idle" +}; + +class CreateManifestPlugin { + constructor(scripts) { + this.scripts = scripts; + this.manifest = require("./manifest-template.json"); + this.scripts.injected = this.scripts.injected + ? { ...this.scripts.injected, ...(this.scripts.injected_and_loaded || {}) } + : this.scripts.injected_and_loaded; + this.scripts.injected_and_loaded = undefined; + } + + apply(compiler) { + compiler.hooks.compilation.tap("CreateManifestPlugin", compilation => { + compilation.hooks.processAssets.tap( + { + name: "CreateManifestPlugin", + stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE, + additionalAssets: true + }, + assets => { + this.manifest.version = version; + this.manifest.content_scripts = [] + + for (const scriptType in scriptTypeRunAtMap) { + if (this.scripts[scriptType]) { + this.manifest.content_scripts.push({ + matches: ["https://banglarbhumi.gov.in/*", "http://banglarbhumi.gov.in/*"], + js: Object.keys(this.scripts[scriptType]), + run_at: scriptTypeRunAtMap[scriptType] + }); + } + } + + const encoder = new TextEncoder("UTF-8"); + const { RawSource } = compiler.webpack.sources; + assets["manifest.json"] = new RawSource(Buffer.from(encoder.encode(JSON.stringify(this.manifest).buffer))); + } + ); + }); + } +} + +module.exports = CreateManifestPlugin; diff --git a/config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json b/config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json new file mode 100644 index 0000000..0c59ef2 --- /dev/null +++ b/config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json @@ -0,0 +1,9 @@ +{ + "manifest_version": 3, + "name": "Banglar Bhumi Utils", + "permissions": ["scripting"], + "description": "A chrome extension to improve functionality of the banglarbhumi.gov.in website.", + "icons": { + "512": "icon512.png" + } +} diff --git a/config/webpack/plugins/inject-script-webpack-plugin.js b/config/webpack/plugins/inject-script-webpack-plugin.js new file mode 100644 index 0000000..63bab27 --- /dev/null +++ b/config/webpack/plugins/inject-script-webpack-plugin.js @@ -0,0 +1,55 @@ +const terser = require("terser"); + +let count = 0; + +class InjectScriptPlugin { + constructor({ onload }) { + this.onload = !!onload; + } + + apply(compiler) { + compiler.hooks.compilation.tap("InjectScriptPlugin", compilation => { + compilation.hooks.processAssets.tapPromise( + { + name: "InjectScriptPlugin", + stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE, + additionalAssets: true + }, + async assets => { + for (const assetName in assets) { + if (assetName.endsWith(".js")) { + const asset = assets[assetName]; + let content = asset._source._children; + let x = 2; + for (let i = 0; i < content.length; i++) { + if (typeof content[i] === "string" && content[i].indexOf("__webpack_exports__") >= 0) { + x = i; + break; + } + } + content[x] += ` + const observer = new MutationObserver(mutations => { + const script = document.querySelector("head > script:nth-child(54)"); + if (script) { + ` + if (count > 0) { + content[x] += "script.innerHTML += `"; + } else { + content[x] += "script.innerHTML = `"; + } + if (this.onload) { + content[x] += "document.addEventListener(\"DOMContentLoaded\", () => {"; + content[content.length - 3] += "});"; + } + content[content.length - 3] += "`;observer.disconnect();}});observer.observe(document, {childList: true, subtree: true});"; + content[x + 1] = (await terser.minify(content[x + 1]._source._source._valueAsString.replaceAll("`", "\\`"))).code; + count++; + } + } + } + ); + }); + } +} + +module.exports = InjectScriptPlugin; |
