From 1b2ff33f1ad9994b66bf055b949ac566762ac22d Mon Sep 17 00:00:00 2001 From: Arnout Kazemier Date: Fri, 27 Feb 2015 14:50:26 -0800 Subject: [PATCH] [doc] REWWWRIRIITIE --- README.md | 255 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 200 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 48ff0b3..cb6f971 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,35 @@ [david]: https://img.shields.io/david/bigpipe/react-jsx.svg?style=flat-square [cover]: http://img.shields.io/coveralls/bigpipe/react-jsx/master.svg?style=flat-square -React-jsx allows you to compile your `.jsx` templates files to React's DOM API -for client-side scripts and to pure HTML strings on the server. All with exactly -the same syntax. In addition to that, the generated templates no longer require -global variables in order to work but can be controlled with a dedicated `data` -argument. +The `react-jsx` module allows you to compile your JSX (`.jsx`) templates to: + +- React's `React.createElement` DOM syntax (default for server and client). +- React's HTML output. +- Pure HTML output. + +These templates can be used on the server **and** client. This way you can move +your `JSX` templates out of your `React.createClass`'s `render` method and to +it's own template files which leads to a more manageable code base. + +In addition to the features mentioned above we also eliminated the requirement +of "global" and "locally" scoped variables in your template. You can now pass in +the data using a `data` argument. By using the same templates on the front and back-end you can create progressively enhanced and SEO friendly web pages. +## Table of Contents + +- [Installation](#installation) +- [Versioning](#versioning) +- [Usage](#usage) +- [Passing data around](#passing-data-around) +- [Templates](#templates) +- [Client-side](#client-side) +- [Output](#output) +- [Warnings](#warnings) +- [License](#license) + ## Installation The module is published in the public npm registry and can be installed using: @@ -25,10 +45,27 @@ The module is published in the public npm registry and can be installed using: npm install --save react-jsx ``` +And that's it! To learn more about how the API works, continue to the [usage] +section. + +## Versioning + +The minor version of this module is in sync with the version of `react` and +`react-tools` that we depend upon. Bug fixes to this library will be done as +patch releases so you should read our versioning as: + +``` +.. +``` + +The earliest version of react that we support is **0.12**. So please note that +our 0.0.x releases CAN include a breaking change so when you're adding this +module to your package.json make sure you put down the full semver version. + ## Usage -Lets get started with requiring our `jsx` compiler, this is the same setup we -will use in all our example codes: +In all of the examples we assume that you've already required the `jsx` compiler +as following: ```js 'use strict'; @@ -36,45 +73,116 @@ will use in all our example codes: var jsx = require('react-jsx'); ``` -The `jsx` object will now contain **2** methods: +This `jsx` variable now contains 3 methods: -- **server** Use this method if you want to generate templates that can be run - on your server. It will return a `function` which can be called with a `data` - object and will return a `string` which is the HTML representation. -- **client** Use this method if you want embed your JSX template in client-side - asset files. It returns a `function` which can be called with a `data` object - and will return a `React.createElement` representation. If you want to use - this on the client side you might want to transform it to a string first, but - more on that later. +- **server** Use this method if you want transform your `jsx` templates for + server-side usage. We will automatically inject `React` as global in the + templates so it all works as intended. We will return a function which you can + call to render your template. +- **client** Use this method if you want to transform your `jsx` templates for + client-side usage. It assumes that React is already available as global on the + page. We will return a function which you can call to render you template. +- **transform** Our internal compiler which transforms the JSX templates to a + template API. -Both methods expose the same API and options: +Both the **server** and **client** method share the same API for compiling and +rendering: ```js -jsx.server('your template string', { /* options */}); -jsx.client(fs.readFileSync('template.jsx', 'utf-8'), {}); +var template = fs.readFileSync('template.jsx', 'utf-8'); + +var server = jsx.server(template, { /* options */}); +var client = jsx.client(template, {}); + +console.log(server({ data: 'for template' })); ``` -The following options are supported: +And they also share the same options: -- **filename**: The filename of the provided template string, can be used for - debugging purposes. -- **debug**: When set to `true` we will automatically inline source map. +- **filename**: File name of the template file we're about to process. This will + be used for debugging purposes in the inlined source map when you've set + `debug` to true. +- **debug**: When set to `true`, we will automatically inline source map. - **ecma**: Which ECMA version should the template be compiled towards. It defaults to `es3` for the client and `es5` on the server. - **types** Don't use strict types. -- **raw** This is a server side only options which allows you to switch to a - pure non-react polluted static markup. Normally there's a bunch of - `data-react-x` attributes added to the elements, setting this option to `true` - will remove those. +- **raw** This allows you to control how the generated HTML is outputted. By + default we output the React generated HTML which is full of `data-react-xxx` + attributes. Setting this option to `true` will return a clean HTML instead. + +When rendering the templates both the server and client method will return the +expected `React.createElement` nodes just like you would normally do in your +templates so you can easily share templates with child/parent relations. If you +want the template methods. But your might want to output the raw/pure HTML +instead. This can be done by supplying `{ html: true }` as option to the +template function: ```js var template = fs.readFileSync('/path/to/template.jsx', 'utf-8') , render = jsx.server(template, { filename: 'template.jsx' }); -console.log(render({ foo: 'bar' })); +console.log(render({ foo: 'bar' }, { html: true })); +``` + +### Passing data around + +The generated client and server functions accept data or "scope" for the +templates as first argument: + +```js +render({ foo: 'bar' }); +``` + +If you want to set a custom `this` context for the template you could call the +returned template function as followed: + +```js +render.call({ custom: 'this', value: 'is possible' }); +``` + +But the template function we've generated is smart enough to figure out if +you're passing around React instances and will automatically set the supplied +`data` argument as context: + +```js +var HelloWorld = React.createClass({ + render: function render() { + return render(this); + } +}); +``` + +So in the example above the data argument is set to `this` so it will +automatically be introduced as `this` in the template AND all properties and +methods will also be introduced as local variables. So if where to mixins the +`React.Intl` module in the class above your template would have access to +`` components: + +```js +var HelloWorld = React.createClass({ + mixins: [require('react-intl').IntlMixin] + render: function render() { + return render(this); + } +}); ``` -Example `template.jsx`: +And the template that you would render could then contain: + +```jsx +} +/> +``` + +### Templates + +The `.jsx` templates that you're creating should only contain the parts that are +transformed in to `React.createElement`'s. In addition to that there is no need +to `return` or `module.exports` the template. This is all taken care of under +the hood. The following example would a valid example of this: ```jsx /** @jsx React.DOM */ @@ -84,17 +192,66 @@ Example `template.jsx`: ; ``` -As you can see in the example above you should not `module.exports` or `return` -your `jsx` template but just define it as regular HTML. This module takes care -of the export handling. +Working with components isn't a problem either, you can still pass them around +using the `data` argument of the template function as illustrated in this HTTP +server example: -### Client +```js +var http = require('http) + , path = require('path') + , React = require('react') + , jsx = require('react-jsx') + , read = require('fs').readFileSync + +var templates = { + hello: jsx.server(read(path.join(__dirname, 'hello.jsx'), 'utf-8')), + index: jsx.server(read(path.join(__dirname, 'index.jsx'), 'utf-8')) +}; + +var HelloWorld = React.createClass({ + render: function render() { + return templates.hello(this); + } +}); -As mentioned previously, when you use the `jsx.client()` method it will return a -`function` which returns `React.createElement` nodes. It assumes that `React` is -available as global in your environment. To export this client compatible -template you might want to transform it to a string and include it your build -files. The string transformation is quite easy to do: +http.createServer(function (req, res) { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/html'); + + res.end(templates.index({ + HelloWorld: HelloWorld, + title: 'Hello world', + another: 'variable' + }, { html: true })); +}).listen(8080); +``` + +```jsx +/* index.jsx */ + + + {title} + + + + + +``` + +```jsx +/* hello.jsx */ +
+ Hello world, you're just another {this.props.name} +
+``` + +### Client-side + +The client that we generate is a function but is optimized for ES3 so it works +in older browser versions without any addition hassle. As the `jsx.client()` +method returns a function you might need to transform this to a string if you +want to use it for client side templates. The string transformation is quite +easy to do: ```js var build = 'var mytemplate = '+ jsx.client(template).toString(); @@ -135,12 +292,12 @@ following JSX template and convert it a client and server template: ; ``` -When we compile this template for server-side usage with the **raw** option -enabled: +When we compile this template for server-side usage with the **raw** and +**html** options enabled: ```js var server = jsx.server(template, { raw: true }); -console.log(server); +console.log(server({ defaultValue: 10 }, { html: true })); ``` It will generate the following output: @@ -155,11 +312,11 @@ And with the **raw** option set to **false** it will generate:
  • un
  • deux
  • trois
``` -And last but not least, the client: +But by default we will just return React.createElement structures: ```js var client = jsx.client(template); -console.log(client.toString()); +console.log(client({ defaultValue: 10 })); ``` Returns the expected `React.createElement` structure: @@ -192,18 +349,6 @@ handler. This will render a read-only field. If the field should be mutable use There's not really a way to prevent this from happening except for running your code with `NODE_ENV=production` as this will silence the warnings. -## Versioning - -The minor version of this module is in sync with the version of `react` and -`react-tools` that we depend upon. Bug fixes to this library will be done as -patch releases so you should read our versioning as: - -``` -.. -``` - -The earliest version of react that we support is **0.12**. - ## License MIT