# Parcel build को obfuscate करें

@afterpack/parcel-optimizer, Parcel 2 Optimizer के रूप में हर packaged bundle को memory में obfuscate करता है, और production में 404 देने वाला chunk ship करने के बजाय build को fail closed करता है।

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

`@afterpack/parcel-optimizer` एक Parcel 2 **Optimizer** है, जो `.parcelrc` में register होता है। यह हर packaged bundle को Parcel के अपने optimize phase के दौरान **memory में** obfuscate करता है, इसलिए bundle कभी cleartext में disk को नहीं छूता।

> **@afterpack/parcel नहीं**
>
> Package का नाम `@afterpack/parcel-optimizer` है।

## Install

```bash
npm install -D @afterpack/parcel-optimizer
```

```jsonc
// .parcelrc
{
  "extends": "@parcel/config-default",
  "optimizers": {
    "*.{js,mjs,cjs}": ["...", "@afterpack/parcel-optimizer"]
  }
}
```

`"..."` spread ज़रूरी है: यह Parcel के default optimizers (`@parcel/optimizer-swc`) को बनाए रखता है और AfterPack को **आख़िर में** रखता है। AfterPack minification के बाद चलता है। Peer dependency: Parcel `>=2.9.0`।

## Build

`.parcelrc` entries बिना inline options वाले सादे package names होती हैं, इसलिए options आपके project root के `afterpack.json` से आते हैं, वह एक config फ़ाइल जिसे हर AfterPack integration पढ़ता है:

```json
{
  "seed": "git",
  "preset": "medium"
}
```

केवल project-root में artifacts बनते हैं; आपके bundles के बगल में कुछ नहीं जाता:

- **हर bundle का एक [`protectionMap.html`](https://www.afterpack.dev/hi/docs/protection-map)**, `.afterpack/<bundle>.<id>.protectionMap.html` पर।
- एक source map, जब [sourceMap policy](https://www.afterpack.dev/hi/docs/config#sourceMap-enabled) उसे चालू करती है। इसे सीधे लिखने के बजाय Parcel को लौटाया जाता है, इसलिए Parcel इसे अपने content hash के साथ नाम देता है और emit करता है।

`.afterpack/` की अपनी `.gitignore` होती है; plugin आपके project की `.gitignore` में कभी बदलाव नहीं करता।

## Verify

चूँकि कोई संयुक्त रिपोर्ट नहीं है, जिस bundle की आपको परवाह है उसे सीधे जाँचें: Parcel द्वारा package की गई हर entry या lazy chunk के लिए `.afterpack/<bundle-name>.<id>.protectionMap.html`। [Production में maps बंद रहते हैं](https://www.afterpack.dev/hi/docs/config#sourceMap-enabled) डिफ़ॉल्ट रूप से; override करने के लिए `afterpack.json` में `"sourceMap": { "enabled": true }` सेट करें। हर रिपोर्ट में आपका पूरा source होता है। इसे कभी commit या serve न करें।

किसी deploy को जाँचने के लिए, plugin का reporter build command में जोड़ें। तब हर build आपके [project root](https://www.afterpack.dev/hi/docs/cli#files) में `.afterpack/receipts/` में एक protection receipt लिखता है, हर target output directory के लिए एक (`dist` के लिए `.afterpack/receipts/dist.json`)। [`afterpack verify`](https://www.afterpack.dev/hi/docs/cli#afterpack-verify-dir) तब fail होता है जब कोई फ़ाइल obfuscate होने के बाद बदली गई हो, या जब कोई receipt न हो:

```bash
parcel build index.html --reporter @afterpack/parcel-optimizer/reporter
npx afterpack@latest verify dist
```

## Options

हर [configuration key](https://www.afterpack.dev/hi/docs/config) वहाँ सेट की जा सकती है, उदाहरण के लिए `{ "preset": "hard", "complexity": 40 }`। [`protectionMap.enabled`](https://www.afterpack.dev/hi/docs/config#protectionMap-enabled) [build mode](https://www.afterpack.dev/hi/docs/config#build-mode) के बजाय इस पर निर्भर करता है कि bundle में source map है या नहीं, और यह हमेशा gitignored `.afterpack/` में जाता है। इस plugin पर कोई `build.backup` option नहीं है। इसे सेट करने पर warning मिलती है। स्पष्ट options हमेशा production defaults पर भारी पड़ते हैं।

## Directives

Plugin directives को आपके source से पढ़ता है। कोई इस्तेमाल योग्य source map न हो, तो pass के पास recover करने को कुछ नहीं होता और वह यह बता देता है।

**आपके entry module में directive recover नहीं होता।** Pass `DIAG_DIRECTIVE_SOURCE_UNRESOLVED` रिपोर्ट करता है और module का नाम बताता है। बाकी हर non-entry module में directives source maps चालू होने पर सामान्य रूप से काम करते हैं। अगर आपको entry-module directive चाहिए, तो सुरक्षित किए जाने वाले code को किसी imported module में ले जाएँ।

## Edge cases

### Content-hash placeholders आपकी build को विफल कर सकते हैं

Content hashing चालू होने पर (`parcel build` का डिफ़ॉल्ट) और native ESM के बिना वाले target के साथ, Parcel के content-hash placeholders obfuscated strings के भीतर पहुँच जाते हैं, और हर code-split chunk production में 404 देता है।

यह plugin इस टकराव को पहचानता है और उसे ship करने के बजाय build को विफल कर देता है:

```
AfterPack obfuscated 1 Parcel content-hash placeholder(s) in app.[hash].js (HASH_REF_...).
  hint: Run `parcel build --no-content-hash` (chunk URLs stop being content-addressed).
  hint: Or set "complexity": 0 in afterpack.json to ship minify-only.
```

Parcel का default ESM output इससे अप्रभावित है।

### जानने योग्य बातें

- **हर bundle के लिए एक pass, worker processes में।** Parcel optimizers को प्रति bundle चलाता है, और अलग-अलग worker processes में package हुए bundles state साझा नहीं कर सकते। एक ही process में package हुए bundles एक seed साझा करते हैं। हर worker में एक ही seed pin करने के लिए, [`seed`](https://www.afterpack.dev/hi/docs/config#seed) स्पष्ट रूप से सेट करें या `AFTERPACK_seed` export करें।
- **Parcel optimizer output को cache करता है।** Warm `.parcel-cache` और बिना बदले input वाला rebuild AfterPack को दोबारा नहीं चलाता, और unpinned seed को rotate नहीं करता। नए pass के लिए `.parcel-cache` साफ़ करें; CI builds वैसे भी cold cache से होती हैं।
- **दो हानिरहित warnings।** Parcel `ES module dependencies are experimental` छापता है (हर AfterPack package ESM है) और बताता है कि plugin `contains non-statically analyzable dependencies` (native engine का runtime binary resolution)। इनमें से कोई भी build को प्रभावित नहीं करता।

### Plugin के बिना: CLI

Parcel से हमेशा की तरह build करें, फिर AfterPack को output पर चलाएँ:

```bash
npx parcel build
```

```bash
npx afterpack@latest dist/ --preset=medium --seed=git
```

[Path argument](https://www.afterpack.dev/hi/docs/cli#usage) न दें, तो CLI `dist/` पहचान लेता है, जो Parcel का default output है; आपकी directory अलग हो तो उसका नाम दें। AfterPack directory में चलता है, हर `.js`/`.mjs`/`.cjs` इकट्ठा करता है और उन्हें [उसी जगह](https://www.afterpack.dev/hi/docs/cli#what-a-run-does) obfuscate करता है। CLI run को कोई content-hash guard नहीं मिलता, और हर bundle के एक के बजाय पूरी directory के लिए एक संयुक्त [`protectionMap.html`](https://www.afterpack.dev/hi/docs/protection-map) मिलता है। [Fail-closed](https://www.afterpack.dev/hi/docs/diagnostics#fail-closed-no-exceptions) फिर भी लागू रहता है: मौजूद न होने वाली build dir, कोई JS फ़ाइल न होना, एक `error`/`critical` [diagnostic](https://www.afterpack.dev/hi/docs/diagnostics), या ऐसी फ़ाइल जिसे engine obfuscate नहीं कर सका, सभी `1` के साथ exit करते हैं।

## आगे

- [Frameworks](https://www.afterpack.dev/hi/docs/frameworks): पूरी matrix।
- [esbuild](https://www.afterpack.dev/hi/docs/frameworks/esbuild#directives): एक और plugin जो minification के बाद source map से directives recover करता है।
- [CLI reference](https://www.afterpack.dev/hi/docs/cli): fallback रास्ते के 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): हर option, और कौन-सी surface उसे सेट कर सकती है।
- [Presets](https://www.afterpack.dev/hi/docs/presets): पाँच पायदानों वाली सीढ़ी।
