Rollup build को obfuscate करें

@afterpack/rollup आपके source से directives पढ़ता है और Rollup के output लिखने से पहले generateBundle में engine चलाता है।

@afterpack/rollup, @afterpack/vite का ही प्रतिरूप है: Vite, Rollup पर बना है, इसलिए वही तरीका यहाँ लागू होता है। यह आपके source से directives पढ़ता है, फिर generateBundle में engine चलाता है, जब तैयार bundle memory में होता है और Rollup उसका कोई हिस्सा लिख चुका नहीं होता।

Install

$ npm install -D @afterpack/rollup
// rollup.config.mjs
import { afterpackRollup } from "@afterpack/rollup";

export default {
  input: "src/index.js",
  output: { dir: "dist", format: "es", sourcemap: true },
  plugins: [afterpackRollup()],
};

Named export afterpackRollup है।

Build

Plugin generateBundle में order: "post" के साथ चलता है, इसलिए bundle को छूने वाला यह आख़िरी hook है। यह bundle के हर JavaScript chunk को obfuscate करता है और उन्हें वापस सौंप देता है, इसलिए Rollup obfuscated chunks लिखता है, मूल कभी नहीं। विफल obfuscation output directory को वैसा ही छोड़ देता है जैसी वह थी।

हर chunk का नाम उसके obfuscated bytes के साथ चलता है, और bundle में मौजूद precompressed .gz और .br copies obfuscated bytes से फिर से बनाई जाती हैं।

Verify

Production build पर Protection Map स्पष्ट रूप से माँगें:

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

यह gitignored .afterpack/protectionMap.html में जाता है। output.sourcemap चालू होने पर यह आपका मूल source render करता है; उसके बिना render करने के लिए कुछ नहीं होता और pass यह बता देता है। रिपोर्ट में आपका पूरा source होता है। इसे कभी commit या serve न करें।

entitlements.jslight · complexity 5Open full size
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.

Options

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

Directives

Plugin directives को minification से पहले आपके source से पढ़ता है, इसलिए एक directive bundling के बाद भी बचा रहता है।

/* @afterpack preset=hard */
export function signRequest(payload) {
  // ...
}
/* @afterpack end */

Capture node_modules, virtual modules और non-JS/TS फ़ाइलों को छोड़ देता है। Grammar हर जगह एक जैसी है।

Edge cases

कई outputs

दो outputs वाली config हर output के लिए एक बार generateBundle चलाती है, और हर run केवल अपना bundle देखता है। Outputs चाहे जिन directories में लिखें, कुछ भी दो बार obfuscate नहीं होता:

output: [
  { dir: "dist/esm", format: "es", entryFileNames: "lib.js" },
  { dir: "dist/cjs", format: "cjs", entryFileNames: "lib.cjs" },
],
plugins: [afterpackRollup({ seed: "git" })],

साथ ship होने वाले outputs पर एक ही seed pin करें।

Library builds

AfterPack उस bundle पर चलता है जिसे Rollup ने build किया, इसलिए आपके consumers जो भी exported name import करते हैं, वह जैसा लिखा गया था वैसा ही बचा रहता है; केवल internals का नाम बदला जाता है और उन्हें नई संरचना दी जाती है।

आगे

  • Frameworks: पूरी matrix।
  • Vite: वही hooks, Vite के config resolution के साथ।
  • Builds और CI: seeds, dev-बनाम-prod, वही bytes promote करना।
  • Protection Map: रिपोर्ट को पढ़ना।
  • Directives: हर marker key, और वह क्या करती है।
  • Configuration: engine config की surface।