├── .autod.conf.js ├── .editorconfig ├── .gitignore ├── .travis.yml ├── History.md ├── README.md ├── example ├── app.js ├── public │ ├── css │ │ └── main.css │ └── js │ │ ├── bundle.js │ │ ├── components │ │ ├── content.jsx │ │ ├── create.jsx │ │ └── item.jsx │ │ └── main.js ├── views │ ├── index.jsx │ └── layout.jsx └── webpack.config.js ├── index.js ├── package.json └── test ├── index.test.js └── support └── views └── home.jsx /.autod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | write: true, 5 | prefix: '^', 6 | exclude: [ 7 | 'test/fixtures' 8 | ], 9 | devdep: [ 10 | 'autod', 11 | 'mocha', 12 | 'istanbul', 13 | 'should', 14 | 'babel-register', 15 | 'babel-preset-es2015', 16 | 'babel-preset-react' 17 | ], 18 | }; 19 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.seed 2 | *.log 3 | *.csv 4 | *.dat 5 | *.out 6 | *.pid 7 | *.gz 8 | 9 | coverage.html 10 | coverage/ 11 | cov/ 12 | 13 | node_modules 14 | 15 | dump.rdb 16 | .DS_Store 17 | 18 | test.js 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '4' 5 | - '6' 6 | install: 7 | - npm i npminstall && npminstall 8 | script: 9 | - npm run test-cov 10 | after_script: 11 | - npminstall codecov && codecov 12 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 3.0.0 / 2016-07-27 3 | ================== 4 | 5 | * test: use babel 6 6 | * Bump react dependencies to v15. (#19) 7 | 8 | 2.0.0 / 2015-12-22 9 | ================== 10 | 11 | * refactor: remove babel from module's core 12 | 13 | 1.1.0 / 2015-11-12 14 | ================== 15 | 16 | * Allow choice of React rendering method 17 | * Upgrade react 0.13.3 -> 0.14.2 18 | 19 | 1.0.2 / 2015-06-10 20 | ================== 21 | 22 | * fix options.views 23 | 24 | 1.0.1 / 2015-06-08 25 | ================== 26 | 27 | * fix default babel.only 28 | 29 | 1.0.0 / 2015-06-08 30 | ================== 31 | 32 | * init 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | koa-react-view 2 | --------------- 3 | 4 | [![NPM version][npm-image]][npm-url] 5 | [![build status][travis-image]][travis-url] 6 | [![Test coverage][coveralls-image]][coveralls-url] 7 | [![David deps][david-image]][david-url] 8 | [![node version][node-image]][node-url] 9 | 10 | [npm-image]: https://img.shields.io/npm/v/koa-react-view.svg?style=flat-square 11 | [npm-url]: https://npmjs.org/package/koa-react-view 12 | [travis-image]: https://img.shields.io/travis/koajs/react-view.svg?style=flat-square 13 | [travis-url]: https://travis-ci.org/koajs/react-view 14 | [coveralls-image]: https://img.shields.io/coveralls/koajs/react-view.svg?style=flat-square 15 | [coveralls-url]: https://coveralls.io/r/koajs/react-view?branch=master 16 | [david-image]: https://img.shields.io/david/koajs/react-view.svg?style=flat-square 17 | [david-url]: https://david-dm.org/koajs/react-view 18 | [node-image]: https://img.shields.io/badge/node.js-%3E=_0.12-green.svg?style=flat-square 19 | [node-url]: http://nodejs.org/download/ 20 | 21 | A Koa view engine which renders React components on server. 22 | 23 | ## Installation 24 | 25 | ```bash 26 | $ npm install koa-react-view 27 | ``` 28 | 29 | ## Usage 30 | 31 | ```js 32 | var react = require('koa-react-view'); 33 | var path = require('path'); 34 | var koa = require('koa'); 35 | 36 | var app = koa(); 37 | 38 | var viewpath = path.join(__dirname, 'views'); 39 | var assetspath = path.join(__dirname, 'public'); 40 | 41 | react(app, { 42 | views: viewpath 43 | }); 44 | 45 | app.use(function* () { 46 | this.render(home, {foo: 'bar'}); 47 | }); 48 | 49 | ``` 50 | 51 | This module no longer includes the [Babel] runtime, as that prevented developers 52 | from using the runtime on the server outside of the scope of this module. Additionally, 53 | Babel recommends that the polyfill is only included by the parent app to avoid these 54 | conflicts. If you'd like to use JSX, ES6, or other features that require transpiling, 55 | you can include Babel in your project directly. See [example]. 56 | 57 | ### Options 58 | 59 | option | values | default 60 | -------|--------|-------- 61 | `doctype` | any string that can be used as [a doctype](http://en.wikipedia.org/wiki/Document_type_declaration), this will be prepended to your document | `""` 62 | `beautify` | `true`: beautify markup before outputting (note, this can affect rendering due to additional whitespace) | `false` 63 | `views` | the root directory of view files | `path.join(__dirname, 'views')` 64 | `extname` | the default view file's extname | `jsx` 65 | `writeResp` | `true`: writes the body response automatically | `true` 66 | `cache` | `true`: cache all the view files | `process.env.NODE_ENV === 'production'` 67 | `internals` | `true`: include React internals in output | `false` 68 | 69 | ### renderToString vs renderToStaticMarkup 70 | 71 | React provides two ways to render components server-side: 72 | 73 | - [ReactDOMServer.renderToStaticMarkup](https://facebook.github.io/react/docs/top-level-api.html#reactdomserver.rendertostaticmarkup) strips out all the React internals, reducing the size of the output. Best for static sites. 74 | 75 | - [ReactDOMServer.renderToString](https://facebook.github.io/react/docs/top-level-api.html#reactdomserver.rendertostring) maintains React internals, allowing for client-side React to process the rendered markup very speedily. Best for an initial server-side rendering of a client-side application. 76 | 77 | By default, the `ReactDOMServer.renderToStaticMarkup` method will be used. It is possible to use `ReactDOMServer.renderToString` instead (and maintain the React internals) by setting the `internals` option to `true`, or by setting the third parameter of `this.render` to `true` on a case-by-case basis. 78 | 79 | ### `ctx.state` 80 | 81 | `koa-react-view` support [ctx.state](https://github.com/koajs/koa/blob/master/docs/api/context.md#ctxstate) in koa. 82 | 83 | ### [example](example) 84 | 85 | ### License 86 | 87 | MIT 88 | 89 | [Babel]: http://babeljs.io/ 90 | [example]: https://github.com/koajs/react-view/blob/master/example/app.js#L25 91 | -------------------------------------------------------------------------------- /example/app.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * koa-react-view - example/app.js 3 | * MIT Licensed 4 | */ 5 | 6 | 'use strict'; 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var staticCache = require('koa-static-cache'); 13 | var register = require('babel-register'); 14 | var react = require('..'); 15 | var path = require('path'); 16 | var koa = require('koa'); 17 | 18 | var app = koa(); 19 | 20 | var viewpath = path.join(__dirname, 'views'); 21 | var assetspath = path.join(__dirname, 'public'); 22 | 23 | react(app, { views: viewpath }); 24 | 25 | // imports babel runtime for JSX views, warning: live transpiling 26 | // best to precompile in production deploys for perf + reliability 27 | register({ 28 | presets: [ 'es2015', 'react' ], 29 | extensions: [ '.jsx' ], 30 | }); 31 | 32 | app.use(staticCache(assetspath)); 33 | 34 | app.use(function* () { 35 | this.render('index', { 36 | title: 'List', 37 | list: [ 38 | 'hello koa', 39 | 'hello react' 40 | ] 41 | }); 42 | }); 43 | 44 | app.listen(3000); 45 | console.log('server start listen at 3000'); 46 | -------------------------------------------------------------------------------- /example/public/css/main.css: -------------------------------------------------------------------------------- 1 | li { 2 | margin: 10px; 3 | } 4 | .item { 5 | font-size: 18px; 6 | } 7 | 8 | .remove { 9 | margin-left: 10px; 10 | cursor: pointer; 11 | color: #aaa; 12 | } 13 | 14 | .create-box input { 15 | height: 20px; 16 | width: 200px; 17 | margin: 20px; 18 | } 19 | -------------------------------------------------------------------------------- /example/public/js/components/content.jsx: -------------------------------------------------------------------------------- 1 | var Create = require('./create'); 2 | var Item = require('./item'); 3 | var React = require('react'); 4 | 5 | var Content = React.createClass({ 6 | propTypes: { 7 | list: React.PropTypes.array 8 | }, 9 | 10 | getInitialState: function () { 11 | return { 12 | list: this.props.list 13 | }; 14 | }, 15 | 16 | render: function() { 17 | return ( 18 |