├── .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 |
--------------------------------------------------------------------------------