{"id":13802095,"url":"https://github.com/bigpipe/react-jsx","last_synced_at":"2025-04-09T14:15:04.727Z","repository":{"id":27812013,"uuid":"31301496","full_name":"bigpipe/react-jsx","owner":"bigpipe","description":"Compile transform your JSX templates into a template engine that works client AND server side","archived":false,"fork":false,"pushed_at":"2020-10-26T13:10:51.000Z","size":85,"stargazers_count":123,"open_issues_count":6,"forks_count":7,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-05-10T01:03:04.139Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bigpipe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-25T07:04:27.000Z","updated_at":"2024-01-28T08:47:50.000Z","dependencies_parsed_at":"2022-08-24T19:41:48.340Z","dependency_job_id":null,"html_url":"https://github.com/bigpipe/react-jsx","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigpipe%2Freact-jsx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigpipe%2Freact-jsx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigpipe%2Freact-jsx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigpipe%2Freact-jsx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bigpipe","download_url":"https://codeload.github.com/bigpipe/react-jsx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054193,"owners_count":21039952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T00:01:35.715Z","updated_at":"2025-04-09T14:15:04.707Z","avatar_url":"https://github.com/bigpipe.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-jsx\n\n[![Version npm][version]](http://browsenpm.org/package/react-jsx)[![Build Status][build]](https://travis-ci.org/bigpipe/react-jsx)[![Dependencies][david]](https://david-dm.org/bigpipe/react-jsx)[![Coverage Status][cover]](https://coveralls.io/r/bigpipe/react-jsx?branch=master)\n\n[from]: https://img.shields.io/badge/from-bigpipe.io-9d8dff.svg?style=flat-square\n[version]: http://img.shields.io/npm/v/react-jsx.svg?style=flat-square\n[build]: http://img.shields.io/travis/bigpipe/react-jsx/master.svg?style=flat-square\n[david]: https://img.shields.io/david/bigpipe/react-jsx.svg?style=flat-square\n[cover]: http://img.shields.io/coveralls/bigpipe/react-jsx/master.svg?style=flat-square\n\nThe `react-jsx` module allows you to compile your JSX (`.jsx`) templates to:\n\n- React's `React.createElement` DOM syntax (default for server and client).\n- React's HTML output.\n- Pure HTML output.\n\nThese templates can be used on the server **and** client. This way you can move\nyour `JSX` templates out of your `React.createClass`'s `render` method and to\nit's own template files which leads to a more manageable code base.\n\nIn addition to the features mentioned above we also eliminated the requirement\nof \"global\" and \"locally\" scoped variables in your template. You can now pass in\nthe data using a `data` argument.\n\nBy using the same templates on the front and back-end you can create\nprogressively enhanced and SEO friendly web pages.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Versioning](#versioning)\n- [Usage](#usage)\n- [Passing data around](#passing-data-around)\n- [Templates](#templates)\n- [Client-side](#client-side)\n- [Output](#output)\n- [Warnings](#warnings)\n- [License](#license)\n\n## Installation\n\nThe module is published in the public npm registry and can be installed using:\n\n```\nnpm install --save react-jsx\n```\n\nAnd that's it! To learn more about how the API works, continue to the [usage]\nsection.\n\n## Versioning\n\nThe minor version of this module is in sync with the version of `react` and\n`react-tools` that we depend upon. Bug fixes to this library will be done as\npatch releases so you should read our versioning as:\n\n```\n\u003creact.major.version\u003e.\u003creact.minor.version\u003e.\u003cour.react-jsx-module.patches\u003e\n```\n\nThe earliest version of react that we support is **0.12**. So please note that\nour 0.0.x releases CAN include a breaking change so when you're adding this\nmodule to your package.json make sure you put down the full semver version.\n\n## Usage\n\nIn all of the examples we assume that you've already required the `jsx` compiler\nas following:\n\n```js\n'use strict';\n\nvar jsx = require('react-jsx');\n```\n\nThis `jsx` variable now contains 3 methods:\n\n- **server** Use this method if you want transform your `jsx` templates for\n  server-side usage. We will automatically inject `React` as global in the\n  templates so it all works as intended. We will return a function which you can\n  call to render your template.\n- **client** Use this method if you want to transform your `jsx` templates for\n  client-side usage. It assumes that React is already available as global on the\n  page. We will return a function which you can call to render you template.\n- **transform** Our internal compiler which transforms the JSX templates to a\n  template API.\n\nBoth the **server** and **client** method share the same API for compiling and\nrendering:\n\n```js\nvar template = fs.readFileSync('template.jsx', 'utf-8');\n\nvar server = jsx.server(template, { /* options */});\nvar client = jsx.client(template, {});\n\nconsole.log(server({ data: 'for template' }));\n```\n\nAnd they also share the same options:\n\n- **filename**: File name of the template file we're about to process. This will\n  be used for debugging purposes in the inlined source map when you've set\n  `debug` to true.\n- **debug**: When set to `true`, we will automatically inline source map.\n- **ecma**: Which ECMA version should the template be compiled towards. It\n  defaults to `es3` for the client and `es5` on the server.\n- **types** Don't use strict types.\n- **raw** This allows you to control how the generated HTML is outputted. By\n  default we output the React generated HTML which is full of `data-react-xxx`\n  attributes. Setting this option to `true` will return a clean HTML instead.\n\nWhen rendering the templates both the server and client method will return the\nexpected `React.createElement` nodes just like you would normally do in your\ntemplates so you can easily share templates with child/parent relations. If you\nwant the template methods. But your might want to output the raw/pure HTML\ninstead. This can be done by supplying `{ html: true }` as option to the\ntemplate function:\n\n```js\nvar template = fs.readFileSync('/path/to/template.jsx', 'utf-8')\n  , render = jsx.server(template, { filename: 'template.jsx' });\n\nconsole.log(render({ foo: 'bar' }, { html: true }));\n```\n\n### Passing data around\n\nThe generated client and server functions accept data or \"scope\" for the\ntemplates as first argument:\n\n```js\nrender({ foo: 'bar' });\n```\n\nIf you want to set a custom `this` context for the template you could call the\nreturned template function as followed:\n\n```js\nrender.call({ custom: 'this', value: 'is possible' });\n```\n\nBut the template function we've generated is smart enough to figure out if\nyou're passing around React instances and will automatically set the supplied\n`data` argument as context:\n\n```js\nvar HelloWorld = React.createClass({\n  render: function render() {\n    return render(this);\n  }\n});\n```\n\nSo in the example above the data argument is set to `this` so it will\nautomatically be introduced as `this` in the template AND all properties and\nmethods will also be introduced as local variables. So if where to mixins the\n`React.Intl` module in the class above your template would have access to\n`\u003cFormattedMessage\u003e` components:\n\n```js\nvar HelloWorld = React.createClass({\n  mixins: [require('react-intl').IntlMixin]\n  render: function render() {\n    return render(this);\n  }\n});\n```\n\nAnd the template that you would render could then contain:\n\n```jsx\n\u003cFormattedMessage\n  message={this.getIntlMessage('post.meta')}\n  num={this.props.post.comments.length}\n  ago={\u003cFormattedRelative value={this.props.post.date} /\u003e}\n/\u003e\n```\n\n### Templates\n\nThe `.jsx` templates that you're creating should only contain the parts that are\ntransformed in to `React.createElement`'s. In addition to that there is no need\nto `return` or `module.exports` the template. This is all taken care of under\nthe hood. The following example would a valid example of this:\n\n```jsx\n\u003cdiv\u003e\n  \u003cinput type=\"text\" value={foo} /\u003e\n\u003c/div\u003e;\n```\n\nWorking with components isn't a problem either, you can still pass them around\nusing the `data` argument of the template function as illustrated in this HTTP\nserver example: \n\n```js\nvar http = require('http')\n  , path = require('path')\n  , React = require('react')\n  , jsx = require('react-jsx')\n  , read = require('fs').readFileSync;\n\nvar templates = {\n  hello: jsx.server(read(path.join(__dirname, 'hello.jsx'), 'utf-8')),\n  index: jsx.server(read(path.join(__dirname, 'index.jsx'), 'utf-8'))\n};\n\nvar HelloWorld = React.createClass({\n  render: function render() {\n    return templates.hello(this);\n  }\n});\n\nhttp.createServer(function (req, res) {\n  res.statusCode = 200;\n  res.setHeader('Content-Type', 'text/html');\n\n  res.end(templates.index({\n    HelloWorld: HelloWorld,\n    title: 'Hello world',\n    another: 'variable'\n  }, { html: true }));\n}).listen(8080);\n```\n\n```jsx\n/* index.jsx */\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003e{title}\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cHelloWorld name={another} /\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n```jsx\n/* hello.jsx */\n\u003cdiv\u003e\n  Hello world, you're just another {this.props.name}\n\u003c/div\u003e\n```\n\n### Client-side\n\nThe client that we generate is a function but is optimized for ES3 so it works\nin older browser versions without any addition hassle. As the `jsx.client()`\nmethod returns a function you might need to transform this to a string if you\nwant to use it for client side templates. The string transformation is quite\neasy to do:\n\n```js\nvar build = 'var mytemplate = '+ jsx.client(template).toString();\n```\n\nThe `.toString()` method automatically transforms the function in to an\nanonymous function. In the example above we saved the template as `mytemplate`\nvariable. So when we store this a JavaScript file to disk using a\n`fs.writeFileSync('/mytemplate.js', build);` we can easily access the\ntemplate on the client side by referencing the `mytemplate` global.\n\nSo with this knowledge, an illustration of this:\n\n```js\nvar Component = React.createClass({\n  render: function render() {\n    return mytemplate({ foo: 'bar' });\n  }\n});\n```\n\n### Output\n\nTo give you an idea about what we're actually generating here, lets take the\nfollowing JSX template and convert it a client and server template:\n\n```jsx\n\u003cdiv\u003e\n  \u003cinput type=\"text\" value={defaultValue} /\u003e\n  \u003cbutton onclick=\"alert('clicked!');\"\u003eClick Me!\u003c/button\u003e\n  \u003cul\u003e\n    {['un', 'deux', 'trois'].map(function(number) {\n      return \u003cli\u003e{number}\u003c/li\u003e;\n    })}\n  \u003c/ul\u003e\n\u003c/div\u003e;\n```\n\nWhen we compile this template for server-side usage with the **raw** and\n**html** options enabled:\n\n```js\nvar server = jsx.server(template, { raw: true });\nconsole.log(server({ defaultValue: 10 }, { html: true }));\n```\n\nIt will generate the following output:\n\n```html\n\u003cdiv\u003e\u003cinput type=\"text\" value=\"10\"\u003e\u003cbutton\u003eClick Me!\u003c/button\u003e\u003cul\u003e\u003cli\u003eun\u003c/li\u003e\u003cli\u003edeux\u003c/li\u003e\u003cli\u003etrois\u003c/li\u003e\u003c/ul\u003e\u003c/div\u003e\n```\n\nAnd with the **raw** option set to **false** it will generate:\n\n```html\n\u003cdiv data-reactid=\".26uh899yvb4\" data-react-checksum=\"-314283895\"\u003e\u003cinput type=\"text\" value=\"10\" data-reactid=\".26uh899yvb4.0\"\u003e\u003cbutton data-reactid=\".26uh899yvb4.1\"\u003eClick Me!\u003c/button\u003e\u003cul data-reactid=\".26uh899yvb4.2\"\u003e\u003cli data-reactid=\".26uh899yvb4.2.0\"\u003eun\u003c/li\u003e\u003cli data-reactid=\".26uh899yvb4.2.1\"\u003edeux\u003c/li\u003e\u003cli data-reactid=\".26uh899yvb4.2.2\"\u003etrois\u003c/li\u003e\u003c/ul\u003e\u003c/div\u003e\n```\n\nBut by default we will just return React.createElement structures:\n\n```js\nvar client = jsx.client(template);\nconsole.log(client({ defaultValue: 10 }));\n```\n\nReturns the expected `React.createElement` structure:\n\n```js\nReact.createElement(\"div\", null,\n  React.createElement(\"input\", {type: \"text\", value: defaultValue}),\n  React.createElement(\"button\", {onclick: \"alert('clicked!');\"}, \"Click Me!\"),\n  React.createElement(\"ul\", null,\n    ['un', 'deux', 'trois'].map(function(number) {\n      return React.createElement(\"li\", null, number);\n    })\n  )\n);\n```\n\n## Warnings\n\nAs we are using the `react-tools` to compile the templates to all the nice\nthings it can happen that it output's \"useful\" information about your templates\nin the terminal. For example for the template used above you would see the\nfollowing warning in your terminal:\n\n```\nWarning: You provided a `value` prop to a form field without an `onChange`\nhandler. This will render a read-only field. If the field should be mutable use\n`defaultValue`. Otherwise, set either `onChange` or `readOnly`.\n```\n\nThere's not really a way to prevent this from happening except for running your\ncode with `NODE_ENV=production` as this will silence the warnings.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigpipe%2Freact-jsx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbigpipe%2Freact-jsx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigpipe%2Freact-jsx/lists"}