🌜
🌞
beidou-view-react

beidou-view-react

v2.1.1

beidou view react

npm install beidou-view-react

README

Beidou view react

Beidou react view plugin, used by beidou-core

Install

$ npm install beidou-view-react --save

Configuration

Default configs

const path = require('path');

module.exports = appInfo => ({
  /**
   * React view options
   * @member Config#react
   */
  react: {
    // React view rendering middlewares
    middlewares: ['cache', 'redux', 'partial', 'render', 'beautify', 'doctype'],
    // optional, beautify HTML snippet
    beautify: false,
    //optional, if false, clean require cache for development usage
    cache: true,
    //optional, true: renderToString or false: renderToStaticMarkup
    internals: true,
    //optional, HTML doctype
    doctype: '<!DOCTYPE html>',
    assetHost: '',
    assetPath: '/build/',
  },
  view: {
    useHashAsset:false,
    defaultViewEngine: 'react',
    defaultExtension: '.jsx',
    // Isomorphic directories
    root: `${path.join(appInfo.baseDir, 'app/views')},${path.join(
      appInfo.baseDir,
      'client'
    )}`,
  },
});

Use internal render component

Use internal render component Render in View.

export default class View extends React.Component {
  render() {
    const { helper, Render } = this.props;
    return (
      <html>
        <head>
          <title>Script</title>
          <link rel="stylesheet" href={helper.asset('index.css')} />
        </head>
        <body>
          <Render stream id="container">
            <App />
          </Render>
        </body>
      </html>
    );
  }
}

The content inside <Render /> element would be dynamicly rendered and set back into the view.

Props

props type default usage
disable Boolean false disable server-side rendering, true to disable
element String or Component div the element type of render container
stream Boolean false true to use renderToNodeStream()
app ReactNode null the component should be rendered
children ReactNode null same as app
[others] any any other props will be passed to element you defined

The difference between <Render /> and getPartial()

getPartial()

The components returnd from getPartial() will be rendered into string and put back to props, You can manipulate them in View template. So the Partial rendered first, and then is the template.

<Render />

But, for the <Render /> component, it contains dynamic parts waiting to be rendered. When View template is rendered, each instance of <Render /> will generate a markup (placeholder) in template result string, View Engine replace regonizes them, gets true parts should be rendered, render and replaces the markups in sequence.

In this mode, template rendered before the dynamic parts. So we can get the first part of page at very beginning, and send it the browser to reduce TTFB.

Custom view middlewares

You can access view rendering process to meet your needs. For example, if you want to record rendering time, you need to write a time.js to your app/view-middlewares/ directory. If you don't understand middleware please read middlewares before you digging into code.

// app/view-middlewares/time.js

/**
 * @param {Object} viewCtx - view context
 * @param {String} viewCtx.filepath - rendering file path
 * @param {Class} viewCtx.Component - sub class of React.Component
 * @param {Object} viewCtx.props - rendering props
 * @param {String} viewCtx.html - rendering html string
 * @param {Object} viewCtx.config - app.config, access to all config
 * @param {Object} viewCtx.options - app.config.react
 * @param {Function} next - middleware next function
 */
module.exports = async function(viewCtx, next) {
  const startTime = Date.now();
  await next(); // Execute other middlewares
  console.log(`Rendering time: ${Date.now() - startTime}`);
};

Set appropriate middlewares order

// config/config.default.js

module.exports = () => ({
  react: {
    middlewares: [
      // Recording time at begining
      'time',
      'cache',
      'redux',
      'partial',
      'render',
      'doctype',
      'beautify',
    ],
  },
});

Start the view-middleware demo project local server, you will get something like below:

Rendering time

Using CDN

You may use CDN resources when your project online. First you need build your project to assets and upload to your CDN server, then custom your asset config in config.prod.js.

// config/config.prod.js

module.exports = {
  react: {
    assetHost: '//your-cdn.com',
    assetPath: '/project/1.0.0',
  },
};

In your project entry render method, using this.props.helper.asset('main.js') you will get //your-cdn.com/project/1.0.0/main.js

Usage

Using render method in your controllers

// app/controller/index.js
exprots.index = async function() {
  await this.ctx.render('path/to/index.jsx', {
    user: 'beidou view',
  });
};

API

React view exports render and renderString 2 APIs, return Promise.

  • ctx.render(name, locals) - render template, and assign to ctx.body
  • ctx.renderString(tpl, locals) - only render template to string, will not assign to ctx.body

License

MIT

Release Notes

1.0.0
By Qing • Published on March 23, 2018

BREAKING CHANGE

  • Node version must >= 8
  • React/react-dom versions must >= 16
  • Replace koa-webpack-dev-middleware with webpack-dev-server
  • Remove app.helper.resolveResource, use app.helper.asset instead

Features

  • Upgrade to [email protected], support async/await style middlewares
  • All in one manage tool - beidou-cli, including init boilerplate, development, debug, test, build assets, start/stop production app, and so on.
  • Custom view rendering process by view middlewares
  • Support rax isomorphic rendering, see beidou-view-rax
  • Webpack support many frontend resource loaders, see code
  • Webpack support CSS Modules with .module.{css|scss|less} files
  • Dump webpack config to [root]/run directory
  • Custom babel client targets by configuration
  • Handle many reasonable default configs, you may not need a lot of options in your config files, see examples

General

License
MIT
Typescript Types
None found
Tree-shakeable
No

Popularity

GitHub Stargazers
2,732
Community Interest
3,112
Number of Forks
280

Maintenance

Commits
10/219/2202
Last Commit
Open Issues
15
Closed Issues
127
Open Pull Requests
36
Closed Pull Requests
56

Versions

Versions Released
10/219/2201
Latest Version Released
May 6, 2019
Current Tags
latest2.1.1
next2.0.0-beta.0

Contributors

njugray
njugray
Commits: 221
weichunpeng
weichunpeng
Commits: 162
devrsi0n
devrsi0n
Commits: 86
justquanyin
justquanyin
Commits: 26
ahungrynoob
ahungrynoob
Commits: 9
xdlrt
xdlrt
Commits: 2
JacksonTian
JacksonTian
Commits: 2
olivewind
olivewind
Commits: 1
fantasyroot
fantasyroot
Commits: 1
chenmingjia
chenmingjia
Commits: 1
lanqy
lanqy
Commits: 1
weihomechen
weihomechen
Commits: 1
xiangxingchen
xiangxingchen
Commits: 1
davidnotes
davidnotes
Commits: 1
kittBoy
kittBoy
Commits: 1