A Babel plugin that compiles ES2015 Unicode escapes (\u{XXXX}) to ES5-compatible Unicode escapes (\uXXXX). This enables backward compatibility with older JavaScript engines while preserving proper character encoding for complex Unicode characters, including those requiring surrogate pairs.
npm install --save-dev @babel/plugin-transform-unicode-escapes@babel/helper-plugin-utils, @babel/core (peer dependency)import plugin from "@babel/plugin-transform-unicode-escapes";For CommonJS:
const plugin = require("@babel/plugin-transform-unicode-escapes");Note: This plugin is built using @babel/helper-plugin-utils. If you're developing or extending plugins, you may need:
import { declare } from "@babel/helper-plugin-utils";
import { types as t } from "@babel/core";// babel.config.js
module.exports = {
plugins: ["@babel/plugin-transform-unicode-escapes"]
};import { transform } from "@babel/core";
import plugin from "@babel/plugin-transform-unicode-escapes";
const result = transform(code, {
plugins: [plugin]
});The main export is a Babel plugin created using the declare helper from @babel/helper-plugin-utils.
/**
* Babel plugin that transforms ES2015 Unicode escapes to ES5
* Created using declare() from @babel/helper-plugin-utils
*/
declare function plugin(api: PluginAPI): PluginObject;
interface PluginAPI {
assertVersion(version: number): void;
}
interface PluginObject {
name: string;
manipulateOptions?(opts: any, parserOpts: any): void;
visitor: VisitorObject;
}
interface VisitorObject {
[key: string]: (path: NodePath) => void;
}The plugin returns a standard Babel plugin configuration object with the following properties:
interface TransformUnicodeEscapesPlugin {
/** Plugin identifier name */
name: "transform-unicode-escapes";
/** Configures generator options for proper Unicode handling */
manipulateOptions(opts: { generatorOpts: any }): void;
/** AST visitor object containing transformation rules */
visitor: {
Identifier(path: NodePath<Identifier>): void;
"StringLiteral|DirectiveLiteral"(path: NodePath<StringLiteral | DirectiveLiteral>): void;
TemplateElement(path: NodePath<TemplateElement>): void;
};
}Input:
"\\u{1d49c}"; // ES2015 Unicode escape
"\\u{41}"; // Basic Unicode escapeOutput:
"\\ud835\\udc9c"; // Surrogate pair for characters > U+FFFF
"\\u0041"; // Padded to 4 digitsInput:
`Hello \\u{1f600}`; // Unicode emoji in templateOutput:
`Hello \\ud83d\\ude00`; // Converted to surrogate pairInput:
var obj = {
"\\u{1d49c}": "value", // Unicode key
["\\u{1d49c}"]: "computed" // Computed property with Unicode
};Output:
var obj = {
"\\ud835\\udc9c": "value", // Transformed key
["\\ud835\\udc9c"]: "computed" // Transformed computed property
};The plugin handles several error scenarios:
Unicode escapes in tagged template literals cannot be safely transformed:
// This will throw an error:
tag`Hello \\u{1f600}`;Error message: "Can't replace Unicode escape '\u{1f600}' inside tagged template literals. You can enable '@babel/plugin-transform-template-literals' to compile them to classic strings."
Identifiers with surrogate pairs that cannot be resolved will throw an error:
// This will throw if the identifier cannot be resolved:
var \\u{1d49c}; // Where the Unicode character creates an unresolvable identifier\\u{41} becomes \\u0041)The plugin automatically configures the Babel generator to ensure proper Unicode output by disabling jsesc minimal mode, which prevents unescaped Unicode strings in the output.
// Core types imported from @babel/core and @babel/traverse
import type { NodePath } from "@babel/traverse";
import type {
Identifier,
StringLiteral,
DirectiveLiteral,
TemplateElement
} from "@babel/types";
// Key imported types (not exported by this plugin, but used)
interface NodePath<T = any> {
node: T;
key: string;
parentPath: NodePath;
scope: Scope;
buildCodeFrameError(message: string): Error;
replaceWith(replacement: any): void;
isMemberExpression(opts?: any): boolean;
isOptionalMemberExpression(opts?: any): boolean;
}
interface Scope {
getBinding(name: string): any;
rename(oldName: string, newName: string): void;
generateUid(name: string): string;
}