# Angular app को obfuscate करें

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

Source: https://www.afterpack.dev/hi/docs/frameworks/angular

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

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

## Install

```bash
npm install -D @afterpack/angular
```

```js
// scripts/obfuscate.mjs — run after `ng build`
import { afterpackAngular } from "@afterpack/angular";

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

या इसके बजाय [CLI](https://www.afterpack.dev/hi/docs/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 करें:

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

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

Helper हर content-hashed फ़ाइल का नाम भी बदलता है ताकि उसका नाम [उसके obfuscated bytes के साथ चले](https://www.afterpack.dev/hi/docs/builds#file-names-and-caching), और उन hashes को फिर से compute करता है जो Angular ने unobfuscated फ़ाइलों के लिए लिखे थे: `subresourceIntegrity` option से बने `integrity` attributes और service worker की `ngsw.json` hash table। [CLI](https://www.afterpack.dev/hi/docs/cli#content-hashed-file-names) को `dist/<app>/browser/` पर चलाने पर वह भी ये दोनों काम करता है। जिस SSR build का `angular-app-manifest.mjs` asset hashes embed करता है, वह pass को विफल कर देता है, और CLI भी उसे अस्वीकार करता है।

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

[Fail-closed](https://www.afterpack.dev/hi/docs/diagnostics#fail-closed-no-exceptions): अगर browser directory में कोई `.js`/`.mjs`/`.cjs` नहीं है, या engine कोई failing [diagnostic](https://www.afterpack.dev/hi/docs/diagnostics) रिपोर्ट करता है, तो `afterpackAngular` throw करता है।

## Verify

जिस build को आप जाँचना चाहते हैं उसके लिए `angular.json` में Angular का अपना `sourceMap` build option चालू करें, ताकि [Protection Map](https://www.afterpack.dev/hi/docs/protection-map) आपका मूल source render कर सके। यह gitignored `.afterpack/protectionMap.html` में लिखा जाता है। इसमें आपका पूरा source होता है। इसे कभी commit या serve न करें।

CLI और helper दोनों Protection Map डिफ़ॉल्ट रूप से केवल तब लिखते हैं जब source maps मौजूद हों और build CI (`CI=true` या `CI=1`) में न चल रही हो; [production](https://www.afterpack.dev/hi/docs/config#build-mode) 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](https://www.afterpack.dev/hi/docs/config) यहाँ options object के रूप में pass की जा सकती है, उदाहरण के लिए `afterpackAngular({ preset: "hard", complexity: 40 })`। ये options केवल इसी package में हैं, build output खोजने के लिए:

| Option | Type | Default |
|---|---|---|
| `cwd` | `string` | `process.cwd()`; project root, जहाँ से `afterpack.json` की खोज और `distRoot` शुरू होते हैं |
| `distRoot` | `string` | `<cwd>/dist`; जहाँ `browser` subdirectory खोजनी है |
| `browserDir` | `string` | unset। 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`](https://www.afterpack.dev/hi/docs/config#regions) फिर भी काम करते हैं, क्योंकि वे comments के बजाय byte ranges बताते हैं।

## Edge cases

**Legacy Angular (webpack)।** जो projects अभी भी पुराने webpack-आधारित builder पर हैं, वे एक custom builder के ज़रिए [`@afterpack/webpack`](https://www.afterpack.dev/hi/docs/frameworks/webpack) से build के भीतर ही obfuscate कर सकते हैं। ऊपर का postbuild तरीका दोनों builders पर एक समान काम करता है और यही अनुशंसित है।

## आगे

- [Frameworks](https://www.afterpack.dev/hi/docs/frameworks): पूरी matrix।
- [CLI reference](https://www.afterpack.dev/hi/docs/cli): ऊपर इस्तेमाल हुए flags।
- [Builds & CI](https://www.afterpack.dev/hi/docs/builds): seeds, dev-बनाम-prod, वही bytes promote करना।
- [Protection Map](https://www.afterpack.dev/hi/docs/protection-map): रिपोर्ट पढ़ना।
- [Configuration](https://www.afterpack.dev/hi/docs/config): engine की config surface।
- [Diagnostics](https://www.afterpack.dev/hi/docs/diagnostics#exit-codes): failing pass क्या लौटाता है।
