babel-plugin-react-native-feedback-wrapper
v1.0.0
Published
Babel plugin to automatically wrap React Native components with FeedbackTrackable for Galadrim Feedback
Maintainers
Readme
babel-plugin-react-native-feedback-wrapper
Babel plugin to automatically wrap React Native components with FeedbackTrackable for Galadrim Feedback integration.
What it does
This plugin automatically wraps the root JSX element of exported components with a FeedbackTrackable wrapper that enables click tracking for feedback collection. It only wraps top-level/exported components, not every component used within.
Before:
export function MyScreen() {
return (
<View>
<Text>Hello World</Text>
<TouchableOpacity onPress={handlePress}>
<Text>Click me</Text>
</TouchableOpacity>
</View>
);
}
export function AnotherScreen() {
return (
<View>
<Text>Another</Text>
</View>
);
}After:
import { FeedbackTrackable } from "galadrim-feedback-react-native";
export function MyScreen() {
return (
<FeedbackTrackable componentPath="screens/MyScreen.tsx:MyScreen">
<View>
<Text>Hello World</Text>
<TouchableOpacity onPress={handlePress}>
<Text>Click me</Text>
</TouchableOpacity>
</View>
</FeedbackTrackable>
);
}
export function AnotherScreen() {
return (
<FeedbackTrackable componentPath="screens/MyScreen.tsx:AnotherScreen:2">
<View>
<Text>Another</Text>
</View>
</FeedbackTrackable>
);
}Note: The counter (:2) is automatically added when multiple exported components exist in the same file.
Key Behavior:
- ✅ Only wraps the root element of exported components
- ✅ Nested components inside are not wrapped
- ✅ Much cleaner output and better performance
- ✅ Tracks at the component level, not element level
- ✅ Auto-increments counter for multiple instances of same component
Component Path Format:
- Single instance:
screens/HomeScreen.tsx:HomeScreen - Multiple instances:
screens/HomeScreen.tsx:HomeScreen:2,screens/HomeScreen.tsx:HomeScreen:3, etc.
Installation
npm install --save-dev babel-plugin-react-native-feedback-wrapper
# or
yarn add -D babel-plugin-react-native-feedback-wrapperUsage
Basic Configuration
Add the plugin to your Babel configuration:
babel.config.js:
module.exports = {
presets: ["module:metro-react-native-babel-preset"],
plugins: ["babel-plugin-react-native-feedback-wrapper"],
};Advanced Configuration
You can customize which components to wrap:
module.exports = {
presets: ["module:metro-react-native-babel-preset"],
plugins: [
[
"babel-plugin-react-native-feedback-wrapper",
{
// Specify which React Native components to wrap
wrappableComponents: [
"View",
"Text",
"ScrollView",
"TouchableOpacity",
"TouchableHighlight",
"Pressable",
"Image",
],
// Set to false to only wrap specified RN components, not user components
wrapUserComponents: true,
},
],
],
};Options
wrappableComponents (Array)
An array of React Native component names that should be wrapped.
Default:
[
"View",
"Text",
"ScrollView",
"TouchableOpacity",
"TouchableHighlight",
"Pressable",
"Image",
"FlatList",
"SectionList",
];wrapUserComponents (boolean)
Whether to wrap user-defined components (components starting with uppercase).
Default: true
Skipping Specific Components
To prevent a specific component from being wrapped, add the data-feedback-skip attribute:
<View data-feedback-skip>
{/* This View and its children won't be tracked */}
<Text>This won't be wrapped</Text>
</View>How it Works
- The plugin traverses your JSX tree (skipping
node_modules) - Identifies components that match the wrapping criteria
- Automatically adds the
FeedbackTrackableimport if needed - Wraps each matching component with
<FeedbackTrackable componentPath="..."> - The
componentPathincludes the file path and component name for tracking
Automatically Skipped:
- Files in
node_modules(third-party packages) FeedbackProviderandFeedbackRootcomponentsFeedbackTrackablecomponents (avoids double-wrapping)- Components with
data-feedback-skipattribute - Fragments (
<Fragment>or<React.Fragment>)
Metro Configuration
For React Native projects using Metro bundler, make sure your metro.config.js is configured properly:
const { getDefaultConfig } = require("expo/metro-config");
const config = getDefaultConfig(__dirname);
module.exports = config;Performance Considerations
- The plugin only processes files during the build/transform phase
node_modulesare automatically skipped for optimal performance- Wrapping adds minimal runtime overhead
- Consider being selective with
wrappableComponentsfor large apps - Nested components avoid redundant wrapping (children of wrapped components aren't wrapped again)
Compatibility
- React Native: 0.60+
- Babel: 7.0+
- Expo: Compatible with Expo workflow
License
MIT
