Metro Plugin
A Metro plugin which hooks into the bundling process to protect the output bundle. The plugin can be configured to process only the modules that are "first-party" application code, or to process the whole bundle, including the third-party modules and the React Native related bootstrapping code.
Supported Versions and Bundle Formats
Supported React Native versions: >=0.59.0
Supported bundle formats: Plain bundle
Limitations
Because of a missing feature in the Metro Bundler, the JSDefender Metro Plugin does not work with the Metro Bundler Server. Starting the bundler server with react-native start
or by running react-native run-android
(it defaults to the --variant=debug
option) or react-native run-ios
(it defaults to the --configuration Debug
option) will not protect the requested bundle. Also, this is the case when creating debug app packages for Android (cd android && ./gradlew bundleDebug
) and iOS.
The following commands, which do not use the Metro Bundle server, will work:
react-native run-android --variant=release
- running on Android emulator or devicereact-native run-ios --configuration Release
- running on iOS emulator or devicereact-native bundle --entry-file index.js --bundle-output index.bundle
- creating a bundle where theindex.js
andindex.bundle
should be replaced by your own paths, by default this generates a development bundle, you can generate a release bundle by also passing the--dev false
argumentscd android && ./gradlew bundleRelease
- generating the release APK for Android and running it on device/emulator or publishing it to the Play Store- Building the Android project with Android Studio and running it on device/emulator or publishing it to the Play Store
- Building the iOS project with Xcode and running it on device/emulator or publishing it to the App Store
The DevTools Blocking protection does not support React Native. The plugin will emit an error and stop the build if this protection is turned on.
Installation
Install the plugin to your project:
npm install <package-directory>/preemptive-jsdefender-core-{version}.tgz <package-directory>/preemptive-jsdefender-metro-plugin-{version}.tgz --save-dev
OR
yarn add file:<package-directory>/preemptive-jsdefender-core-{version}.tgz file:<package-directory>/preemptive-jsdefender-metro-plugin-{version}.tgz --dev
@preemptive/jsdefender-core
as its peerDependency, this is why you must also install it.
Usage
Add the plugin to your metro.config.js
:
const jsdefenderMetroPlugin = require("@preemptive/jsdefender-metro-plugin")(
// --JSDefender configuration
{
configurationFile: "jsdefender.config.json", // Optional path to the configuration file, if any, it defaults to `jsdefender.config.json`
quietMode: false, // If false every log message will be displayed, otherwise only the errors and warnings, it defaults to false
protectUserModulesOnly: false, // If false the whole bundle will be protected, otherwise only the "first-party" application code, it defaults to false
enableInDevelopmentMode: false, // If false the protection will be skipped in non-production modes, otherwise it will run in every mode, it defaults to false
/* Other JSDefender options e.g. `settings: { booleanLiterals: true, stringLiterals: true }` etc. could also be provided here */
},
// --Metro configuration
{
resolver: {
/* resolver Metro options */
},
transformer: {
/* transformer Metro options */
},
serializer: {
/* serializer Metro options */
},
server: {
/* server Metro options */
}
/* general Metro options */
}
)
module.exports = jsdefenderMetroPlugin;
enableInDevelopmentMode
option of the plugin to true
.
Configuration
The JSDefender Metro plugin accepts the same configuration object as the JSDefender configuration file. You can learn more about it at the documentation home. The plugin uses a default configuration just as JSDefender CLI does. This can be overridden by explicitly specifying a configuration to the plugin. As you can see, you can also specify your own Metro options and they will be applied.
configurationFile
is present, its individual configuration lines will be overwritten by the JSDefender configuration directly used in the metro.config.js
file. For example, if you set booleanLiterals: true
for the jsdefenderMetroPlugin
in the metro.config.js
but there is a configurationFile
set which has booleanLiterals: false
, then the first will take precedence, so the final value will be booleanLiterals: true
.