├── .gitignore ├── examples └── test.js ├── bin └── es6-template-stringss-jsx ├── Makefile ├── loader.js ├── README.md ├── package.json └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /examples/test.js: -------------------------------------------------------------------------------- 1 | jsx`
Hello
`; 2 | 3 | jsx`
Hello, ${name}
`; 4 | 5 | jsx`
Hello, ${name}! How are ${you}?
`; 6 | 7 | jsx`
`; 8 | 9 | jsx` 10 |
11 |

${title}

12 |
13 | ` 14 | -------------------------------------------------------------------------------- /bin/es6-template-stringss-jsx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /** 3 | * @copyright 2015, Andrey Popp 4 | */ 5 | 'use strict'; 6 | 7 | var recast = require('recast'); 8 | var transformer = require('../'); 9 | 10 | recast.run(function(node, cb) { 11 | transformer.transform(node); 12 | cb(node); 13 | }); 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | BIN := ./node_modules/.bin 2 | 3 | install link: 4 | @npm $@ 5 | 6 | release-patch: test 7 | @$(call release,patch) 8 | 9 | release-minor: test 10 | @$(call release,minor) 11 | 12 | release-major: test 13 | @$(call release,major) 14 | 15 | publish: 16 | git push --tags origin HEAD:master 17 | npm publish 18 | 19 | define release 20 | npm version $(1) 21 | endef 22 | -------------------------------------------------------------------------------- /loader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Webpack Loader 3 | * 4 | * @copyright 2015, Andrey Popp 5 | */ 6 | 'use strict'; 7 | 8 | var transformer = require('./index'); 9 | 10 | function loader(source) { 11 | if (this.cacheable) { 12 | this.cacheable(); 13 | } 14 | var result = transformer.transformString(source); 15 | return result.code; 16 | } 17 | 18 | module.exports = loader; 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ES6 JSX-Tagged Template Strings to JS transform 2 | 3 | This is a syntax transform which transforms ES6 JSX-Tagged Template Strings to 4 | JS. For example: 5 | 6 | var element = jsx` 7 |

8 | Hello, ${name}! 9 |

10 | `; 11 | 12 | is being transformed into: 13 | 14 | var element = React.createElement('p', 15 | 'Hello, ', name 16 | ); 17 | 18 | ## Installation 19 | 20 | % npm install es6-template-strings-jsx 21 | 22 | ## Using with Webpack 23 | 24 | Webpack loader is included as `es6-template-strings-jsx/loader`. 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "es6-template-strings-jsx", 3 | "version": "1.0.1", 4 | "description": "Transform ES6 Tagged Template Strings with JSX into JS", 5 | "main": "index.js", 6 | "directories": { 7 | "example": "examples" 8 | }, 9 | "dependencies": { 10 | "react-tools": "^0.12.2", 11 | "recast": "^0.9.15" 12 | }, 13 | "devDependencies": {}, 14 | "scripts": { 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/andreypopp/es6-template-strings-jsx" 20 | }, 21 | "keywords": [ 22 | "es6", 23 | "jsx", 24 | "template-strings", 25 | "transform", 26 | "webpack", 27 | "webpack-loader" 28 | ], 29 | "author": "Andrey Popp ", 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/andreypopp/es6-template-strings-jsx/issues" 33 | }, 34 | "homepage": "https://github.com/andreypopp/es6-template-strings-jsx" 35 | } 36 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2015, Andrey Popp 3 | */ 4 | 'use strict'; 5 | 6 | var ReactTools = require('react-tools'); 7 | var recast = require('recast'); 8 | var types = recast.types; 9 | var n = types.namedTypes; 10 | var b = types.builders; 11 | 12 | function transform(node) { 13 | recast.visit(node, { 14 | visitTaggedTemplateExpression: function(path) { 15 | this.traverse(path); 16 | var node = path.value; 17 | if (node.tag.name === 'jsx') { 18 | var nodes = node.quasi.quasis.concat(node.quasi.expressions); 19 | nodes.sort(compareLocation); 20 | var source = nodes 21 | .map(function(node) { 22 | if (node.type === 'TemplateElement') { 23 | return node.value.raw; 24 | } else { 25 | return '{' + recast.print(node) + '}'; 26 | } 27 | }) 28 | .join(''); 29 | var result = ReactTools.transform(source); 30 | var nextNode = recast.parse(result).program.body[0].expression; 31 | path.replace(nextNode); 32 | } 33 | } 34 | }); 35 | } 36 | 37 | function transformString(source, options) { 38 | var node = recast.parse(source, options); 39 | transform(node); 40 | return recast.print(node, options) 41 | } 42 | 43 | function compareLocation(a, b) { 44 | a = a.loc.start; 45 | b = b.loc.start; 46 | if (a.line < b.line) { 47 | return -1; 48 | } else if (a.line > b.line) { 49 | return 1; 50 | // Nodes are on the same line. 51 | } else if (a.column < b.column) { 52 | return -1; 53 | } else if (a.column > b.column) { 54 | return 1; 55 | // Impossible. 56 | } else { 57 | throw new Error( 58 | 'Invariant violation: invalid AST structure, nodes have same location'); 59 | } 60 | } 61 | 62 | module.exports = { 63 | transform: transform, 64 | transformString: transformString 65 | }; 66 | --------------------------------------------------------------------------------