@afterpack/vite reference integration है। Astro, Svelte, SvelteKit, Vue और Nuxt सभी इसे wrap करते हैं, इसलिए यह पेज जो बताता है वह उन packages पर भी लागू होता है।
यह आपके source से @afterpack directives पढ़ता है, फिर engine को generateBundle में चलाता है, जब तैयार bundle memory में होता है और Vite ने उसका कुछ भी नहीं लिखा होता।
Install
$ npm install -D @afterpack/vite// vite.config.ts
import { defineConfig } from "vite";
import { afterpackVite } from "@afterpack/vite";
export default defineConfig({
plugins: [afterpackVite()],
});Build
पूरा setup बस इतना ही है। अब npm run build obfuscated output देता है; vite dev अछूता रहता है, क्योंकि plugin केवल build के generateBundle पर काम करता है। Vite obfuscated chunks लिखता है, मूल कभी नहीं, और विफल obfuscation outDir को वैसा ही छोड़ देता है जैसा वह था।
यह वही obfuscate करता है जो Vite ने build किया: output bundle का हर chunk। जो फ़ाइलें Vite publicDir से output directory में ज्यों की त्यों copy करता है, वे build नहीं होतीं, bundle में नहीं होतीं, और उन्हें छुआ नहीं जाता। जिस भी चीज़ को protection चाहिए, उसे bundler से होकर भेजें।
Plugin ये लिखता है:
protectionMap.html: build का एक संयुक्त map, जो हमेशा आपके project root पर gitignored.afterpack/में लिखा जाता है। इसमें आपका मूल source embedded होता है। इसे कभी किसी serve होने वाली directory में न पहुँचने दें।foo.js.map: source map, जब maps चालू हों। जब maps बंद हों, जो production का डिफ़ॉल्ट है, तो Vite की अपनी map entry obfuscated chunk के बगल में लिखे जाने के बजाय हटा दी जाती है।
यहाँ कोई foo.backup.<hash>.js नहीं है। Obfuscated bytes वापस bundle में जाते हैं, इसलिए कोई emit की हुई फ़ाइल नहीं होती जिसके बगल में backup रखा जाए, और build.backup: true backup लिखने के बजाय चेतावनी देता है।
.afterpack/ की अपनी .gitignore होती है, इसलिए plugin आपकी .gitignore में कभी बदलाव नहीं करता। अगर कोई artifact किसी serve होने वाले path के अंतर्गत पहुँचता है, तो यह चेतावनी देता है।
Verify
Protection Map डिफ़ॉल्ट रूप से तब लिखा जाता है जब Vite source map emit करे और build CI (CI=true या CI=1) में न चल रही हो; production build इसे बंद नहीं करती। जब तक build.sourcemap सेट न हो, Vite कोई source map emit नहीं करता, इसलिए सामान्य build में map डिफ़ॉल्ट रूप से बंद रहता है। जब आप उसे देखना चाहें, तो स्पष्ट रूप से माँगें:
afterpackVite({ protectionMap: { enabled: true } });अगर build.sourcemap सेट नहीं है, तो यह Vite के अपने source maps भी चालू कर देता है, ताकि map आपका मूल source render कर सके। मिलने योग्य map के बिना plugin के पास मूल source render करने का कोई आधार नहीं होता, और वह यह बता देता है।
Report .afterpack/protectionMap.html में लिखी जाती है। इसमें आपका पूरा source होता है। इसे कभी commit या serve न करें, और केवल local रूप से review करें।
entitlements.js, 54 lines, built at the light preset with a directive around the signature check. Click any token to see what was applied to it.एक .map फ़ाइल आपके मूल source तक पहुँचती है। इसे कभी deploy न करें।
Options
हर configuration key यहाँ options object के रूप में दी जा सकती है, उदाहरण के लिए afterpackVite({ preset: "hard", complexity: 40 })। ये सभी वैकल्पिक हैं। Named export afterpackVite है।
preset और complexity अलग-अलग चीज़ें सेट करते हैं। Preset एक bundle है: यह complexity target, कुल output multiplier और inflation budget एक साथ सेट करता है। complexity उस bundle के अंदर की एक संख्या है:
afterpackVite({ preset: "hard", complexity: 40 }); // hard's size limits, target 40Directives
Directives को plugin आपके source से पढ़ता है, इससे पहले कि कोई minifier comments हटा दे। Grammar केवल block comments की है:
/* @afterpack preset=hard */
function verifyLicense(token) {
// ...
}
/* @afterpack end */// @afterpack … line comments scan नहीं होते और उन्हें diagnostics के रूप में report किया जाता है।
Directive जो भी key सेट कर सकता है, वह हर key Directives पेज पर है।
Capture node_modules और non-JS/TS फ़ाइलों को छोड़ देता है। .vue या .svelte single-file component के अंदर का directive capture नहीं होता। इसके बजाय उसे एक सादे .ts/.js module में रखें जिसे component import करता है। Scan को पूरी तरह छोड़ने के लिए directives.enabled: false सेट करें।
Edge cases
Library mode
build.lib output एक public contract है। AfterPack तैयार bundle पर चलता है, इसलिए exported names बने रहते हैं; internals फिर भी rename और restructure होते हैं।
कई outputs
हर Vite build केवल अपना bundle obfuscate करती है और कुछ नहीं, इसलिए अलग-अलग builds अलग passes हैं, भले ही वे एक ही directory में लिखें। अगर वे एक runtime contract साझा करती हैं, तो उन सब पर एक ही seed pin करें।
Content-hashed नाम
हर chunk का नाम उसके obfuscated bytes के साथ चलता है। जो JavaScript फ़ाइल Vite द्वारा build किए गए chunk के बजाय plain asset के रूप में bundle में पहुँचती है, वह वही नाम रखती है जो Vite ने उसके unobfuscated bytes को दिया था, और build चेतावनी देता है: उसे module के रूप में import करें, या उसे long-lived caching के बिना serve करें। Bundle में मौजूद precompressed .gz और .br copies obfuscated bytes से फिर से बनाई जाती हैं, और किसी दूसरे format की precompressed copy build को विफल कर देती है।
Subresource integrity
Subresource integrity hashes compute करने वाला Vite plugin अस्वीकार कर दिया जाता है, क्योंकि उसके integrity attributes obfuscated फ़ाइलों से मेल नहीं खाएँगे। उसे हटाएँ, और build के बाद deploy की गई फ़ाइलों से integrity compute करें।
आगे
- Frameworks: पूरी तालिका।
- Builds & CI: seeds, dev बनाम prod, वही bytes promote करना।
- Protection Map: report पढ़ना।
- Configuration: engine का config surface।
- Directives: हर marker key, और वह क्या करती है।
- Presets: पाँच पायदानों की सीढ़ी।