@fullstory/babel-plugin-annotate-react
Advanced tools
Comparing version 2.2.1 to 2.2.2
# Changelog | ||
## 2.2.2 | ||
- Fixed annotating short syntax Fragments when enabled. | ||
## 2.2.1 | ||
@@ -4,0 +8,0 @@ |
74
index.js
@@ -51,3 +51,3 @@ const webComponentName = 'data-component'; | ||
module.exports = function({ types: t }) { | ||
module.exports = function ({ types: t }) { | ||
return { | ||
@@ -93,2 +93,3 @@ pre() { | ||
}) | ||
if (!render || !render.traverse) return | ||
@@ -102,4 +103,5 @@ if (isKnownIncompatiblePluginFromState(state)) return | ||
const arg = returnStatement.get('argument') | ||
if (!arg.isJSXElement()) return | ||
processJSXElement( | ||
if (!arg.isJSXElement() && !arg.isJSXFragment()) return | ||
processJSX( | ||
state.opts[annotateFragmentsOptionName] === true, | ||
@@ -151,4 +153,4 @@ t, | ||
let pluginName = knownIncompatiblePlugins[i]; | ||
if (fullSourceFileName.includes("/node_modules/" + pluginName + "/") || | ||
fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")) { | ||
if (fullSourceFileName.includes("/node_modules/" + pluginName + "/") || | ||
fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")) { | ||
return true | ||
@@ -162,3 +164,3 @@ } | ||
function attributeNamesFromState(state) { | ||
if(state.opts[nativeOptionName] === true) { | ||
if (state.opts[nativeOptionName] === true) { | ||
return [nativeComponentName, nativeElementName, nativeSourceFileName] | ||
@@ -170,2 +172,6 @@ } | ||
function isReactFragment(openingElement) { | ||
if (openingElement.isJSXFragment()) { | ||
return true | ||
} | ||
if ( | ||
@@ -176,3 +182,5 @@ !openingElement.node || | ||
if (openingElement.node.name.name === 'Fragment') return true; | ||
if (openingElement.node.name.name === 'Fragment' || | ||
openingElement.node.name.name === 'React.Fragment' | ||
) return true; | ||
@@ -195,6 +203,6 @@ if ( | ||
if (!openingElement | ||
|| isReactFragment(openingElement) | ||
|| !openingElement.node | ||
|| !openingElement.node.name | ||
) { | ||
|| isReactFragment(openingElement) | ||
|| !openingElement.node | ||
|| !openingElement.node.name | ||
) { | ||
return | ||
@@ -259,20 +267,23 @@ } | ||
function processJSXElement(annotateFragments, t, jsxElement, componentName, sourceFileName, attributeNames, ignoreComponentsFromOption) { | ||
if (!jsxElement) { | ||
function processJSX(annotateFragments, t, jsxNode, componentName, sourceFileName, attributeNames, ignoreComponentsFromOption) { | ||
if (!jsxNode) { | ||
return | ||
} | ||
const openingElement = jsxElement.get('openingElement') | ||
// only a JSXElement contains openingElement | ||
const openingElement = jsxNode.get('openingElement') | ||
applyAttributes(t, openingElement, componentName, sourceFileName, attributeNames, ignoreComponentsFromOption) | ||
const children = jsxElement.get('children') | ||
const children = jsxNode.get('children') | ||
if (children && children.length) { | ||
let shouldSetComponentName = annotateFragments | ||
for (let i=0; i < children.length; i += 1){ | ||
for (let i = 0; i < children.length; i += 1) { | ||
const child = children[i] | ||
// Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true | ||
if (shouldSetComponentName && children[i].get('openingElement') && children[i].get('openingElement').node) { | ||
if (shouldSetComponentName && child.get('openingElement') && child.get('openingElement').node) { | ||
shouldSetComponentName = false | ||
processJSXElement(annotateFragments, t, children[i], componentName, sourceFileName, attributeNames, ignoreComponentsFromOption) | ||
processJSX(annotateFragments, t, child, componentName, sourceFileName, attributeNames, ignoreComponentsFromOption) | ||
} else { | ||
processJSXElement(annotateFragments, t, children[i], null, sourceFileName, attributeNames, ignoreComponentsFromOption) | ||
processJSX(annotateFragments, t, child, null, sourceFileName, attributeNames, ignoreComponentsFromOption) | ||
} | ||
@@ -284,10 +295,12 @@ } | ||
function functionBodyPushAttributes(annotateFragments, t, path, componentName, sourceFileName, attributeNames, ignoreComponentsFromOption) { | ||
let jsxElement = null | ||
let jsxNode = null | ||
const functionBody = path.get('body').get('body') | ||
if (functionBody.parent && functionBody.parent.type === 'JSXElement') { | ||
const maybeJsxElement = functionBody.find(c => { | ||
return c.type === 'JSXElement' | ||
if (functionBody.parent && | ||
(functionBody.parent.type === 'JSXElement' || functionBody.parent.type === 'JSXFragment') | ||
) { | ||
const maybeJsxNode = functionBody.find(c => { | ||
return (c.type === 'JSXElement' || c.type === 'JSXFragment') | ||
}) | ||
if (!maybeJsxElement) return | ||
jsxElement = maybeJsxElement | ||
if (!maybeJsxNode) return | ||
jsxNode = maybeJsxNode | ||
} else { | ||
@@ -301,9 +314,12 @@ const returnStatement = functionBody.find(c => { | ||
const arg = returnStatement.get('argument') | ||
if (!arg || !arg.isJSXElement()) { | ||
if (!arg) { | ||
return | ||
} | ||
jsxElement = arg | ||
if (!arg.isJSXFragment() && !arg.isJSXElement()) { | ||
return | ||
} | ||
jsxNode = arg | ||
} | ||
if (!jsxElement) return | ||
processJSXElement(annotateFragments, t, jsxElement, componentName, sourceFileName, attributeNames, ignoreComponentsFromOption) | ||
if (!jsxNode) return | ||
processJSX(annotateFragments, t, jsxNode, componentName, sourceFileName, attributeNames, ignoreComponentsFromOption) | ||
} | ||
@@ -310,0 +326,0 @@ |
{ | ||
"name": "@fullstory/babel-plugin-annotate-react", | ||
"version": "2.2.1", | ||
"version": "2.2.2", | ||
"description": "A Babel plugin that annotates React components, making them easier to target with FullStory search", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
# Babel Plugin: Annotate React | ||
[![CircleCI](https://circleci.com/gh/fullstorydev/fullstory-babel-plugin-annotate-react.svg?style=svg)](https://circleci.com/gh/fullstorydev/fullstory-babel-plugin-annotate-react) | ||
This is a Babel plugin that annotates React components with stable attributes that can be used to search and select using FullStory. This is most useful when using a React system that generates dynamic names for Components or rearranges elements. | ||
This is a Babel plugin that annotates React components with stable attributes that can be used to search and select using [FullStory](https://www.fullstory.com/). This is most useful when using a React system that generates dynamic names for Components or rearranges elements. | ||
@@ -77,5 +77,5 @@ For React on the web the attributes are `data-component`, `data-element`, and `data-source-file`. For React Native the attributes are `dataComponent`, `dataElement`, and `dataSourceFile`. | ||
'../..', | ||
{ | ||
{ | ||
ignoreComponents:[ | ||
// each item must be a string array containing three items: file name, component name, element name | ||
// each item must be a string array containing three items: file name, component name, element name | ||
// corresponding to the values for data-source-file, data-component, data-element | ||
@@ -85,3 +85,3 @@ // use wild card (*) to match anything | ||
["App.jsx", "*", "ThemeProvider"], // use wild-card to match anything | ||
["App.jsx", "App", "*"], | ||
["App.jsx", "App", "*"], | ||
] | ||
@@ -95,6 +95,14 @@ } | ||
- [Single Page App](./samples/single-page-app/) | ||
- [styled-components](./samples/styled-components/) | ||
- [React native](./samples/react-native-app/) | ||
- [Single Page App](https://github.com/fullstorydev/fullstory-babel-plugin-annotate-react/tree/master/samples/single-page-app/) | ||
- [styled-components](https://github.com/fullstorydev/fullstory-babel-plugin-annotate-react/tree/master/samples/styled-components/) | ||
- [React native](https://github.com/fullstorydev/fullstory-babel-plugin-annotate-react/tree/master/samples/react-native-app/) | ||
Much of the logic for adding the attributes originated in the [transform-react-qa-classes](https://github.com/davesnx/babel-plugin-transform-react-qa-classes/) plugin. | ||
## Getting Help | ||
Please refer to our [Knowledge Base article](https://help.fullstory.com/hc/en-us/articles/360049493054-FullStory-s-Annotate-React-plugin-for-Web-Native) or contact mobile-support@fullstory.com for additional help. | ||
### React Native | ||
Please see our [Getting Started with FullStory React Native Capture](https://help.fullstory.com/hc/en-us/articles/360052419133) guide or email mobile-support@fullstory.com for additional help. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17792
314
106
1