Babel plugin for turning __proto__ into a shallow property clone
npx @tessl/cli install tessl/npm-babel--plugin-transform-proto-to-assign@7.27.0A Babel plugin that transforms JavaScript code using the __proto__ property into compatible property assignment operations using helper functions. This plugin addresses browser compatibility issues by converting __proto__ usage into calls to helper functions that provide equivalent functionality across different JavaScript engines.
npm install --save-dev @babel/plugin-transform-proto-to-assignThis is a Babel plugin, so it's used in Babel configuration rather than direct imports:
Babel Config (babel.config.js):
module.exports = {
plugins: ["@babel/plugin-transform-proto-to-assign"]
};Babel Config (.babelrc.json):
{
"plugins": ["@babel/plugin-transform-proto-to-assign"]
}Direct Babel API usage:
import babel from "@babel/core";
import protoToAssignPlugin from "@babel/plugin-transform-proto-to-assign";
const result = babel.transformSync(code, {
plugins: [protoToAssignPlugin]
});The plugin automatically transforms __proto__ usage during the Babel compilation process. No runtime API calls are needed.
Input (before transformation):
// Object literal with __proto__
var obj = {
__proto__: parentObj,
prop: "value"
};
// Assignment expression using __proto__
obj.__proto__ = parentObj;
// __proto__ assignment in expression
console.log(target.__proto__ = source);Output (after transformation):
// Transformed to extends helper
var obj = babelHelpers.extends({}, parentObj, {
prop: "value"
});
// Transformed to defaults helper
babelHelpers.defaults(obj, parentObj);
// Transformed with temporary variable
var _target;
console.log((_target = target, babelHelpers.defaults(_target, source), _target));The main and only public API of this package - a Babel plugin function.
import { declare } from "@babel/helper-plugin-utils";
import { types as t, type File } from "@babel/core";
/**
* Main Babel plugin function that transforms __proto__ usage
* @param api - Babel plugin API object with assertVersion method
* @returns Babel plugin configuration object with visitor methods
*/
export default declare(api => {
api.assertVersion("^7.0.0-0");
return {
name: "transform-proto-to-assign",
visitor: {
AssignmentExpression(path: NodePath<t.AssignmentExpression>, state: PluginState): void;
ExpressionStatement(path: NodePath<t.ExpressionStatement>, state: PluginState): void;
ObjectExpression(path: NodePath<t.ObjectExpression>, state: PluginState): void;
}
};
});
interface BabelPluginApi {
assertVersion(required: string): void;
}
interface BabelPlugin {
name: string;
visitor: {
[nodeType: string]: (path: NodePath<any>, state: PluginState) => void;
};
}
interface PluginState {
file: File;
}
interface NodePath<T = t.Node> {
node: T;
scope: Scope;
replaceWith(node: t.Node): void;
replaceWithMultiple(nodes: t.Node[]): void;
}
interface Scope {
maybeGenerateMemoised(node: t.Node): t.Identifier | null;
}Transforms object literals containing __proto__ properties.
Pattern: { __proto__: value, ...properties }
Transforms to: babelHelpers.extends({}, value, { ...properties })
This transformation:
__proto__ property from the object literalextends helper with an empty object, the proto value, and remaining propertiesTransforms __proto__ assignments within expressions.
Pattern: object.__proto__ = value (within expressions)
Transforms to: (temp = object, babelHelpers.defaults(temp, value), temp)
This transformation:
defaults helper to perform the prototype assignmentTransforms standalone __proto__ assignment statements.
Pattern: object.__proto__ = value; (as statement)
Transforms to: babelHelpers.defaults(object, value);
This transformation:
defaults helper functionThe plugin generates calls to two Babel runtime helpers:
Used for object literal __proto__ transformations. Equivalent to Object.assign({}, proto, ...sources).
Used for __proto__ assignment transformations. Copies properties from source to target object, similar to Object.setPrototypeOf functionality but using property assignment.
This plugin accepts no configuration options. It operates with default behavior on all __proto__ usage patterns.
This plugin enables __proto__ usage in environments that don't support it natively, including:
__proto__ is disabled__proto__ behavior differsThe transformed code uses standard property assignment operations that work in all JavaScript environments.