Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

babel-plugin-transform-react-create-element

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-transform-react-create-element - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

2

package.json
{
"name": "babel-plugin-transform-react-create-element",
"version": "0.1.0",
"version": "0.2.0",
"description": "Shorten JSX React.createElement calls using a local variable.",

@@ -5,0 +5,0 @@ "main": "src/index.js",

@@ -49,5 +49,5 @@ # babel-plugin-transform-react-create-element

It works by inserting a JSX pragma that points to the local variable. Hence, it needs to run before any JSX compilers. If you're using `@babel/preset-react` everything will work out of the box. If you're using `@babel/plugin-transform-react-jsx` directly, make sure to list this plugin before it.
It works by translating any found calls to `React.createElement` to use the newly inserted local variable instead.
This plugin _does_ respect any existing JSX pragmas in the file and does not modify them.
As such, it automatically respects any existing JSX pragmas in the file and does not interfer with their use.

@@ -63,1 +63,3 @@ ## Why?

MIT
Loosely based on https://github.com/facebook/create-react-app/pull/6219.

@@ -1,7 +0,11 @@

import { Visitor } from "@babel/core";
import * as t from "@babel/types";
declare const transform: () => {
name: string;
visitor: Visitor<{}>;
visitor: {
CallExpression(path: any, state: {
localVariableIdent: t.Identifier;
}): void;
};
};
export default transform;
//# sourceMappingURL=index.d.ts.map

@@ -5,74 +5,76 @@ "use strict";

const template_1 = tslib_1.__importDefault(require("@babel/template"));
const PRAGMA_ELEM_NAME = "createElement";
const LOCAL_VARIABLE_TEMPLATE = template_1.default(`
const %%pragma%% = React.createElement;
`);
const PRAGMA_ELEM_NAME = "createElement";
const transform = () => {
let createElementIdent;
let hasInsertedJsxLocalVariable = false;
let usesJsx = false;
const checkUsesJsxVisitor = {
JSX() {
usesJsx = true;
},
};
const insertingVisitor = {
ImportDeclaration(path) {
if (path.node.source.value !== "react" || hasInsertedJsxLocalVariable) {
const %%pragma%% = /*#__PURE__*/ React.createElement;
`, {
preserveComments: true,
});
const getReactImport = (path) => {
const binding = path.scope.getBinding(path.node.name);
if (!binding) {
return null;
}
const bindingPath = binding.path;
if (bindingPath.isImportDefaultSpecifier()) {
const parentPath = bindingPath.parentPath;
if (parentPath.isImportDeclaration() &&
parentPath.node.source.value === "react") {
return bindingPath;
}
}
else if (bindingPath.isVariableDeclarator()) {
const init = bindingPath.get("init");
if (init.isCallExpression() &&
init.node.callee.isIdentifier() &&
init.node.callee.name === "require" &&
init.node.arguments.length === 1 &&
init.node.arguments[0].isStringLiteral() &&
init.node.arguments[0].value === "react") {
return bindingPath;
}
}
return null;
};
const getCreateElementAndImport = (path) => {
const callee = path.get("callee");
if (!callee.isMemberExpression()) {
return null;
}
const property = callee.get("property");
if (!property.isIdentifier() || property.node.name !== "createElement") {
return null;
}
const object = callee.get("object");
const reactImport = getReactImport(object);
if (!reactImport) {
return null;
}
return [callee, reactImport];
};
const insertLocalVariable = (importSite) => {
const uniqueIdent = importSite.scope.generateUidIdentifier(PRAGMA_ELEM_NAME);
const variableDeclaration = LOCAL_VARIABLE_TEMPLATE({
pragma: uniqueIdent,
});
const [node] = importSite.parentPath.insertAfter(variableDeclaration);
importSite.parentPath.scope.registerDeclaration(node);
return uniqueIdent;
};
const transform = () => ({
name: "transform-create-element",
visitor: {
CallExpression(path, state) {
const data = getCreateElementAndImport(path);
if (!data) {
return;
}
const defaultImportSpec = path.node.specifiers.find((spec) => spec.type === "ImportDefaultSpecifier");
if (!defaultImportSpec) {
return;
const [callee, importSite] = data;
if (!state.localVariableIdent) {
state.localVariableIdent = insertLocalVariable(importSite);
}
const spec = defaultImportSpec;
if (spec.local.name !== "React") {
return;
}
path.insertAfter(LOCAL_VARIABLE_TEMPLATE({ pragma: createElementIdent }));
hasInsertedJsxLocalVariable = true;
callee.replaceWith(state.localVariableIdent);
},
};
const programVisitor = {
Program(path, { file }) {
var _a;
/*
* Check if we already have an existing pragma in the source code and if so,
* leave the file be.
*/
const alreadyContainsJsxPragma = file.ast.comments.some((c) => c.value.indexOf("@jsx") !== -1);
if (alreadyContainsJsxPragma) {
return;
}
/*
* Leave the file be if it doesn't use any JSX.
*/
path.traverse(checkUsesJsxVisitor);
if (!usesJsx) {
return;
}
createElementIdent = path.scope.generateUidIdentifier(PRAGMA_ELEM_NAME);
path.traverse(insertingVisitor);
if (!hasInsertedJsxLocalVariable) {
return;
}
const commentText = `* @jsx ${createElementIdent.name} `;
path.addComment("leading", commentText);
/*
* Because babel doesn't reparse the source code, our new comment does not
* show up in `file.ast.comments`, where @babel/plugin-transform-react-jsx
* expects it.
*
* Hence add it manually.
*/
const insertedCommentNode = (_a = path.node.leadingComments) === null || _a === void 0 ? void 0 : _a.find((c) => c.value === commentText);
file.ast.comments.push(insertedCommentNode);
},
};
return {
name: "transform-react-imports",
visitor: programVisitor,
};
};
},
});
exports.default = transform;
//# sourceMappingURL=index.js.map

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc