Giter VIP home page Giter VIP logo

express-react-views's Introduction

express-react-views

This is an Express view engine which renders React components on server. It renders static markup and does not support mounting those views on the client.

This is intended to be used as a replacement for existing server-side view solutions, like jade, ejs, or handlebars.


Deprecated

This package is no longer maintained. There are better options, though not all work with Express. I recommend Next.js or Remix.


Usage

npm install express-react-views react react-dom

Note: You must explicitly install react as a dependency. Starting in v0.5, react is a peer dependency here. This is to avoid issues that may come when using incompatible versions.

Add it to your app.

// app.js

var app = express();

app.set('views', __dirname + '/views');
app.set('view engine', 'jsx');
app.engine('jsx', require('express-react-views').createEngine());

Options

Beginning with v0.2, you can now pass options in when creating your engine.

option values default
doctype any string that can be used as a doctype, this will be prepended to your document "<!DOCTYPE html>"
beautify true: beautify markup before outputting (note, this can affect rendering due to additional whitespace) false
transformViews true: use babel to apply JSX, ESNext transforms to views.
Note: if already using babel-register in your project, you should set this to false
true
babel any object containing valid Babel options
Note: does not merge with defaults
{presets: ['@babel/preset-react', [ '@babel/preset-env', {'targets': {'node': 'current'}}]]}

The defaults are sane, but just in case you want to change something, here's how it would look:

var options = { beautify: true };
app.engine('jsx', require('express-react-views').createEngine(options));

Views

Under the hood, Babel is used to compile your views to code compatible with your current node version, using the react and env presets by default. Only the files in your views directory (i.e. app.set('views', __dirname + '/views')) will be compiled.

Your views should be node modules that export a React component. Let's assume you have this file in views/index.jsx:

var React = require('react');

function HelloMessage(props) {
  return <div>Hello {props.name}</div>;
}

module.exports = HelloMessage;

Routes

Your routes would look identical to the default routes Express gives you out of the box.

// app.js

app.get('/', require('./routes').index);
// routes/index.js

exports.index = function(req, res){
  res.render('index', { name: 'John' });
};

That's it! Layouts follow really naturally from the idea of composition.

Layouts

Simply pass the relevant props to a layout component.

views/layouts/default.jsx:

var React = require('react');

function DefaultLayout(props) {
  return (
    <html>
      <head><title>{props.title}</title></head>
      <body>{props.children}</body>
    </html>
  );
}

module.exports = DefaultLayout;

views/index.jsx:

var React = require('react');
var DefaultLayout = require('./layouts/default');

function HelloMessage(props) {
  return (
    <DefaultLayout title={props.title}>
      <div>Hello {props.name}</div>
    </DefaultLayout>
  );
}

module.exports = HelloMessage;

Questions

What about partials & includes?

These ideas don't really apply. But since they are familiar ideas to people coming from more traditional "templating" solutions, let's address it. Most of these can be solved by packaging up another component that encapsulates that piece of functionality.

What about view helpers?

I know you're used to registering helpers with your view helper (hbs.registerHelper('something', ...))) and operating on strings. But you don't need to do that here.

  • Many helpers can be turned into components. Then you can just require and use them in your view.
  • You have access to everything else in JS. If you want to do some date formatting, you can require('moment') and use directly in your view. You can bundle up other helpers as you please.

Where does my data come from?

All "locals" are exposed to your view in this.props. These should work identically to other view engines, with the exception of how they are exposed. Using this.props follows the pattern of passing data into a React component, which is why we do it that way. Remember, as with other engines, rendering is synchronous. If you have database access or other async operations, they should be done in your routes.

Caveats

  • I'm saying it again to avoid confusion: this does not do anything with React in the browser. This is only a solution for server-side rendering.
  • This currently uses require to access your views. This means that contents are cached for the lifetime of the server process. You need to restart your server when making changes to your views. In development, we clear your view files from the cache so you can simply refresh your browser to see changes.
  • React & JSX have their own rendering caveats. For example, inline <script>s and <style>s will need to use dangerouslySetInnerHTML={{__html: 'script content'}}. You can take advantage of ES6 template strings here.
<script dangerouslySetInnerHTML={{__html: `
  // Google Analytics
  // is a common use
`}} />
  • It's not possible to specify a doctype in JSX. You can override the default HTML5 doctype in the options.

Contributors

express-react-views's People

Contributors

ajacksified avatar andrerpena avatar arthurfranca avatar bernabefelix avatar boblauer avatar dependabot[bot] avatar dijonkitchen avatar ekryski avatar gaearon avatar jillesme avatar kasparsklavins avatar lijunle avatar peterlau avatar randomailer avatar svenkatreddy avatar tenorviol avatar vikeen avatar zpao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

express-react-views's Issues

Manage js loading order

So,I got a default layout like this,the common javascript is import in the bottom of the page.

var React = require('react');

var DefaultLayout = React.createClass({
  render: function () {
    return (
      <html>
      <head>
        <title>{this.props.title}</title>
        <link href="/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
        <link href="/bower_components/metisMenu/dist/metisMenu.min.css" rel="stylesheet"/>
        <link href="/stylesheets/sb-admin-2.css" rel="stylesheet"/>
        <link href="/bower_components/bootstrap-social/bootstrap-social.css" rel="stylesheet"/>
        <link href="/bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"/>

      </head>
      <body role="document" ontuchstart="">
      {this.props.children}
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
        <script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
        <script src="/bower_components/metisMenu/dist/metisMenu.min.js"></script>
        <script src="/bower_components/datatables/media/js/jquery.dataTables.min.js"></script>
        <script src="/bower_components/datatables-plugins/integration/bootstrap/3/dataTables.bootstrap.min.js"></script>
        <script src="/js/sb-admin-2.js"></script>
        <script src="/bower_components/react/JSXTransformer.js"></script>
        <script src="/bower_components/react/react-with-addons.js"></script>
        <script src="/bower_components/ReactiveElements/dist/reactive-elements.js"></script>
      </body>
      </html>
    );
  }
});

module.exports = DefaultLayout;

But in another page,I need to import another js file,

var React = require('react');
var DefaultLayout = require('../layouts/default');
var Navigation = require('../components/navigation');

module.exports = React.createClass({
  render: function () {
    var data = this.props.session;
    return (
      <DefaultLayout title="Forms">
        <div id="wrapper">
          {/* Navigation */}
          <Navigation></Navigation>
          <div id="page-wrapper">
            <div className="row row-same-height">
              <div className="col-xs-12 col-xs-height"><h3>Forms / Create a new form</h3></div>
            </div>
            <div id="form-wrapper">
            </div>
          </div>
        </div>
        <script type="text/jsx" src="/js/Forms.add.js"></script>
      </DefaultLayout>
    );
  }
});

But in this case,the Forms.add.js wont loader after all the js files in the DefaultLayout layout.so I create a script component.

var Scirpts = React.createClass({
  render: function () {
    return (
      <div style={{display: 'none'}}>
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
        <script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
        <script src="/bower_components/metisMenu/dist/metisMenu.min.js"></script>
        <script src="/bower_components/datatables/media/js/jquery.dataTables.min.js"></script>
        <script src="/bower_components/datatables-plugins/integration/bootstrap/3/dataTables.bootstrap.min.js"></script>
        <script src="/js/sb-admin-2.js"></script>
        <script src="/bower_components/react/JSXTransformer.js"></script>
        <script src="/bower_components/react/react-with-addons.js"></script>
        <script src="/bower_components/ReactiveElements/dist/reactive-elements.js"></script>
      </div>
    );
  }
});

All my js files has to wrap in a div.How to do this in a right way?

Error during installation `The package react does not satisfy its siblings' peerDependencies requirements`

Hello. I'm getting an error during installation using npm install --save express-react-views react.

npm WARN unmet dependency /Users/oleks/projects/mine/testreact/node_modules/express-react-views/node_modules/node-jsx requires react-tools@'^0.12.1' but will load
npm WARN unmet dependency /Users/oleks/projects/mine/testreact/node_modules/express-react-views/node_modules/react-tools,
npm WARN unmet dependency which is version 0.12.2
npm ERR! peerinvalid The package react does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants react@^0.12.0

npm ERR! System Darwin 13.4.0
npm ERR! command "node" "/usr/local/bin/npm" "install" "--save" "express-react-views" "react"
npm ERR! cwd /Users/oleks/projects/mine/testreact
npm ERR! node -v v0.10.32
npm ERR! npm -v 1.4.28
npm ERR! code EPEERINVALID

My first thought was that something is wrong with my project's dependencies, but i've created a new project from scratch:

> mkdir testreact
> cd testreact/
> npm init
> npm install --save express-react-views react

And still get the same error :( Probably something wrong with the dependencies, but i'm not sure which ones are conflicting. Thanks for looking into this.

Support react 15.0.0

React just updated to version 15.0.0. This repository is still using react 0.14.0. When running npm install --save react@^15.0.0 react-dom@^15.0.0 an error occurs.

npm ERR! Darwin 15.3.0
npm ERR! argv "/usr/local/Cellar/node/4.1.2/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v4.1.2
npm ERR! npm  v2.14.6
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package [email protected] does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants react@^0.14.0

ES6 template is not working

How to make ES6 template working?

<DefaultLayout title={this.props.title}>
        <script dangerouslySetInnerHTML={{__html:`
          function test(a){
            alert(a);
          }
          test();
        `}} />
</DefaultLayout>

I got error React.createElement("script", {dangerouslySetInnerHTML: {__html: ^ Unexpected token ILLEGAL`

Use React.renderComponentToString to work with client side render

According to React's doc, renderComponentToString does same thing like renderComponentToStaticMarkup but keeps the React data attributes, which can be used in the client side render. But, it is using renderComponentToStaticMarkup function here.

If you call React.renderComponent() on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience.

So, I think use renderComponentToString is better, any concern not to do it?

Partial support es6 classes

I create es6 react view. I have some problem with static props and instance props

Unexpected token (7:18) export default class CurrentProduct extends React.Component { static errors = { ^ }

Render es2015 jsx in server side error

The log object is undefined.
My Log:

error:  TypeError: Cannot call method 'error' of undefined
    at OptionManager.mergeOptions (/home/kautism/workspace/mail/node_modules/express-react-views/node_modules/babel-core/lib/transformation/file/options/option-manager.js:126:29)
    at OptionManager.addConfig (/home/kautism/workspace/mail/node_modules/express-react-views/node_modules/babel-core/lib/transformation/file/options/option-manager.js:107:10)
    at OptionManager.findConfigs (/home/kautism/workspace/mail/node_modules/express-react-views/node_modules/babel-core/lib/transformation/file/options/option-manager.js:168:35)
    at OptionManager.init (/home/kautism/workspace/mail/node_modules/express-react-views/node_modules/babel-core/lib/transformation/file/options/option-manager.js:229:12)
    at compile (/home/kautism/workspace/mail/node_modules/express-react-views/node_modules/babel-core/lib/api/register/node.js:117:22)
    at normalLoader (/home/kautism/workspace/mail/node_modules/express-react-views/node_modules/babel-core/lib/api/register/node.js:199:14)
    at Object.require.extensions.(anonymous function) [as .jsx] (/home/kautism/workspace/mail/node_modules/express-react-views/node_modules/babel-core/lib/api/register/node.js:216:7)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at View.renderFile [as engine] (/home/kautism/workspace/mail/node_modules/express-react-views/index.js:43:23)
    at View.render (/home/kautism/workspace/mail/node_modules/express/lib/view.js:126:8)
    at tryRender (/home/kautism/workspace/mail/node_modules/express/lib/application.js:639:10)
    at EventEmitter.render (/home/kautism/workspace/mail/node_modules/express/lib/application.js:591:3)
    at ServerResponse.render (/home/kautism/workspace/mail/node_modules/express/lib/response.js:961:7)

This jsx can be compile by my client side compiler
jsx:

'use strict'
import React from 'react';
import {render} from 'react-dom';
import DefaultLayout from './layouts/DefaultLayout.jsx';
import CommandBar from './Component/CommandBar.jsx';
import LogList from './Component/LogList.jsx';
import PageController from './Component/PageController.jsx';
if (/*global*/typeof window !== 'undefined') {
    require('jquery');
    require('bootstrap');
}

class LoglistPage extends  React.Component {
    static defaultProps(){
        return {
            title: 'NoTitle'
        };
    }

    render(){
        return (
            <DefaultLayout>
                <h1>AutoTest List</h1>
                <hr />
                <CommandBar></CommandBar>
                <LogList></LogList>
                <PageController></PageController>
            </DefaultLayout>
        );
    }
};

export default LoglistPage;

My .babelrc

{
  "presets" : ["react", "es2015"]
}

Updated Example with Express 4 and BabelJS

Hi There,

I am trying to create a CMS that uses ReactJS as the view layer.

The CMS itself should be the latest version of Express and using BabelJS to give me ES2015 syntax all throughout the project.

I am kind of a laymen when it comes the the differences between Express 3.5 vs 4.x.

So I was hoping someone could either update the examples, or give me a few pointers.

Here is my project on github: multiDomainCMS

So far no major bugs that I couldn't fix myself.

But I could really use some pointers on deploying this to production!

Thanks for all your hard work!

-Robert Baindourov

Error with babel when using babel/register

I'm encountering the following error in a small project I'm working on:

Error: only one instance of babel/polyfill is allowed
   at Object.<anonymous> (/Users/Alex/code/projects/marketplace/node_modules/express-react-views/node_modules/babel/node_modules/babel-core/lib/babel/polyfill.js:16:9)
   at Module._compile (module.js:460:26)
   at Module._extensions..js (module.js:478:10)
   at Object.require.extensions.(anonymous function) [as .js] (/Users/Alex/code/projects/marketplace/node_modules/babel/node_modules/babel-core/lib/babel/api/register/node.js:215:7)
   at Module.load (module.js:355:32)
   at Function.Module._load (module.js:310:12)
   at Module.require (module.js:365:17)
   at require (module.js:384:17)
   at Object.<anonymous> (/Users/Alex/code/projects/marketplace/node_modules/express-react-views/node_modules/babel/node_modules/babel-core/lib/babel/api/register/node-polyfill.js:11:1)
   at Module._compile (module.js:460:26)
   at Module._extensions..js (module.js:478:10)
   at Object.require.extensions.(anonymous function) [as .js] (/Users/Alex/code/projects/marketplace/node_modules/babel/node_modules/babel-core/lib/babel/api/register/node.js:215:7)
   at Module.load (module.js:355:32)
   at Function.Module._load (module.js:310:12)
   at Module.require (module.js:365:17)
   at require (module.js:384:17)

The entry file for the server has require('babel/register'); in order to use ES6 style imports, etc. throughout the rest of the project. But it seems like there's a conflict between this package's babel and the project's. Any idea why there's a conflict, or is this totally on my end?

update to babel 6: Couldn't find preset "es2015" relative to express views directory

Hi,

I recently upgraded to express-react-views 0.0.10 and got into production issues when trying to deploy.
I have a setup with a client-side react app which is not rendered server-side and then also one react component which is rendered on the server using express-react-views.

When I did the upgrade everything went smooth locally but on the server with NODE_ENV=production I encountered the following issue:

Error: Couldn't find preset "es2015" relative to directory "/path/to/code/server/views"
    at /path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/options/option-manager.js:405:17
    at Array.map (native)
    at OptionManager.resolvePresets (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/options/option-manager.js:397:20)
    at OptionManager.mergePresets (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/options/option-manager.js:381:10)
    at OptionManager.mergeOptions (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/options/option-manager.js:340:14)
    at OptionManager.init (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/options/option-manager.js:498:10)
    at compile (/path/to/code/node_modules/express-react-views/node_modules/babel-register/lib/node.js:81:45)
    at loader (/path/to/code/node_modules/express-react-views/node_modules/babel-register/lib/node.js:126:14)
    at Object.require.extensions.(anonymous function) [as .jsx] (/path/to/code/node_modules/express-react-views/node_modules/babel-register/lib/node.js:136:7)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at View.renderFile [as engine] (/path/to/code/node_modules/express-react-views/index.js:50:23)
    at View.render (/path/to/code/node_modules/express/lib/view.js:126:8)
    at tryRender (/path/to/code/node_modules/express/lib/application.js:639:10)
    at EventEmitter.render (/path/to/code/node_modules/express/lib/application.js:591:3)
    at ServerResponse.render (/path/to/code/node_modules/express/lib/response.js:961:7)
    at discountsFragment (/path/to/code/server/routes/discounts.js:29:23)
    at tryCatcher (/path/to/code/node_modules/request-promise/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler (/path/to/code/node_modules/request-promise/node_modules/bluebird/js/main/promise.js:507:31)
    at Promise._settlePromiseAt (/path/to/code/node_modules/request-promise/node_modules/bluebird/js/main/promise.js:581:18)

Trying locally with the following steps:

package.json includes among express also express-react-views in the dependencies.
devDependencies are, among other things:

"babel-core": "^6.6.0",
    "babel-eslint": "^5.0.0",
    "babel-loader": "^6.2.4",
    "babel-plugin-react-transform": "^2.0.0",
    "babel-plugin-transform-react-display-name": "^6.5.0",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babel-runtime": "^6.6.1",

run NODE_ENV=production npm install followed by NODE_ENV=production npm prune.
Then run the server using NODE_ENV=production npm start.

Now accessing the route which should render the JSX view I get the error above.
I tinkered around a bit, and tried moving babel-preset-es2015 from the devDependencies to the dependencies. This yielded another error:

ReferenceError: [BABEL] /path/to/code/server/views/some-view.jsx: Unknown option: base.Children. Check out http://babeljs.io/docs/usage/options/ for more info
    at Logger.error (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/logger.js:41:11)
    at OptionManager.mergeOptions (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/options/option-manager.js:300:20)
    at OptionManager.init (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/options/option-manager.js:498:10)
    at File.initOptions (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/index.js:206:75)
    at new File (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/index.js:124:22)
    at Pipeline.transform (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/transformation/pipeline.js:44:16)
    at Object.transformFileSync (/path/to/code/node_modules/express-react-views/node_modules/babel-register/node_modules/babel-core/lib/api/node.js:124:10)
    at compile (/path/to/code/node_modules/express-react-views/node_modules/babel-register/lib/node.js:98:20)
    at loader (/path/to/code/node_modules/express-react-views/node_modules/babel-register/lib/node.js:126:14)
    at Object.require.extensions.(anonymous function) [as .jsx] (/path/to/code/node_modules/express-react-views/node_modules/babel-register/lib/node.js:136:7)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at View.renderFile [as engine] (/path/to/code/node_modules/express-react-views/index.js:50:23)
    at View.render (/path/to/code/node_modules/express/lib/view.js:126:8)
    at tryRender (/path/to/code/node_modules/express/lib/application.js:639:10)
    at EventEmitter.render (/path/to/code/node_modules/express/lib/application.js:591:3)
    at ServerResponse.render (/path/to/code/node_modules/express/lib/response.js:961:7)
    at discountsFragment (/path/to/code/server/routes/discounts.js:29:23)
    at tryCatcher (/path/to/code/node_modules/request-promise/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler (/path/to/code/node_modules/request-promise/node_modules/bluebird/js/main/promise.js:507:31)

After also moving babel-preset-react from the devDependencies to the dependencies it seems to work now (locally at least, deployment to production is in progress).

I wonder whether I did something wrong or this is something which should be stated in the README?
If my steps to reproduce are unclear, I'll try to create a small repo which shows the issue.

Handling events/onClick

Hello,

I have the following JSX component:

/** @jsx React.DOM */

var React = require('react');
var VideoPlayer = require('../iplayer');

var createFeedItem = function(feedId){
  var activeFeedId = this.state.activeFeed;

  return <dd className={'feed ' + (feedId === activeFeedId ? 'active' : '')} key={feedId}>
    <a href={'#' + feedId} onClick={this.activateFeed}>{feedId.toUpperCase()}</a>
  </dd>
};

var VideoComponent = React.createClass({
  getInitialState: function(){
    return {
      activeFeed: 'bbc1'
    };
  },
  activateFeed: function(event){
    this.setState({ activeFeed: false});
  },
  render: function(){
    var feeds = this.props.streams.map(createFeedItem, this);

    return (<div>
      <div className="panel">
        <h1 className="hd">{this.props.title}</h1>

        <dl className="feeds-switcher">
          <dt>Switch to Feed:</dt>
          {feeds}
        </dl>
      </div>
      <div className="panel control-panel">
        <VideoPlayer feed={this.state.activeFeed} />
      </div>
    </div>);
  }
});

module.exports = VideoComponent;

The thing is the onClick is removed from the view and I do not see where I could grab the possibly generated autobinding/delegation JS code.

Maybe I am missing something. Maybe I am missing how I should implement the same reactified view on the client side.

Error Logging

I love using React as the view engine with express, but I have found debugging to be an issue.

When I encounter basic errors with React (in render() generally) I am unable to see the error message. I can use logging statements in my components if my component will compile, but when it doesn't compile I receive no error message.

Is there any way to expose this? It would be very useful for debugging. My application is very simple for the time being, and it would be great to get this in sooner rather than later.

Can't include attributes for <head>

I'm trying to implement opensearch with autodiscovery, which requires <head profile="http://a9.com/-/spec/opensearch/1.1/"> property but the profile property gets stripped away. Quite by accident, I discovered that it doesn't do this in the case of <head property="anything">, which is quite odd.

How to make express-react-views and the frontend react component work together?

I used to use Jade as my Views engine, now I change it to express-react-views.
Everything runs ok, but I got a problem....and it makes me confused.
For example, I make a layout component from the server side and store it in views folder and then make an other frontend component by using the frontend react and store it in public folder.
Now the problem hits....I can not render the frontend component when I put it into the server side layout component.
How can I fix it?
urgently~~

Twitter Images don't shown

Hi,

I've just finished chapter number 7 and I've runned de application. I did npm start on snapkite-engine folder and gulp on my snapterest folder but when I go to broswer I don't see images, only text Waiting for public photos from Twitter...Your collection is empty.

If I try to do the same on your examples folder (ES6 version) I have the same issue.

I don't have js errors and I'm using Win 10.

Do you have any idea of which could be the problem?

Thanks.

A better way to work with web components?

Due to JSX's rule,we can't put a custom element in reactjs.For now I could come up the idea is

<div dangerouslySetInnerHTML={{__html:`
            <paper-button></paper-button>
            `}}/>

Is there a better way to do this?

express-react-views

when i pull and setup dynamic views it give me error : Uncaught ReferenceError: main is not defined

how to manage onsubmit event of a form

Hi I'm a beginner to react. I understand that express-react-views can handle the server side rendering of view. In that i don't need to write javascript externally. correct me if i'm wrong,

Now I was going through the react tutorial https://facebook.github.io/react/docs/tutorial.html.
I want to handle the onsumit event of a form,

var AuthForm = React.createClass({
    handleSubmit: function (e) {
        e.preventDefault();
        console.log("submit event fired!!")
       // do something
    },
    render: function () {
        return (
                    <form className="AuthForm"  onSubmit={this.handleSubmit}>
                                <input type="text" placeholder="Username" />
                                <input type="text" placeholder="code" />
                                <input type="submit" value="Login" className="button" />
                    </form>
               );
    }
})

Failed to lookup view in views directory

Hi,

I'm experimenting with express-react-views, and the view engine is unable to lookup any view.

Here's what I have so far that I find relevant.

.
├── config
│   └── application.js
├── app
    └── views
        └── index.jsx
// config/application.js
const Express = require('express');
const path = require('path');

const app = Express();

// React views
app.set('views', path.resolve(__dirname, '../app/views'));
app.set('view engine', 'jsx');
app.engine('jsx', require('express-react-views').createEngine());

app.get('/', function (req, res) {
  res.render('index');
});

app.listen(process.env.PORT, function () {
  console.log('Server listening on port', process.env.PORT);
});
// app/views/index.jsx
import React from 'React';

export default class Index extends React.Component {
  render() {
    return (
      <!doctype html>
      <html>
        <head>
          <meta charset="utf-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1" />
          <title>Hello!</title>
        </head>
        <body>
        </body>
      </html>
    );
  }
}

And here's the error.

➔ node config/application.js
Server listening on port 3000
::1 - - [30/Apr/2016:07:17:36 +0000] "GET / HTTP/1.1" 500 1382 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36"
Error: Failed to lookup view "index" in views directory "/Users/ruipereira/code/deltaworx/webclient/app/views"
    at EventEmitter.render (/Users/ruipereira/code/deltaworx/webclient/node_modules/express/lib/application.js:579:17)
    at ServerResponse.render (/Users/ruipereira/code/deltaworx/webclient/node_modules/express/lib/response.js:961:7)
    at /Users/ruipereira/code/deltaworx/webclient/config/application.js:23:7
    at Layer.handle [as handle_request] (/Users/ruipereira/code/deltaworx/webclient/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/ruipereira/code/deltaworx/webclient/node_modules/express/lib/router/route.js:131:13)
    at Route.dispatch (/Users/ruipereira/code/deltaworx/webclient/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/ruipereira/code/deltaworx/webclient/node_modules/express/lib/router/layer.js:95:5)
    at /Users/ruipereira/code/deltaworx/webclient/node_modules/express/lib/router/index.js:277:22
    at Function.process_params (/Users/ruipereira/code/deltaworx/webclient/node_modules/express/lib/router/index.js:330:12)
    at next (/Users/ruipereira/code/deltaworx/webclient/node_modules/express/lib/router/index.js:271:10)

Am I missing something? I would appreciate any help. CCing @zpao Thanks.

Output javascript objects?

How to output javascript objects so we could use it for front-end pages?
maybe like this:

<script dangerouslySetInnerHTML={{__html:`
            var data = JSON.parse({this.props.users});
            console.log(data);
            `}}/>

value in select element not works.

According to why-select-value.

<div className="form-group">
                <label htmlFor="role">Role</label>
                <select className="form-control" id="role" name="role" value="Editor">
                  <option value="Register">Register</option>
                  <option value="Editor">Editor</option>
                  <option value="Administrator">Administrator</option>
                </select>
              </div>

But the second option not got selected.

Documentation for createEngine() example is incomplete?

The example shows:

app.engine('jsx', require('express-react-views').createEngine());

But that doesn't work, giving:

TypeError: Cannot read property 'jsx' of undefined

because it expects a jsx key in the configuration:

app.engine('jsx', require('express-react-views').createEngine({ jsx: {} }));

works however.

Clear cache not work after render throws exception

Repro steps:

  1. In development mode, render a view which throws exception. For example, TypeError: Cannot read property 'length' of undefined.
  2. Add console.log to the view for debugging the issue.
  3. Console output nothing.
  4. Restart server, console comes back.

I am not sure if it is related to Babel (#45).

Views in a sub-directory

I have a view in a sub-directory
views/form/list.jsx
can I use it in this way?or how can I use it?

res.render('form/list',{forms: forms});

Very slow if render more than 50 entries

I am sure it is not the mongodb issue,because I have another api to get more than 50 entries each request,pretty fast,but when render with express-react-views,it's take more then 3's to get it done.
My page has 4 components,each has two or one loops for the data,I don't think this will be the issue for javascript,and the whole response only has 3KB.Is there any thing I can do?

I can't seem to use ES6 modules

I'm considering using express-react-views, however, I've run into a problem with the simplest examples while using ES6.

Here's how my View look like:

import React from 'react';
import DefaultLayout from './layouts/default';

var HelloMessage = React.createClass({
    render: function() {
        return (
            <DefaultLayout title={this.props.title}>
                <div>Hello {this.props.name}</div>
            </DefaultLayout>
        );
    }
});

export default HelloMessage;

Error:

SyntaxError: Unexpected reserved word
   at exports.runInThisContext (vm.js:73:16)
   at Module._compile (module.js:443:25)
   at Object.require.extensions.(anonymous function) [as .jsx] (C:\Projects\Git\gearz-node\node_modules\express-react-views\node_modules\node-jsx\index.js:26:12)
   at Module.load (module.js:355:32)
   at Function.Module._load (module.js:310:12)
   at Module.require (module.js:365:17)
   at require (module.js:384:17)
   at View.renderFile [as engine] (C:\Projects\Git\gearz-node\node_modules\express-react-views\index.js:44:23)
   at View.render (C:\Projects\Git\gearz-node\node_modules\express\lib\view.js:93:8)
   at EventEmitter.app.render (C:\Projects\Git\gearz-node\node_modules\express\lib\application.js:566:10)

Is there anything I can do to make it work? Using babel or something?

Thanks very much.

recommendations for serving front end?

Hidy ho friends,

Curious what your recommendations are for serving front end with react.js and mounting those views on the client along side express-react-views?

How to input (redis) database info into React templates/props?

I am trying to build my first app, and I'm using a Redis/Express/React stack, with express-react-views doing the rendering of my React templates. I've followed the README.md pretty well, but would now like to include data from my database into the React templates.

How can I go about doing that? My best guess is adding a callback to app.get('/', require('./routes').index);, which somehow inserts the database data into props or JS vars (which would then get put into React somehow?). That part is what I would like to know.

Thanks,
&!

Is it isomorphic?

hi,I'm using handlebars but don't know should I using react as a template engine,is it possible to automatic update part of page when server updated?

Kill js-beautifier?

Projects using express-react-views will fail Mocha's global leak checker (checkGlobals):

  2) / should say "hello":
     Error: global leak detected: input_char

Removing js-beautifier solves the problem. I think the root issue is https://github.com/beautify-web/js-beautify/blob/04645a19b2a3ed05cff177644016ee89c5343d19/js/lib/beautify-html.js#L479

In any case I highly recommend removing js-beautifier from this project due to the possibility of incredibly annoying and unprofessional errors which can arise from altering the TextNodes in the DOM between dev and prod builds.

TypeError: Cannot read property 'props' of undefined

In the index.jsx file , if I don't use this.props, it will be OK:

const React = require('react');

let App = React.createClass({
    render: () => {
        return (

            <div>
                Hello,this is jsx!
            </div>
        );
    }
});

module.exports = App;

Here is the renderd html :

<!DOCTYPE html><div>Hello,this is jsx!</div>

If I want to use this.props, it will throw an error, and here is my code below:

const React = require('react');

let App = React.createClass({
    render: () => {
        return (

            <div>
                Hello,this is jsx!{this.props.name}
            </div>
        );
    }
});

module.exports = App;

In server.js , the code is like this:

app.get('/',(req,res)=>{

    res.render('index', { name: 'John' });

});

The error log:

TypeError: Cannot read property 'props' of undefined
    at [object Object].render (/Users/xinhengs/Desktop/QunarDevs/qact/webapps/views/index.jsx:8:36)
    at [object Object].ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (/Users/xinhengs/Desktop/QunarDevs/qact/server/node_modules/react/lib/ReactCompositeComponent.js:587:34)
    at [object Object].ReactCompositeComponentMixin._renderValidatedComponent (/Users/xinhengs/Desktop/QunarDevs/qact/server/node_modules/react/lib/ReactCompositeComponent.js:607:32)
    at [object Object].wrapper [as _renderValidatedComponent] (/Users/xinhengs/Desktop/QunarDevs/qact/server/node_modules/react/lib/ReactPerf.js:66:21)
    at [object Object].ReactCompositeComponentMixin.mountComponent (/Users/xinhengs/Desktop/QunarDevs/qact/server/node_modules/react/lib/ReactCompositeComponent.js:220:30)
    at [object Object].wrapper [as mountComponent] (/Users/xinhengs/Desktop/QunarDevs/qact/server/node_modules/react/lib/ReactPerf.js:66:21)
    at /Users/xinhengs/Desktop/QunarDevs/qact/server/node_modules/react/lib/ReactServerRendering.js:70:32
    at ReactServerRenderingTransaction.Mixin.perform (/Users/xinhengs/Desktop/QunarDevs/qact/server/node_modules/react/lib/Transaction.js:136:20)
    at Object.renderToStaticMarkup (/Users/xinhengs/Desktop/QunarDevs/qact/server/node_modules/react/lib/ReactServerRendering.js:68:24)
    at View.renderFile [as engine] (/Users/xinhengs/Desktop/QunarDevs/qact/server/node_modules/express-react-views/index.js:46:32)

Does anyone knows why ?

Enables React 0.14

It would be great to be able to use the new version of react in this module.I don't know if this implies code changes or just packages.json peerDependencies updates.

Babel view caching

Hi reactjs team,

I'm using this library, but it looks like babel's caching my jsx views. According the to the docs, this feature is disabled "in development." Is there an environmental variable or something I have to set for express-react-views to consider me being in a dev environment?

onClick is not working

Hi, I have been developing a simple react component. There is a button with onClick on it. I have tried to debug the issue but the event is not firing. How should I fix this problem?

React as PeerDependency

Hello,

I have tried to follow the README but here are 2 caveeats I encountered:

  • I need to do var React = require('react') in my jsx files
  • the react npm module needs to be a dependency of the express project as well

So I guess react should be a peerDependency, injected into the middleware so as you would not have to possibly deal with 2 different versions.

Let me know how do you feel about that.

Prepend doctype only when it is HTML

I am using React and Express to render SVG. The generated string is something like <svg>...</svg>.

  • It is not a HTML, do not prepend doctype in front of the string.
  • The SVG is the root element, it needs one more xmlns attribute to tell browser to render this SVG: xmlns="http://www.w3.org/2000/svg".

Currently, I hack the viewEngine callback as a workaround:

const viewEngine = react.createEngine({ transformViews: false });
app.engine('js', (filePath, options, callback) => {
  return viewEngine(filePath, options, (error, html) => {
    const raw = html.substring('<!DOCTYPE html>'.length);
    const hack = raw.indexOf('<svg') === 0
      ? raw.replace('<svg', '<svg xmlns="http://www.w3.org/2000/svg"')
      : html;

    callback(error, hack);
  });
});

Hope this package could handle it. Thanks!

Cache is not cleared when module path contains backslash

In development mode, we attempt to clear the require cache of all of the modules in the view directory.

On Linux, the view path may contain backslashes; on Windows, it always does. Regular expressions interpret backslashes as escape characters and because the module detection regex is built directly from the view path, no views will ever be cleared from the require cache if the path contains a backslash.

Issues with using Babel

I'm running into an issue with using both Babel and Sugar with io.js which was recently switched to in #29

Repro:
https://github.com/crdeutsch/iojsbabel

My app is requiring sugar way before express-react-views requires babel.

I can require babel before sugar but then express-react-views will cause an error because babel can only be required once.

In addition Babel doesn't recommend using itself in libraries:
https://babeljs.io/docs/usage/require/

Would it make sense to remove all .JSX parsing libraries as a dependency from express-react-views?

Or at least have an option to skip the require call to babel?

Make the use of Babel 'only' setting optional?

Very happy users of this project, thanks for releasing it.

I have just started using more es6 syntax in the rest of my code which is outside of the 'views' folder. Unfortunately as Babel is initialised with the only setting set to the views folder, the rest of my code is not automatically translated from es6 and so errors.

Would it be possible to make this setting optional in some way? Or is there a preferred way to approach this situation? I tried running my server with babel-node but that still fails. I suspect that the babel/register call in this code base might be resetting the babel options but that is purely a guess.

Any advice welcome. Thanks.

React is not defined

Hello guys,

I am just starting with a project similar to the example, but I am getting the following error:

ReferenceError: React is not defined
   at Object.<anonymous> ...X/views/index.jsx:3:20)
   at Module._compile (module.js:456:26)
   at Object.require.extensions.(anonymous function) [as .jsx] (...X/node_modules/express-react-views/node_modules/node-jsx/index.js:26:12)
   at Module.load (module.js:356:32)
   at Function.Module._load (module.js:312:12)
   at Module.require (module.js:364:17)
   at require (module.js:380:17)
   at View.renderFile [as engine] ...X/node_modules/express-react-views/index.js:36:23)
   at View.render (...X/node_modules/express/lib/view.js:76:8)
   at Function.app.render (...X/node_modules/express/lib/application.js:517:10)

Any idea why?

SyntaxError on Windows

It seems that the jsx view files will raise syntax error on windows(my os is win 8.1 64bit),
but it works well on my mac.

anybody meet the same problem?

Version 0.8.0 is broken on Windows: SyntaxError: Unexpected token <

Problem

Version 0.8.0 is broken on Windows.
See Error below.

Steps To Reproduce

  1. Implement the basic example
  2. Access the '/' route
    • BUG: Error occurs
    • WORK-AROUND: Use back leveled version: 0.7.2.

Error

            <DefaultLayout title={this.props.title}>
            ^
SyntaxError: Unexpected token <
    at exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:443:25)
    at Module._extensions..js (module.js:478:10)
    at Object.require.extensions.(anonymous function) [as .jsx] (C:\...\node_modules\express-react-views\node_modules\babel\node_modules\babel-core\lib\babel\api\register\node.js:161:7)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at View.renderFile [as engine] (C:\...\node_modules\express-react-views\index.js:37:23)
    at View.render (C:\...\node_modules\express\lib\view.js:93:8)

Issue Duplicate?

#32

Node Package Versions

"express-react-views": "0.8.0",
"react": "0.13.3"

OS Version

Windows 7 Pro SP1 (64-bit)

Best way to include IE conditional markup in <head>?

Using the DefaultLayout example from the readme, is there any way to render IE conditional markup like this:

<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->

The best thing I came up with was to use dangerouslySetInnerHTML for the entire head tag... is there a better way?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.