shieldmycode-webpack-plugin
v0.1.0
Published
Webpack 5 plugin for Shield (shieldmycode.com) — protect your bundle on every npm run build.
Maintainers
Readme
shieldmycode-webpack-plugin
Drop-in Shield protection for Webpack 5. Every
npm run build ships an obfuscated bundle without any manual upload or
post-processing step.
Install
npm install --save-dev shieldmycode-webpack-pluginRequires Webpack 5 and Node 18+.
Authenticate
Create an API key at shield.shieldmycode.com/dashboard/api-keys (Business plan and up), then expose it to your build:
# CI
SHIELD_API_KEY=shield_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx npm run build
# .env (with dotenv-cli or webpack's DefinePlugin)
SHIELD_API_KEY=shield_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxQuick start
// webpack.config.js
const ShieldPlugin = require('shieldmycode-webpack-plugin');
module.exports = {
// ...your existing config...
plugins: [
new ShieldPlugin({
apiKey: process.env.SHIELD_API_KEY,
options: {
level: 'hard',
antiLlm: true,
domainLock: 'mycompany.com,app.mycompany.com'
}
})
]
};That's it. Run npm run build and Webpack will:
- Bundle your code as usual.
- Run the configured minifier (TerserPlugin, etc.).
- Hand each
.js/.htmlasset to Shield. - Replace each asset with its protected output before writing to disk.
The protected bundle is what ends up in dist/. No extra step.
When the plugin runs
Shield hooks into processAssets at stage OPTIMIZE_SIZE + 1. That means:
- Minifiers run first (their output is smaller, so the obfuscator has less to chew on and your output is leaner).
- Shield protects whatever they produced.
- Webpack's normal asset-emit logic writes the protected files.
Source maps (*.map) are excluded by default — there's no value in
obfuscating them, and they'd confuse Webpack's sourcemap-loader.
Configuration
new ShieldPlugin({
// Auth
apiKey?: string; // falls back to $SHIELD_API_KEY
endpoint?: string; // default https://shield.shieldmycode.com
// Engine options (passed verbatim to /api/v1/obfuscate)
options?: {
level?: 'soft' | 'medium' | 'hard'; // default 'hard'
antiLlm?: boolean; // default true
encodeStrings?: boolean;
obfuscateNumbers?: boolean;
mangleLocals?: boolean;
integrity?: boolean;
debuggerTrap?: boolean;
devToolsCheck?: boolean;
headlessCheck?: boolean;
deadCode?: boolean;
stealth?: boolean;
noscriptFallback?: boolean;
domainLock?: string;
expiresAt?: string;
geoAllow?: string;
browserBlocklist?: string;
osBlocklist?: string;
ipBlocklist?: string;
telemetryUrl?: string;
heartbeatMs?: number;
};
// Filtering
include?: RegExp | ((name: string) => boolean); // default /\.(m?js|cjs|html?)$/
exclude?: RegExp | ((name: string) => boolean); // default /\.map$/
// Behavior
concurrency?: number; // default 5, max 20
verbose?: boolean; // default true in dev, false in prod
silence?: boolean; // when true, skip Shield entirely
continueOnError?: boolean; // default true. when false, a failed file aborts the build
});Skip in development
You almost never want to obfuscate the dev bundle (it's slow and the output is unreadable in the browser's debugger). The simplest pattern:
const ShieldPlugin = require('shieldmycode-webpack-plugin');
module.exports = (env, argv) => ({
// ...
plugins: [
new ShieldPlugin({
apiKey: process.env.SHIELD_API_KEY,
silence: argv.mode !== 'production',
options: { level: 'hard', antiLlm: true }
})
]
});Or just conditionally include the plugin:
const plugins = [];
if (process.env.NODE_ENV === 'production') {
plugins.push(new ShieldPlugin({ /* ... */ }));
}Each file = one obfuscation against your quota
The plugin makes one /api/v1/obfuscate call per matching asset. A Webpack
build that emits 20 chunks consumes 20 obfuscations from your monthly quota
— same as if you'd uploaded those 20 files via the dashboard. Plan
accordingly:
| Plan | Quota | Typical build size that fits | |---|---|---| | Pro | 1,000/mo | ~30 production builds with 30 chunks each | | Business | 10,000/mo | ~300 production builds with 30 chunks each | | Enterprise | Custom | Unbounded |
If you hit the quota mid-build, the plugin reports over_quota as a
warning (or error, with continueOnError: false) and unprotected assets
ship instead. Keep an eye on usage via the dashboard.
License
MIT. Plugin only — the Shield engine itself runs server-side at shieldmycode.com.
Issues, feedback: https://shieldmycode.com/support
