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

babel-plugin-react-transform

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

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

Comparing version 1.0.5 to 1.1.0

test/fixtures/classic/.babelrc

119

lib/index.js

@@ -43,2 +43,4 @@ 'use strict';

var wrapComponentIdKey = '__reactTransformWrapComponentId';
var optionsKey = '__reactTransformOptions';
var cacheKey = '__reactTransformCache';

@@ -56,11 +58,74 @@ function isRenderMethod(member) {

var isCreateClassCallExpression = t.buildMatchMemberExpression('React.createClass');
function buildIsCreateClassCallExpression(factoryMethods) {
var matchMemberExpressions = {};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = factoryMethods[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var method = _step.value;
matchMemberExpressions[method] = t.buildMatchMemberExpression(method);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator['return']) {
_iterator['return']();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return function (node) {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = factoryMethods[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var method = _step2.value;
if (method.indexOf('.') !== -1) {
if (matchMemberExpressions[method](node.callee)) {
return true;
}
} else {
if (node.callee.name === method) {
return true;
}
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2['return']) {
_iterator2['return']();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
};
}
/**
* Does this node look like a createClass() call?
*/
function isCreateClass(node) {
function isCreateClass(node, isCreateClassCallExpression) {
if (!node || !t.isCallExpression(node)) {
return false;
}
if (!isCreateClassCallExpression(node.callee)) {
if (!isCreateClassCallExpression(node)) {
return false;

@@ -99,2 +164,15 @@ }

function isValidOptions(options) {
return typeof options === 'object' && Array.isArray(options.transforms);
}
var didWarnAboutLegacyConfig = false;
function warnOnceAboutLegacyConfig() {
if (didWarnAboutLegacyConfig) {
return;
}
console.warn('Warning: you are using an outdated format of React Transform configuration. ' + 'Please update your configuration to the new format. See the Releases page for migration instructions: ' + 'https://github.com/gaearon/babel-plugin-react-transform/releases');
didWarnAboutLegacyConfig = true;
}
/**

@@ -107,6 +185,16 @@ * Enforces plugin options to be defined and returns them.

}
var pluginOptions = file.opts.extra['react-transform'];
if (!Array.isArray(pluginOptions)) {
throw new Error('babel-plugin-react-transform requires that you specify ' + 'extras["react-transform"] in .babelrc ' + 'or in your Babel Node API call options, and that it is an array.');
if (Array.isArray(pluginOptions)) {
warnOnceAboutLegacyConfig();
var transforms = pluginOptions.map(function (option) {
option.transform = option.transform || option.target;
return option;
});
pluginOptions = { transforms: transforms };
}
if (!isValidOptions(pluginOptions)) {
throw new Error('babel-plugin-react-transform requires that you specify ' + 'extras["react-transform"] in .babelrc ' + 'or in your Babel Node API call options, and that it is an object with ' + 'a transforms property which is an array.');
}
return pluginOptions;

@@ -136,3 +224,3 @@ }

* Memorizes the fact that we have visited a valid component in the plugin state.
* We will later retrieved memorized records to compose an object out of them.
* We will later retrieve memorized records to compose an object out of them.
*/

@@ -177,3 +265,3 @@ function addComponentRecord(node, scope, file, state) {

var id = scope.generateUidIdentifier('reactComponentWrapper');
var target = targetOptions.target;
var transform = targetOptions.transform;
var _targetOptions$imports = targetOptions.imports;

@@ -200,3 +288,3 @@ var imports = _targetOptions$imports === undefined ? [] : _targetOptions$imports;

return [id, t.variableDeclaration('var', [t.variableDeclarator(id, t.callExpression(file.addImport(resolvePath(target, filename)), [t.objectExpression([t.property('init', t.identifier('filename'), t.literal(filename)), t.property('init', t.identifier('components'), recordsId), t.property('init', t.identifier('locals'), t.arrayExpression(locals.map(function (local) {
return [id, t.variableDeclaration('var', [t.variableDeclarator(id, t.callExpression(file.addImport(resolvePath(transform, filename)), [t.objectExpression([t.property('init', t.identifier('filename'), t.literal(filename)), t.property('init', t.identifier('components'), recordsId), t.property('init', t.identifier('locals'), t.arrayExpression(locals.map(function (local) {
return t.identifier(local);

@@ -246,3 +334,5 @@ }))), t.property('init', t.identifier('imports'), t.arrayExpression(imports.map(function (imp) {

exit: function exit(node, parent, scope, file) {
if (!isCreateClass(node)) {
var isCreateClassCallExpression = this.state[cacheKey].isCreateClassCallExpression;
if (!isCreateClass(node, isCreateClassCallExpression)) {
return;

@@ -260,2 +350,9 @@ }

enter: function enter(node, parent, scope, file) {
var options = getPluginOptions(file);
var factoryMethods = options.factoryMethods || ['React.createClass', 'createClass'];
this.state[optionsKey] = options;
this.state[cacheKey] = {
isCreateClassCallExpression: buildIsCreateClassCallExpression(factoryMethods)
};
this.state[wrapComponentIdKey] = scope.generateUidIdentifier('wrapComponent');

@@ -270,3 +367,3 @@ },

// Generate a variable holding component records
var allTransformOptions = getPluginOptions(file);
var allTransforms = this.state[optionsKey].transforms;

@@ -281,3 +378,3 @@ var _defineComponentRecords = defineComponentRecords(scope, this.state);

// Import transformation functions and initialize them
var initTransformCalls = allTransformOptions.map(function (transformOptions) {
var initTransformCalls = allTransforms.map(function (transformOptions) {
return defineInitTransformCall(scope, file, recordsId, transformOptions);

@@ -284,0 +381,0 @@ }).filter(Boolean);

2

package.json
{
"name": "babel-plugin-react-transform",
"version": "1.0.5",
"version": "1.1.0",
"description": "Babel plugin to instrument React components with custom transforms",

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

@@ -9,5 +9,6 @@ # babel-plugin-react-transform

* catch errors inside `render()` like **[react-transform-catch-errors](https://github.com/gaearon/react-transform-catch-errors)**;
* enable hot reloading like **[react-transform-webpack-hmr](https://github.com/gaearon/react-transform-webpack-hmr)**;
* enable hot reloading like **[react-transform-hmr](https://github.com/gaearon/react-transform-hmr)**;
* render an inline prop inspector like **[react-transform-debug-inspector](https://github.com/alexkuz/react-transform-debug-inspector)**;
* highlight parts of the screen when components update (want to write this one?),
* highlight parts of the screen when components update like
**[react-transform-render-visualizer](https://github.com/spredfast/react-transform-render-visualizer)**;
* etc.

@@ -37,3 +38,3 @@

```
npm install --save-dev react-transform-webpack-hmr
npm install --save-dev react-transform-hmr
npm install --save-dev react-transform-catch-errors

@@ -43,3 +44,3 @@ ```

Then edit your `.babelrc` to include `extra.react-transform`.
It must be an array of the transforms you want to use:
It must be an object with a `transforms` property being an array of the transforms you want to use:

@@ -61,17 +62,23 @@ ```js

"extra": {
// must be defined and be an array
"react-transform": [{
// can be an NPM module name or a local path
"target": "react-transform-webpack-hmr",
// see specific transform's docs for "imports" and "locals" it needs
"imports": ["react"],
"locals": ["module"]
}, {
// you can have many transforms, not just one
"target": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}, {
// can be an NPM module name or a local path
"target": "./src/my-custom-transform"
}]
// must be an object
"react-transform": {
// must be an array
"transforms": [{
// can be an NPM module name or a local path
"transform": "react-transform-hmr",
// see specific transform's docs for "imports" and "locals" it needs
"imports": ["react"],
"locals": ["module"]
}, {
// you can have many transforms, not just one
"transform": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}, {
// can be an NPM module name or a local path
"transform": "./src/my-custom-transform"
}]
},
// by default we only look for `React.createClass` (and ES6 classes)
// but you can tell the plugin to look for different component factories:
// factoryMethods: ["React.createClass", "createClass"]
}

@@ -83,4 +90,8 @@ }

As you can see each transform, apart from the `target` field where you write it name, also has `imports` and `locals` fields. You should consult the docs of each individual transform to learn which `imports` and `locals` it might need, and how it uses them. You probably already guessed that this is just a way to inject local variables (like `module`) or dependencies (like `react`) into the transforms that need them.
As you can see each transform, apart from the `transform` field where you write it name, also has `imports` and `locals` fields. You should consult the docs of each individual transform to learn which `imports` and `locals` it might need, and how it uses them. You probably already guessed that this is just a way to inject local variables (like `module`) or dependencies (like `react`) into the transforms that need them.
Note that when using `React.createClass()` and allowing `babel` to extract the `displayName` property you must ensure that [babel-plugin-react-display-name](https://github.com/babel/babel/tree/development/packages/babel-plugin-react-display-name) is included before `react-transform`. See [this github issue](https://github.com/gaearon/babel-plugin-react-transform/issues/19) for more details.
You may optionally specify an array of strings called `factoryMethods` if you want the plugin to look for components created with a factory method other than `React.createClass`. Note that you don’t have to do anything special to look for ES6 components—`factoryMethods` is only relevant if you use factory methods akin to `React.createClass`.
## Writing a Transform

@@ -201,3 +212,3 @@

* **https://github.com/gaearon/react-transform-boilerplate**
* **https://github.com/gaearon/react-transform-webpack-hmr**
* **https://github.com/gaearon/react-transform-hmr**
* **https://github.com/gaearon/react-transform-catch-errors**

@@ -207,8 +218,2 @@ * **https://github.com/alexkuz/react-transform-debug-inspector**

## Limitations
Currently, it can only locate components of two types: ES6 classes with `render` method and explicit `React.createClass()` calls. I’m open to adding more heuristics for other common patterns, given enough interest.
When using `React.createClass()` and allowing `babel` to extract the `displayName` property you must ensure that [babel-plugin-react-display-name](https://github.com/babel/babel/tree/development/packages/babel-plugin-react-display-name) is included before `react-transform`. See [this github issue](https://github.com/gaearon/babel-plugin-react-transform/issues/19) for more details.
## Discussion

@@ -215,0 +220,0 @@

@@ -17,14 +17,4 @@ import path from 'path';

const actualPath = path.join(fixtureDir, 'actual.js');
const actual = transformFileSync(actualPath, {
plugins: [plugin],
extra: {
'react-transform': [{
target: 'my-custom-module/wrap',
locals: ['module'],
imports: ['react']
}, {
target: 'my-other-custom-module/wrap'
}]
}
}).code;
const actual = transformFileSync(actualPath).code;
const expected = fs.readFileSync(

@@ -31,0 +21,0 @@ path.join(fixtureDir, 'expected.js')

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