एक esbuild build को obfuscate करें

@afterpack/esbuild build.onEnd में hook होता है और emit हुए output को उसी जगह obfuscate करता है।

@afterpack/esbuild एक सामान्य esbuild plugin है ({ name, setup(build) })। यह build.onEnd में hook होता है, जो तब चलता है जब esbuild output को disk पर लिखना पूरा कर लेता है (write !== false, जो डिफ़ॉल्ट है)।

यह दोनों तरह के output संभालता है: outdir (कई फ़ाइलें) और outfile (एक फ़ाइल)। जो build पहले ही error दे चुकी हो, उसे यह छोड़ देता है।

Install

$ npm install -D @afterpack/esbuild
// build.mjs
import { build } from "esbuild";
import { afterpackEsbuild } from "@afterpack/esbuild";

await build({
  entryPoints: ["src/main.js"],
  bundle: true,
  format: "esm",
  outfile: "dist/app.js",
  plugins: [afterpackEsbuild()],
});

Named export afterpackEsbuild है।

Build

Plugin build.onEnd पर चलता है, esbuild के output को disk पर लिख लेने के बाद, outdir और outfile दोनों के लिए। ऐसा कोई अलग dev command नहीं है जिसे यह छोड़े: फ़ाइलें लिखने वाली हर build() call plugin को चलाती है।

esbuild pipeline के अंदर कोई hook नहीं देता, इसलिए pass पूरा होने तक आपका unobfuscated bundle disk पर रहता है, जिसमें डिफ़ॉल्ट preset पर 185 KB bundle के लिए लगभग एक चौथाई सेकंड लगता है, और उस दौरान जो कुछ भी output directory पढ़ सकता है, वह इसे पढ़ सकता है। Obfuscation विफल होने पर वह output अपनी जगह रहता है: build विफल होती है, इसलिए कुछ ship नहीं होता, लेकिन फ़ाइलें तब तक रहती हैं जब तक अगली build उन्हें overwrite न कर दे।

Verify

Protection Map डिफ़ॉल्ट रूप से तब लिखा जाता है जब esbuild source map emit करे और build CI (CI=true या CI=1) में न चल रही हो; production mode इसे बंद नहीं करता। जब तक आप sourcemap सेट न करें, esbuild कोई source map emit नहीं करता, इसलिए map डिफ़ॉल्ट रूप से बंद रहता है। इसे स्पष्ट रूप से माँगें:

afterpackEsbuild({ protectionMap: { enabled: true } });

यह gitignored .afterpack/protectionMap.html में लिखा जाता है। sourcemap: true के बिना plugin चेतावनी देता है कि उसे कोई bundler map नहीं मिला जिससे मूल source render किया जा सके। इस रिपोर्ट में आपका पूरा source होता है। इसे कभी commit या serve न करें।

Options

हर configuration key यहाँ options object के रूप में दी जा सकती है, उदाहरण के लिए afterpackEsbuild({ preset: "hard", complexity: 40 })।

Directives

Directives bundler के source map से recover किए जाते हैं, इसलिए अगर आप उनका उपयोग करते हैं तो sourcemap: true के साथ build करें। देखें Directives।

Edge cases

  • Fail-closed। एक विफल फ़ाइल या खाली output build को reject कर देता है।
  • write: false। Disk पर कुछ नहीं होता, इसलिए plugin कुछ नहीं करता। AfterPack को लिखी हुई फ़ाइलें चाहिए।
  • TypeScript। AfterPack के चलने तक esbuild types हटा चुका होता है; maps chain होकर आपकी .ts लाइनों तक वापस पहुँचते हैं।

आगे

  • Frameworks: पूरी तालिका।
  • Vite: reference integration और options का पूरा अर्थ।
  • Builds & CI: seeds, dev बनाम prod, वही bytes promote करना।
  • Protection Map: रिपोर्ट पढ़ना।
  • Directives: हर marker key, और वह क्या करती है।
  • Configuration: engine की config surface।