├── .npmignore
├── .babelrc
├── lib
├── __tests__
│ ├── html.jsx
│ └── compile.test.js
└── compile.js
├── .gitignore
├── index.js
├── LICENSE-MIT
├── package.json
└── README.md
/.npmignore:
--------------------------------------------------------------------------------
1 | *.test.js
2 | *.jsx
3 | .babelrc
4 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "es2015", "react" ]
3 | }
4 |
--------------------------------------------------------------------------------
/lib/__tests__/html.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | export default (props) =>
3 | {props.children}
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ignore system files
2 |
3 | # OS X
4 | .DS_Store
5 | .Spotlight-V100
6 | .Trashes
7 | ._*
8 |
9 | # Win
10 | Thumbs.db
11 | Desktop.ini
12 |
13 | # vim
14 | *~
15 | .swp
16 | .*.sw[a-z]
17 | Session.vim
18 |
19 | # Node
20 | node_modules
21 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /* global hexo */
2 | 'use strict'
3 |
4 | var compile = require('./lib/compile')
5 |
6 | function renderer (data, locals) {
7 | return compile(data)(locals)
8 | }
9 |
10 | renderer.compile = compile
11 |
12 | hexo.extend.renderer.register('jsx', 'html', renderer, true)
13 |
--------------------------------------------------------------------------------
/lib/compile.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | var babel = require('babel-core')
4 | var React = require('react')
5 | var ReactDOMServer = require('react-dom/server')
6 | var reval = require('eval')
7 | require('babel-core/register')
8 |
9 | module.exports = function compile (data) {
10 | var js = babel.transform(data.text, { filename: data.path })
11 | var Component = reval(js.code, data.path, null, true)
12 |
13 | return function (locals) {
14 | var element = React.createElement(Component.default || Component, locals)
15 | var markup = ReactDOMServer.renderToStaticMarkup(element)
16 |
17 | if (markup.slice(0, 5).toLowerCase() === '=0.14",
31 | "react-dom": ">=0.14"
32 | },
33 | "devDependencies": {
34 | "babel-preset-es2015": "^6.14.0",
35 | "babel-preset-react": "^6.11.1",
36 | "mocha": "^3.0.0",
37 | "react": "^15.0.0",
38 | "react-dom": "^15.0.0",
39 | "standard": "^8.0.0"
40 | },
41 | "scripts": {
42 | "pre-test": "standard",
43 | "test": "mocha 'lib/__tests__/*.js'"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/__tests__/compile.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | 'use strict'
3 |
4 | const assert = require('assert')
5 | const join = require('path').join
6 | const compile = require('../compile')
7 |
8 | const TEMPLATE_PATH = join(__dirname, 'template.jsx')
9 |
10 | describe('hexo-renderer-react/lib/compile', () => {
11 | it('returns function to render html strings', () => {
12 | const template = `
13 | var React = require('react')
14 | module.exports = React.createClass({
15 | render: function () {
16 | return React.createElement('div', { className: 't1' }, 'test')
17 | }
18 | })
19 | `
20 |
21 | const compiled = compile({ text: template, path: TEMPLATE_PATH })
22 | assert.equal(typeof compiled, 'function')
23 |
24 | const rendered = compiled()
25 | assert.equal(rendered, '
test
')
26 | })
27 |
28 | it('handles es6 and jsx', () => {
29 | const template = `
30 | import React from 'react'
31 | export default () =>
32 | test
33 | `
34 |
35 | const rendered = compile({ text: template, path: TEMPLATE_PATH })()
36 | assert.equal(rendered, 'test
')
37 | })
38 |
39 | it('prepends doctype if top node is html', () => {
40 | const template = `
41 | import React from 'react'
42 | export default () =>
43 | test
44 | `
45 |
46 | const rendered = compile({ text: template, path: TEMPLATE_PATH })()
47 | assert.equal(rendered, '\ntest')
48 | })
49 |
50 | it('handles imported components', () => {
51 | const template = `
52 | import React from 'react'
53 | import Html from './html.jsx'
54 | export default () =>
55 | test
56 | `
57 |
58 | const rendered = compile({ text: template, path: TEMPLATE_PATH })()
59 | assert.equal(rendered, '\ntest')
60 | })
61 |
62 | it('passes locals as props', () => {
63 | const template = `
64 | import React from 'react'
65 | export default (props) =>
66 | {props.message}
67 | `
68 |
69 | const rendered = compile({ text: template, path: TEMPLATE_PATH })({
70 | message: 'Test Message'
71 | })
72 | assert.equal(rendered, 'Test Message
')
73 | })
74 | })
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # hexo-renderer-react
2 |
3 | > Render ES6 React components as hexo templates
4 |
5 | [![npm Version][npm-image]][npm]
6 | [![Dependency Status][deps-image]][deps]
7 | [![Dev Dependency Status][dev-deps-image]][dev-deps]
8 |
9 | [![JS Standard Style][style-image]][style]
10 | [![MIT License][license-image]][LICENSE]
11 |
12 |
13 | ## Install
14 |
15 | ``` bash
16 | $ npm install hexo-renderer-react react react-dom --save
17 | ```
18 |
19 | This requires you to have `react` installed as well.
20 |
21 |
22 | ## Usage
23 |
24 | * Name your components with the `.jsx` extension
25 | * `export default` or `module.exports =` your component class
26 | * ES6/7 syntax and JSX is handled by [`babel`][babel] Version 6
27 | * `.babelrc` Config file [preset requirements][babel-6-setup]:
28 | * [babel-preset-es2015][babel-preset-es2015]
29 | * [babel-preset-react][babel-preset-react]
30 | * [babel-preset-stage-0][babel-preset-stage-0]
31 |
32 | ### Examples
33 |
34 | *layout.jsx*
35 | ```js
36 | import React from 'react';
37 |
38 | export default class extends React.Component {
39 | render() {
40 | return (
41 |
42 |
43 | {this.props.page.title}
44 |
45 |
46 |
47 |
48 |
49 | );
50 | }
51 | }
52 | ```
53 |
54 | *post.jsx*
55 | ```js
56 | import React from 'react';
57 |
58 | export default class extends React.Component {
59 | render() {
60 | return (
61 |
62 |
POST: {this.props.page.title}
63 |
{this.props.page.date.toString()}
64 |
65 | )
66 | }
67 | }
68 | ```
69 |
70 |
71 | ## License
72 |
73 | This software is free to use under the MIT license. See the
74 | [LICENSE-MIT file][LICENSE] for license text and copyright information.
75 |
76 |
77 | [npm]: https://www.npmjs.org/package/hexo-renderer-react
78 | [npm-image]: https://img.shields.io/npm/v/hexo-renderer-react.svg
79 | [deps]: https://david-dm.org/thetalecrafter/hexo-renderer-react
80 | [deps-image]: https://img.shields.io/david/thetalecrafter/hexo-renderer-react.svg
81 | [dev-deps]: https://david-dm.org/thetalecrafter/hexo-renderer-react#info=devDependencies
82 | [dev-deps-image]: https://img.shields.io/david/dev/thetalecrafter/hexo-renderer-react.svg
83 | [style]: https://github.com/feross/standard
84 | [style-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg
85 | [license-image]: https://img.shields.io/npm/l/hexo-renderer-react.svg
86 | [babel]: https://github.com/babel/babel
87 | [babel-6-setup]: http://babeljs.io/blog/2015/10/31/setting-up-babel-6/
88 | [babel-preset-es2015]: https://www.npmjs.com/package/babel-preset-es2015
89 | [babel-preset-react]: https://www.npmjs.com/package/babel-preset-react
90 | [babel-preset-stage-0]: https://www.npmjs.com/package/babel-preset-stage-0
91 | [LICENSE]: https://github.com/thetalecrafter/hexo-renderer-react/blob/master/LICENSE-MIT
92 |
--------------------------------------------------------------------------------