@babel/plugin-transform-member-expression-literals is a Babel transformation plugin that ensures compatibility with ES3 environments by converting JavaScript member expressions using reserved words from dot notation to bracket notation with string literals.
npm install --save-dev @babel/plugin-transform-member-expression-literalsimport memberExpressionLiteralsPlugin from "@babel/plugin-transform-member-expression-literals";For CommonJS:
const memberExpressionLiteralsPlugin = require("@babel/plugin-transform-member-expression-literals");The plugin requires:
@babel/core (peer dependency)@babel/helper-plugin-utils (helper for plugin creation)@babel/helper-validator-identifier internally via Babel typesimport { transform } from "@babel/core";
import memberExpressionLiteralsPlugin from "@babel/plugin-transform-member-expression-literals";
// Transform code with the plugin
const result = transform(`
const obj = {};
obj.catch = "value"; // ES3 reserved word -> transformed
obj.package = "pkg"; // ES3 reserved word -> transformed
obj.private = true; // ES3 reserved word -> transformed
obj.public = false; // ES3 reserved word -> transformed
obj.static = "method"; // ES3 reserved word -> transformed
obj.interface = "ITest"; // ES3 reserved word -> transformed
obj.validName = "ok"; // Valid identifier -> unchanged
`, {
plugins: [memberExpressionLiteralsPlugin]
});
console.log(result.code);
// Output:
// const obj = {};
// obj["catch"] = "value";
// obj["package"] = "pkg";
// obj["private"] = true;
// obj["public"] = false;
// obj["static"] = "method";
// obj["interface"] = "ITest";
// obj.validName = "ok";The default export is a Babel plugin created using the declare helper from @babel/helper-plugin-utils.
/**
* Default export: Babel plugin for transforming member expression literals
* Created using declare() helper which handles plugin API version validation
*/
const plugin: BabelPlugin;
export default plugin;
/**
* Plugin structure returned by declare() helper
*/
interface BabelPlugin {
name: "transform-member-expression-literals";
visitor: {
MemberExpression: {
exit(path: NodePath<MemberExpression>): void;
};
};
}
/**
* Babel node path type used in visitor
*/
interface NodePath<T> {
node: T;
}Usage Examples:
// In Babel configuration (.babelrc.json)
{
"plugins": ["@babel/plugin-transform-member-expression-literals"]
}
// Programmatically with Babel
import { transform } from "@babel/core";
import plugin from "@babel/plugin-transform-member-expression-literals";
const code = "obj.package = 'value';";
const result = transform(code, {
plugins: [plugin]
});
// Result: obj["package"] = 'value';The plugin transforms member expressions where the property name fails the isValidES3Identifier check. This includes:
isValidIdentifier)ES3-Only Reserved Words (transformed by this plugin):
obj.abstract // ES3 reserved -> obj["abstract"]
obj.boolean // ES3 reserved -> obj["boolean"]
obj.byte // ES3 reserved -> obj["byte"]
obj.char // ES3 reserved -> obj["char"]
obj.double // ES3 reserved -> obj["double"]
obj.enum // ES3 reserved -> obj["enum"]
obj.final // ES3 reserved -> obj["final"]
obj.float // ES3 reserved -> obj["float"]
obj.goto // ES3 reserved -> obj["goto"]
obj.implements // ES3 reserved -> obj["implements"]
obj.int // ES3 reserved -> obj["int"]
obj.interface // ES3 reserved -> obj["interface"]
obj.long // ES3 reserved -> obj["long"]
obj.native // ES3 reserved -> obj["native"]
obj.package // ES3 reserved -> obj["package"]
obj.private // ES3 reserved -> obj["private"]
obj.protected // ES3 reserved -> obj["protected"]
obj.public // ES3 reserved -> obj["public"]
obj.short // ES3 reserved -> obj["short"]
obj.static // ES3 reserved -> obj["static"]
obj.synchronized // ES3 reserved -> obj["synchronized"]
obj.throws // ES3 reserved -> obj["throws"]
obj.transient // ES3 reserved -> obj["transient"]
obj.volatile // ES3 reserved -> obj["volatile"]Common JavaScript Keywords (also transformed):
obj.catch // Keyword -> obj["catch"]
obj.class // Keyword -> obj["class"]
obj.const // Keyword -> obj["const"]
obj.default // Keyword -> obj["default"]
obj.delete // Keyword -> obj["delete"]
obj.export // Keyword -> obj["export"]
obj.import // Keyword -> obj["import"]The plugin leaves already valid expressions unchanged:
Unchanged Examples:
obj.validName // Valid identifier - unchanged
obj["alreadyQuoted"] // Already computed - unchanged
obj[variable] // Dynamic property - unchanged
obj.normalProp // Valid ES3 identifier - unchanged/**
* Core AST node types used by the plugin
*/
interface MemberExpression {
type: "MemberExpression";
object: Expression;
property: Expression;
computed: boolean;
}
interface Identifier {
type: "Identifier";
name: string;
}
interface StringLiteral {
type: "StringLiteral";
value: string;
}
type Expression = MemberExpression | Identifier | StringLiteral | any;
/**
* Babel types utilities (from @babel/core)
*/
interface BabelTypes {
isIdentifier(node: any): node is Identifier;
isValidES3Identifier(name: string): boolean;
stringLiteral(value: string): StringLiteral;
}
/**
* Plugin helper functions
*/
declare const REQUIRED_VERSION: (version: number) => number | string;The plugin operates during Babel's transformation phase and relies on Babel's error handling mechanisms. It does not throw custom errors but may fail if:
Common issues and solutions: