Angular app को obfuscate करें

Angular v17+ का obfuscation dist/<app>/browser पर एक postbuild pass है: CLI से, या @afterpack/angular helper से।

आधुनिक Angular (v17+) @angular-devkit/build-angular:application से build होता है। वह builder esbuild पर आधारित है लेकिन कोई plugin hook नहीं देता, इसलिए Vite, webpack और esbuild plugins के विपरीत, AfterPack यहाँ build में hook नहीं कर सकता।

Integration emit किए गए browser bundle पर एक postbuild pass है। @afterpack/angular उस pass के ऊपर एक सुविधाजनक wrapper है। यह builder plugin नहीं है।

Install

$ npm install -D @afterpack/angular
// scripts/obfuscate.mjs — run after `ng build`
import { afterpackAngular } from "@afterpack/angular";

await afterpackAngular({ seed: "git" });

या इसके बजाय CLI सीधे चलाएँ, कुछ भी install किए बिना।

Build

Application builder client bundle को dist/<app>/browser में लिखता है।

Helper के साथ, findAngularBrowserDir(distRoot) browser output खोजता है। Monorepo में browserDir pass करें। अगर आपको केवल locator चाहिए, तो findAngularBrowserDir अलग से भी export किया गया है।

CLI के साथ, उसे सीधे browser output पर point करें:

// package.json
{
  "scripts": {
    "build": "ng build && afterpack dist/my-app/browser --seed=git"
  }
}

CLI को इस पर point करें और emit किया गया हर .js chunk उसी जगह obfuscate हो जाता है। CLI का backup project root पर .afterpack/backup/ में जाता है, dist/ के बाहर, इसलिए वह deploy के साथ ship नहीं होता; npx afterpack@latest restore run को undo कर देता है। ध्यान देने वाला मामला @afterpack/angular helper है: वहाँ build: { backup: true } dist/ में एक .backup.<hash> sibling लिखता है, जो आपके deploy किए जाने वाले tree के अंदर आपका मूल source है।

Pass चलने से पहले ही builder bundle लिख देता है, इसलिए pass पूरा होने तक आपका unobfuscated bundle disk पर रहता है, और उस दौरान dist/ पढ़ सकने वाली कोई भी चीज़ उसे पढ़ सकती है। Failed pass वह output वहीं छोड़ देता है: build fail होती है, इसलिए कुछ ship नहीं होता, लेकिन फ़ाइलें अगली build के overwrite करने तक बनी रहती हैं।

Fail-closed: अगर browser directory में कोई .js/.mjs/.cjs नहीं है, या engine कोई failing diagnostic रिपोर्ट करता है, तो afterpackAngular throw करता है।

Verify

जिस build को आप जाँचना चाहते हैं उसके लिए angular.json में Angular का अपना sourceMap build option चालू करें, ताकि Protection Map आपका मूल source render कर सके। यह gitignored .afterpack/protectionMap.html में लिखा जाता है। इसमें आपका पूरा source होता है। इसे कभी commit या serve न करें।

CLI और helper दोनों Protection Map डिफ़ॉल्ट रूप से केवल तब लिखते हैं जब source maps मौजूद हों और build CI (CI=true या CI=1) में न चल रही हो; production mode इसे बंद नहीं करता। ng build अपनी production configuration में कोई source maps emit नहीं करता, इसलिए वहाँ map डिफ़ॉल्ट रूप से बंद रहता है। protectionMap: { enabled: true } इसे ज़बरदस्ती चालू करता है।

Source maps को कभी अपने CDN पर ship न करें

Production source map आपके मूल source तक पहुँचता है। इसे build के लिए generate करें, फिर इसे अपने deploy किए गए dist/ से बाहर रखें।

Options

हर configuration key यहाँ options object के रूप में pass की जा सकती है, उदाहरण के लिए afterpackAngular({ preset: "hard", complexity: 40 })। ये options केवल इसी package में हैं, build output खोजने के लिए:

OptionTypeDefault
cwdstringprocess.cwd(); वह project root जिसमें .gitignore और .afterpack/ हैं
distRootstring<cwd>/dist; जहाँ browser subdirectory खोजनी है
browserDirstringunset। Auto-location को पूरी तरह छोड़ देता है

यहाँ कोई build.autorun option नहीं है।

Directives

directives.enabled यहाँ हर layer में अस्वीकार है — options object, AFTERPACK_directives_enabled और afterpack.json, सभी में। Angular का application builder sealed है, इसलिए यह pass हमेशा पहले से minified output ही देखता है और उसके पास /* @afterpack ... */ comments पकड़ने के लिए कोई hook नहीं है। इसे सेट करने पर build चुपचाप ignore होने के बजाय fail हो जाती है। हाथ से लिखे regions फिर भी काम करते हैं, क्योंकि वे comments के बजाय byte ranges बताते हैं।

Edge cases

Legacy Angular (webpack)। जो projects अभी भी पुराने webpack-आधारित builder पर हैं, वे एक custom builder के ज़रिए @afterpack/webpack से build के भीतर ही obfuscate कर सकते हैं। ऊपर का postbuild तरीका दोनों builders पर एक समान काम करता है और यही अनुशंसित है।

आगे

  • Frameworks: पूरी matrix।
  • CLI reference: ऊपर इस्तेमाल हुए flags।
  • Builds & CI: seeds, dev-बनाम-prod, वही bytes promote करना।
  • Protection Map: रिपोर्ट पढ़ना।
  • Configuration: engine की config surface।
  • Diagnostics: failing pass क्या लौटाता है।