@afterpack/rollup 与 @afterpack/vite 镜像:Rollup 正是 Vite 构建所依托的基础,因此同样的做法在这里也适用。它从你的源代码中读取指令,然后在 generateBundle 中运行引擎,此时完整的打包产物就在内存里,而 Rollup 还没有写入其中任何一部分。
安装
$ 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()],
};具名导出是 afterpackRollup。
构建
该插件以 order: "post" 运行在 generateBundle 中,因此它是最后一个接触打包产物的钩子。它会混淆打包产物中持有的每一个 JavaScript chunk 并交还回去,因此 Rollup 写入的是混淆后的 chunk,而绝不会写入原始内容。一次失败的混淆会让输出目录保持原样。
验证
在生产构建中显式请求 Protection Map:
afterpackRollup({ protectionMap: { enabled: true } });它会落在已被 gitignore 的 .afterpack/protectionMap.html 中。开启 output.sourcemap 时,它会渲染出你的原始源码;如果没有,就没有可渲染的内容,报告会说明这一点。报告包含你的完整源码。绝不要提交它或对外提供服务。
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.选项
每一个配置键都可以作为选项对象在这里传入,例如 afterpackRollup({ preset: "hard", complexity: 40 })。
指令
插件会在压缩之前从你的源代码中读取指令,因此指令能在打包过程中存活下来。
/* @afterpack preset=hard */
export function signRequest(payload) {
// ...
}
/* @afterpack end */捕获会跳过 node_modules、虚拟模块和非 JS/TS 文件。语法在各处都是一样的。
边界情况
多个输出
一个配置了两个输出的构建会对每个输出各运行一次 generateBundle,每次运行只能看到自己的打包产物。无论输出写到哪个目录,都不会有任何内容被混淆两次:
output: [
{ dir: "dist/esm", format: "es", entryFileNames: "lib.js" },
{ dir: "dist/cjs", format: "cjs", entryFileNames: "lib.cjs" },
],
plugins: [afterpackRollup({ seed: "git" })],对一起发布的多个输出固定同一个 seed。
库构建
AfterPack 运行在 Rollup 已经构建好的打包产物之上,因此你的使用者导入的每一个导出名称都会按原样保留;只有内部实现会被重命名和重构。