Babel plugin that transforms ECMAScript do expressions into standard JavaScript code. Do expressions allow developers to use block statements as expressions, where the completion value of the final statement becomes the value of the entire do expression. The plugin works by extracting the contents of do expressions and relying on JavaScript's native statement completion semantics.
npm install --save-dev babel-plugin-transform-do-expressionsThe plugin is used through Babel configuration, not direct imports:
.babelrc configuration:
{
"plugins": ["transform-do-expressions"]
}CLI usage:
babel --plugins transform-do-expressions script.jsNode API usage:
require("babel-core").transform("code", {
plugins: ["transform-do-expressions"]
});Do expressions allow complex conditional logic to be embedded as expressions:
// Input: Do expression syntax
let result = do {
if (x > 10) {
'big';
} else {
'small';
}
};
// Output: Transformed to use statement completion values
// The plugin transforms the DoExpression by extracting its body statements
// and relying on JavaScript's statement completion value semantics
let result = (() => {
if (x > 10) {
'big';
} else {
'small';
}
})();JSX Usage Example:
// Input: Complex conditional logic in JSX
const Component = props =>
<div className='myComponent'>
{do {
if(color === 'blue') { <BlueComponent/>; }
if(color === 'red') { <RedComponent/>; }
if(color === 'green') { <GreenComponent/>; }
}}
</div>;
// Output: Transformed JSX
// The plugin extracts the do expression body statements
const Component = props =>
<div className='myComponent'>
{(() => {
if(color === 'blue') { <BlueComponent/>; }
if(color === 'red') { <RedComponent/>; }
if(color === 'green') { <GreenComponent/>; }
})()}
</div>;The plugin uses Babel's AST visitor pattern to transform DoExpression nodes:
babel-plugin-syntax-do-expressions for parsing supportMain export that returns the Babel plugin configuration.
/**
* Default export: Babel plugin factory function
* @returns {Object} Babel plugin configuration object
*/
export default function(): {
inherits: any;
visitor: {
DoExpression: (path: any) => void;
};
};The plugin transforms do expressions through a simple process of extracting block contents:
do {} → undefined (using buildUndefinedNode())replaceWithMultiple()Transformation Logic:
/**
* AST visitor method for DoExpression nodes
* @param {Object} path - Babel AST path object containing the DoExpression node
*/
DoExpression(path) {
const body = path.node.body.body;
if (body.length) {
// Replace the do expression with its body statements
path.replaceWithMultiple(body);
} else {
// Empty do expressions become undefined
path.replaceWith(path.scope.buildUndefinedNode());
}
}Note: This transformation relies on JavaScript's statement completion values - the final statement in a block becomes the completion value of that block.
### Plugin Configuration
The plugin returns a standard Babel plugin configuration object:
The plugin configuration object structure:
```javascript { .api }
{
// Inherits syntax parsing capabilities
inherits: require("babel-plugin-syntax-do-expressions"),
// AST visitor methods
visitor: {
// Visitor method for DoExpression nodes
DoExpression: function(path) {
// Transform logic here
}
}
}Based on the plugin's test suite, here are the actual transformations:
// Empty do expression
do {} // → undefined
// Single expression
do { "foo"; } // → "foo"
// Conditional expression
do {
if (true) {
"bar";
}
} // → "bar" (when condition is true)// Input
let status = do {
if (user.isAdmin) {
'admin';
} else if (user.isModerator) {
'moderator';
} else {
'user';
}
};
// Output: Statement completion values preserved
let status = (() => {
if (user.isAdmin) {
'admin';
} else if (user.isModerator) {
'moderator';
} else {
'user';
}
})();// Input
let result = do {
let temp = expensive_calculation();
if (temp > threshold) {
temp * factor;
} else {
fallback_value;
}
};
// Output: Block contents extracted, completion value preserved
let result = (function() {
let temp = expensive_calculation();
if (temp > threshold) {
temp * factor;
} else {
fallback_value;
}
})();// Input
let value = do {};
// Output
let value = undefined;The plugin handles transformation edge cases:
undefinedThe plugin integrates with Babel's error reporting system for syntax and transformation errors.