-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JSX support By popular demand... This implements very basic support for JSX. Still to do: * Support pragmas other than `React.createElement` * Optimisations (see [here](https://medium.com/doctolib-engineering/improve-react-performance-with-babel-16f1becfaa25#.thsp2ymcd) and [here](facebook/react#3226)) * Some method to auto-import needed modules? (e.g. automatically add `import * as React from 'react'` It's still an open question whether this truly belongs in core, but I do like the convenience of it. Since I don't ever use JSX, I could have completely pooched this up – would welcome input from people more experienced with it. See merge request !37
- Loading branch information
Showing
11 changed files
with
181 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import Node from '../Node.js'; | ||
|
||
export default class JSXAttribute extends Node { | ||
transpile ( code, transforms ) { | ||
code.overwrite( this.name.end, this.value.start, ': ' ); | ||
|
||
super.transpile( code, transforms ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import Node from '../Node.js'; | ||
|
||
export default class JSXClosingElement extends Node { | ||
transpile ( code, transforms ) { | ||
code.remove( this.start, this.end ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import Node from '../Node.js'; | ||
|
||
export default class JSXElement extends Node { | ||
transpile ( code, transforms ) { | ||
code.insertLeft( this.end, `)` ); | ||
|
||
super.transpile( code, transforms ); | ||
|
||
const children = this.children.filter( child => { | ||
return child.type === 'JSXElement' || /\S/.test( child.value ); | ||
}); | ||
|
||
if ( children.length ) { | ||
code.insertLeft( this.openingElement.end, ',' ); | ||
|
||
for ( let i = 0; i < children.length - 1; i += 1 ) { | ||
const child = children[i]; | ||
code.insertLeft( child.end, ',' ); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Node from '../Node.js'; | ||
|
||
export default class JSXExpressionContainer extends Node { | ||
transpile ( code, transforms ) { | ||
code.remove( this.start, this.expression.start ); | ||
code.remove( this.expression.end, this.end ); | ||
|
||
super.transpile( code, transforms ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import Node from '../Node.js'; | ||
|
||
export default class JSXOpeningElement extends Node { | ||
transpile ( code, transforms ) { | ||
code.overwrite( this.start, this.name.start, `${this.program.jsx}( ` ); | ||
|
||
const html = this.name.type === 'JSXIdentifier' && this.name.name[0] === this.name.name[0].toLowerCase(); | ||
if ( html ) code.insertRight( this.name.start, `'` ); | ||
|
||
const len = this.attributes.length; | ||
let c = this.name.end; | ||
|
||
if ( len ) { | ||
code.insertLeft( this.name.end, html ? `', {` : `, {` ); | ||
code.insertLeft( this.attributes[ len - 1 ].end, ' }' ); | ||
|
||
let i; | ||
c = this.attributes[0].end; | ||
|
||
for ( i = 1; i < len; i += 1 ) { | ||
code.overwrite( c, this.attributes[i].start, ', ' ); | ||
c = this.attributes[i].end; | ||
} | ||
} else { | ||
code.insertLeft( this.name.end, `', null` ); | ||
c = this.name.end; | ||
} | ||
|
||
code.remove( c, this.end ); | ||
super.transpile( code, transforms ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
module.exports = [ | ||
{ | ||
description: 'transpiles self-closing JSX tag', | ||
input: `var img = <img src='foo.gif'/>;`, | ||
output: `var img = React.createElement( 'img', { src: 'foo.gif' });` | ||
}, | ||
|
||
{ | ||
description: 'transpiles non-self-closing JSX tag', | ||
input: `var div = <div className='foo'></div>;`, | ||
output: `var div = React.createElement( 'div', { className: 'foo' });` | ||
}, | ||
|
||
{ | ||
description: 'transpiles nested JSX tags', | ||
|
||
input: ` | ||
var div = ( | ||
<div className='foo'> | ||
<img src='foo.gif'/> | ||
<img src='bar.gif'/> | ||
</div> | ||
);`, | ||
|
||
output: ` | ||
var div = ( | ||
React.createElement( 'div', { className: 'foo' }, | ||
React.createElement( 'img', { src: 'foo.gif' }), | ||
React.createElement( 'img', { src: 'bar.gif' }) | ||
) | ||
);` | ||
}, | ||
|
||
{ | ||
description: 'transpiles JSX tag with expression attributes', | ||
input: `var img = <img src={src}/>;`, | ||
output: `var img = React.createElement( 'img', { src: src });` | ||
}, | ||
|
||
{ | ||
description: 'transpiles JSX tag with expression children', | ||
|
||
input: ` | ||
var div = ( | ||
<div> | ||
{ images.map( src => <img src={src}/> ) } | ||
</div> | ||
);`, | ||
|
||
output: ` | ||
var div = ( | ||
React.createElement( 'div', null, | ||
images.map( function (src) { return React.createElement( 'img', { src: src }); } ) | ||
) | ||
);` | ||
}, | ||
|
||
{ | ||
description: 'transpiles JSX component', | ||
input: `var element = <Hello name={name}/>;`, | ||
output: `var element = React.createElement( Hello, { name: name });` | ||
}, | ||
|
||
{ | ||
description: 'transpiles namespaced JSX component', | ||
input: `var element = <Foo.Bar name={name}/>;`, | ||
output: `var element = React.createElement( Foo.Bar, { name: name });` | ||
}, | ||
|
||
{ | ||
description: 'supports pragmas', | ||
options: { jsx: 'NotReact.createElement' }, | ||
input: `var img = <img src='foo.gif'/>;`, | ||
output: `var img = NotReact.createElement( 'img', { src: 'foo.gif' });` | ||
} | ||
]; |