JSPM

  • Created
  • Published
  • Downloads 15
  • Score
    100M100P100Q56373F
  • License Apache-2.0

Package Exports

  • coren

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (coren) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Coren

npm Version Build Status

React Pluggable Serverside Render

Is serverside render a big headache for your Single Page App?

say you need head title, description, jsonld, og...

perhaps fetch data from db, then render redux preloadedState

so many things need to be rendered in HTML

How about we use more flexible way to solve it?

What if we let component define what they need in static method?

What if we could fetch database in component?

Coren provide you pluggable, flexible way to render your html

Table Of Content

Features

Installation

$ npm install coren --save

Simple Example

Here's some simple example components using collector

we'll insert what component want as to HTML</p> <h3 id="react"><a class="anchor" aria-hidden="true" tabindex="-1" href="#react"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>React</h3><div class="highlight highlight-source-js"><pre class="language-js">@<span class="token function">collector</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span> <span class="token comment">// Put `user ${props.userId}` title tag to HTML</span> <span class="token keyword">static</span> <span class="token function">defineHead</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">user </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>props<span class="token punctuation">.</span>userId<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span>div<span class="token operator">></span> <span class="token operator">...</span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></pre></div><h3 id="how-headcollector-insert-head"><a class="anchor" aria-hidden="true" tabindex="-1" href="#how-headcollector-insert-head"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>How HeadCollector insert head</h3><p>In MultiRoutesRenderer, HeadCollector insert head using <code>appendToHead</code></p> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token keyword">class</span> <span class="token class-name">HeadCollector</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>heads <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ...</span> <span class="token function">componentDidConstruct</span><span class="token punctuation">(</span><span class="token parameter">id<span class="token punctuation">,</span> component<span class="token punctuation">,</span> props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>heads<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>component<span class="token punctuation">.</span><span class="token function">defineHead</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">getFirstHead</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>heads<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ...</span> <span class="token function">appendToHead</span><span class="token punctuation">(</span><span class="token parameter">$head</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span>title<span class="token punctuation">,</span> description<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getFirstHead</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"><title></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>title<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"></title></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> $head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"><meta name="description" content="</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>description<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">"></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></pre></div><h3 id="serverside"><a class="anchor" aria-hidden="true" tabindex="-1" href="#serverside"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Serverside</h3><div class="highlight highlight-source-js"><pre class="language-js"><span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">App</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">'path/to/app'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// HeadCollector get data from `defineHead()`</span> app<span class="token punctuation">.</span><span class="token function">registerCollector</span><span class="token punctuation">(</span><span class="token string">"head"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">HeadCollector</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ssr</span> <span class="token keyword">const</span> ssr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MultiRoutesRenderer</span><span class="token punctuation">(</span><span class="token punctuation">{</span>app<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> ssr<span class="token punctuation">.</span><span class="token function">renderToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">result</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [{route: "/", html: "<html><head>user 1</head>...</html>"}]</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token parameter">err</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></div><h2 id="redux-preloaded-state"><a class="anchor" aria-hidden="true" tabindex="-1" href="#redux-preloaded-state"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Redux preloaded state</h2><p>How <code>Coren</code> render <code>__PRELOADED_STATE__</code></p> <h3 id="react-1"><a class="anchor" aria-hidden="true" tabindex="-1" href="#react-1"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>React</h3><div class="highlight highlight-source-js"><pre class="language-js">@<span class="token function">collector</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">Product</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span> <span class="token comment">// Fetch data first</span> <span class="token comment">// then, during serverside render, put `window.__PRELOADED_STATE__=${state}` to HTML</span> <span class="token keyword">static</span> <span class="token function">definePreloadedState</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>db<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> db<span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'products'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">data</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token literal-property property">products</span><span class="token operator">:</span> data<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span>div<span class="token operator">></span> <span class="token operator">...</span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></pre></div><h3 id="collector"><a class="anchor" aria-hidden="true" tabindex="-1" href="#collector"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Collector</h3><p>In ReduxCollector, we push promise we got from <code>definePreloadedState</code></p> <p>then, we wait all promises done at <code>appWillRender</code></p> <p>Last, we wrap your app with react-redux provider, and get state from <code>store.getState()</code>, append the state to <code>head</code></p> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token keyword">class</span> <span class="token class-name">ReduxCollector</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token function">componentDidImport</span><span class="token punctuation">(</span><span class="token parameter">id<span class="token punctuation">,</span> component</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> promise <span class="token operator">=</span> component<span class="token punctuation">.</span><span class="token function">definePreloadedState</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>componentProps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>queries<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>promise<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">appWillRender</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>queries<span class="token punctuation">,</span> <span class="token parameter">state</span> <span class="token operator">=></span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>initialState<span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">wrapElement</span><span class="token punctuation">(</span><span class="token parameter">appElement</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">createStore</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>reducers<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>initialState<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> wrapedElements <span class="token operator">=</span> react<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span>Provider<span class="token punctuation">,</span> <span class="token punctuation">{</span>store<span class="token punctuation">}</span><span class="token punctuation">,</span> appElement<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> store<span class="token punctuation">.</span><span class="token function">getState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> wrapedElements<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">appendToHead</span><span class="token punctuation">(</span><span class="token parameter">$head</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> $head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"><script> window.__PRELOADED_STATE__ = </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </script></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></pre></div><h3 id="serverside-1"><a class="anchor" aria-hidden="true" tabindex="-1" href="#serverside-1"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Serverside</h3><div class="highlight highlight-source-js"><pre class="language-js"><span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">App</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">'path/to/app'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ReduxCollector get initialState from `definePreloadedState()`</span> app<span class="token punctuation">.</span><span class="token function">registerCollector</span><span class="token punctuation">(</span><span class="token string">"redux"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">ReduxCollector</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token comment">// componentProps will be passed to </span> <span class="token literal-property property">componentProps</span><span class="token operator">:</span> <span class="token punctuation">{</span> db <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// reducer of your app</span> <span class="token literal-property property">reducers</span><span class="token operator">:</span> reducer <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ssr</span> <span class="token keyword">const</span> ssr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MultiRoutesRenderer</span><span class="token punctuation">(</span><span class="token punctuation">{</span>app<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> ssr<span class="token punctuation">.</span><span class="token function">renderToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">result</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [{route: "/", html: "<html><body>window.__PRELOADED_STATE__={...}</body>></html>"}]</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token parameter">err</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></div><h1 id="concepts"><a class="anchor" aria-hidden="true" tabindex="-1" href="#concepts"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Concepts</h1><h2 id="define"><a class="anchor" aria-hidden="true" tabindex="-1" href="#define"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Define</h2><p><code>Coren</code> render html base on data gotten from Component.</p> <p>so, where do Component write what they could provide for Serverside render?</p> <p>Component should use <code>@collector</code> decorator outside, and use static method, prefixed with <code>define</code>. In this case, <code>@collector</code> could return data back to server during right lifecycle.</p> <h2 id="lifecycle-hook"><a class="anchor" aria-hidden="true" tabindex="-1" href="#lifecycle-hook"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Lifecycle Hook</h2><p>We metioned lifecycle above. How does this work?</p> <p>let us take a look at <code>collector</code> decorator</p> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token parameter">WrappedComponent</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> uniqId <span class="token operator">=</span> shortid<span class="token punctuation">.</span><span class="token function">generate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* trigger componentDidImport lifecycle here notify collectors */</span> hook<span class="token punctuation">.</span><span class="token function">componentDidImport</span><span class="token punctuation">(</span>uniqId<span class="token punctuation">,</span> WrappedComponent<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">Hoc</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* trigger componentDidConstruct lifecycle here pass props to collectors */</span> hook<span class="token punctuation">.</span><span class="token function">componentDidConstruct</span><span class="token punctuation">(</span>uniqId<span class="token punctuation">,</span> WrappedComponent<span class="token punctuation">,</span> props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span>WrappedComponent <span class="token punctuation">{</span><span class="token operator">...</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token function">hoistStatic</span><span class="token punctuation">(</span>Hoc<span class="token punctuation">,</span> WrappedComponent<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></pre></div><p>During serverside render, two lifecycle will be triggered</p> <ul> <li><code>componentDidImport(id, component)</code>: called when component imported</li> <li><code>componentDidConstruct(id, component, props)</code>: called when component constructed</li> </ul> <h3 id="why-these-two-methods"><a class="anchor" aria-hidden="true" tabindex="-1" href="#why-these-two-methods"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><strong>Why these two methods?</strong></h3><p>In <code>React-router</code>, only component matched with route will be rendered. So, component rendered will trigger both methods, on the other hand, component <em>not</em> rendered will trigger only <code>componentDidImport</code>. It will help you put right data in your HTML.</p> <p>For Example, we should only put the <code>head</code> tags return from first constructed component. Components that didn't trigger <code>componentDidConstruct</code> should not be considered.</p> <h2 id="collector-1"><a class="anchor" aria-hidden="true" tabindex="-1" href="#collector-1"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Collector</h2><p><strong>What is a <code>Collector</code>?</strong></p> <p><code>Collector</code> collect data from <code>define</code> methods, collector can choose which lifecycle it want to call <code>define</code> method.</p> <p>For example, we take a look at <code>HeadCollector</code>, <code>HeadCollector</code> call <code>defineHead(props)</code> in <code>componentDidConstruct</code>, it get <code>{title, description}</code>, then push to heads array.</p> <p>when <code>serverside renderer</code> call <code>appendToHead</code>, <code>HeadCollector</code> push the first head it got from component to <code>$head</code></p> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token keyword">class</span> <span class="token class-name">HeadCollector</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>heads <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ...</span> <span class="token function">componentDidConstruct</span><span class="token punctuation">(</span><span class="token parameter">id<span class="token punctuation">,</span> component<span class="token punctuation">,</span> props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>heads<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>component<span class="token punctuation">.</span><span class="token function">defineHead</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">getFirstHead</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>heads<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ...</span> <span class="token function">appendToHead</span><span class="token punctuation">(</span><span class="token parameter">$head</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span>title<span class="token punctuation">,</span> description<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getFirstHead</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"><title></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>title<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"></title></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> $head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"><meta name="description" content="</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>description<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">"></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></pre></div><h2 id="app"><a class="anchor" aria-hidden="true" tabindex="-1" href="#app"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>App</h2><p>App represent your react application. developer use <code>App</code> to register collector</p> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token comment">// create App with path to your React App entry file</span> <span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">App</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">'path/to/app'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// register collector</span> app<span class="token punctuation">.</span><span class="token function">registerCollector</span><span class="token punctuation">(</span><span class="token string">"head"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">HeadCollector</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></div><p><code>App</code> controlls lifecycle of all registered collectors.</p> <p>Serverside renderer will call <code>App</code>'s lifecycle method at certain time, to get the desired result it want.</p> <h2 id="serverside-renderer"><a class="anchor" aria-hidden="true" tabindex="-1" href="#serverside-renderer"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Serverside Renderer</h2><p>The main purpose of Serverside Renderer is to create HTML. By calling <code>App</code> to controll lifecycle of collectors, make sure collectors get the result they want.</p> <h3 id="collector-lifecycle"><a class="anchor" aria-hidden="true" tabindex="-1" href="#collector-lifecycle"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Collector Lifecycle</h3><p>In <code>MultiRoutesRenderer</code>, every collector will go through same phases:</p> <ol> <li><code>componentDidImport(id, component)</code>: when component imported</li> <li><code>appWillRender</code>: do some async work here if you want to make some api call before render</li> <li><code>routeWillRender</code>: when rendering multiple routes, appWillRender will be called every time the route match with your component and trigger render, so is every method below</li> <li><code>wrapElement</code>: you can wrap your app reactElement if you need a provider outside</li> <li>(app renderToString) => ssrRenderer will call ReactDom.renderToString</li> <li><code>componentDidConstruct(id, component, props)</code>: called when component was constructed</li> <li><code>appendToHead($cheerio('head'))</code>: append any html to head</li> <li><code>appendToBody($cheerio('body'))</code>: append any html to body</li> </ol> <h1 id="api"><a class="anchor" aria-hidden="true" tabindex="-1" href="#api"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>API</h1><h2 id="app-1"><a class="anchor" aria-hidden="true" tabindex="-1" href="#app-1"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>App</h2><h3 id="constructorpath-string"><a class="anchor" aria-hidden="true" tabindex="-1" href="#constructorpath-string"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>constructor({path: String})</h3><ul> <li>path: path to your React app entry file</li> </ul> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">App</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">'path/to/app'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></div><h3 id="registercollectorkey-string-collector-collector"><a class="anchor" aria-hidden="true" tabindex="-1" href="#registercollectorkey-string-collector-collector"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>registerCollector(key: String, collector: Collector)</h3><ul> <li>key: you can directly access to collector by key</li> </ul> <div class="highlight highlight-source-js"><pre class="language-js">app<span class="token punctuation">.</span><span class="token function">getCollector</span><span class="token punctuation">(</span><span class="token string">"head"</span><span class="token punctuation">)</span> <span class="token comment">// return headCollector</span></pre></div><ul> <li>collector: the collector you want to register</li> </ul> <div class="highlight highlight-source-js"><pre class="language-js">app<span class="token punctuation">.</span><span class="token function">registerCollector</span><span class="token punctuation">(</span><span class="token string">"head"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">HeadCollector</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></div><h2 id="collector-2"><a class="anchor" aria-hidden="true" tabindex="-1" href="#collector-2"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Collector</h2><h3 id="ifentercomponent-boolean"><a class="anchor" aria-hidden="true" tabindex="-1" href="#ifentercomponent-boolean"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>ifEnter(component): Boolean</h3><p><code>app</code> will use <code>ifEnter</code> to determine whether call this collector or not</p> <h3 id="componentdidimportid-component-void"><a class="anchor" aria-hidden="true" tabindex="-1" href="#componentdidimportid-component-void"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>componentDidImport(id, component): void</h3><p>called when component imported, when component imported, a unique id attached to it, so you'll know where this component appeared before or not in <code>componentDidConstruct</code>.</p> <h3 id="componentdidconstructid-string-component-reactcomponent-props-object-void"><a class="anchor" aria-hidden="true" tabindex="-1" href="#componentdidconstructid-string-component-reactcomponent-props-object-void"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>componentDidConstruct(id: String, component: ReactComponent, props: Object): void</h3><p>called when component was constructed</p> <h3 id="appwillrender-promise"><a class="anchor" aria-hidden="true" tabindex="-1" href="#appwillrender-promise"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>appWillRender(): Promise</h3><p>Because we react wont wait for your async code during <code>import</code>. So a better way to use async related task is to push your promise to an array, wait for them in <code>appWillRender</code>.</p> <p>Take reduxCollector for example:</p> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token comment">// /src/reduxCollector</span> <span class="token function">componentDidImport</span><span class="token punctuation">(</span><span class="token parameter">id<span class="token punctuation">,</span> component</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> promise <span class="token operator">=</span> component<span class="token punctuation">.</span><span class="token function">definePreloadedState</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>componentProps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>queries<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>promise<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">appWillRender</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>queries<span class="token punctuation">,</span> <span class="token parameter">state</span> <span class="token operator">=></span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>initialState<span class="token punctuation">,</span> state<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></pre></div><h3 id="routewillrender-void"><a class="anchor" aria-hidden="true" tabindex="-1" href="#routewillrender-void"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>routeWillRender(): void</h3><p>In <code>MultiRoutesRenderer</code>, you'll have multiple routes to be rendered, so you need a hook to tell your collector when a route is going to be rendered. You can do some reset variable things here.</p> <p>Take <code>HeadCollector</code> for example, we make sure we collect fresh head from component constructed.</p> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token function">componentDidConstruct</span><span class="token punctuation">(</span><span class="token parameter">id<span class="token punctuation">,</span> component<span class="token punctuation">,</span> props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>heads<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>component<span class="token punctuation">.</span><span class="token function">defineHead</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">routeWillRender</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// empty heads</span> <span class="token keyword">this</span><span class="token punctuation">.</span>heads <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></pre></div><h3 id="wrapelementreactelement-reactelement"><a class="anchor" aria-hidden="true" tabindex="-1" href="#wrapelementreactelement-reactelement"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>wrapElement(ReactElement): ReactElement</h3><p>Some module require developer wrap ReactElement with provider in serverside render.</p> <p>Take <code>reduxCollector</code> for example, we wrap ReactElement with react-redux provider.</p> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token function">wrapElement</span><span class="token punctuation">(</span><span class="token parameter">appElement</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">createStore</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>reducers<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>initialState<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> wrapedElements <span class="token operator">=</span> react<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span>Provider<span class="token punctuation">,</span> <span class="token punctuation">{</span>store<span class="token punctuation">}</span><span class="token punctuation">,</span> appElement<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> store<span class="token punctuation">.</span><span class="token function">getState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> wrapedElements<span class="token punctuation">;</span> <span class="token punctuation">}</span></pre></div><h3 id="appendtoheadhead-cheerio"><a class="anchor" aria-hidden="true" tabindex="-1" href="#appendtoheadhead-cheerio"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>appendToHead($head: cheerio)</h3><p>append any html to head</p> <h3 id="appendtobodybody-cheerio"><a class="anchor" aria-hidden="true" tabindex="-1" href="#appendtobodybody-cheerio"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>appendToBody($body: cheerio)</h3><p>append any html to body</p> <h1 id="usage"><a class="anchor" aria-hidden="true" tabindex="-1" href="#usage"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Usage</h1><h2 id="getting-started"><a class="anchor" aria-hidden="true" tabindex="-1" href="#getting-started"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Getting Started</h2><ol> <li>npm install coren --save</li> <li>use @collector in your component</li> </ol> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token keyword">import</span> collector <span class="token keyword">from</span> <span class="token string">'coren/lib/client/collectorHoc'</span><span class="token punctuation">;</span> @<span class="token function">collector</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">UserList</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></pre></div><ol start="3"> <li>write <code>define</code> method.</li> </ol> <div class="highlight highlight-source-js"><pre class="language-js">@<span class="token function">collector</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">UserList</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token function">defineHead</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"user list"</span><span class="token punctuation">,</span> <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"user list"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> <span class="token function">defineRoutes</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>Url<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Url</span><span class="token punctuation">(</span><span class="token string">'/users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> <span class="token function">definePreloadedState</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>db<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> db<span class="token punctuation">.</span>users<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">execAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">list</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">users</span><span class="token operator">:</span> <span class="token punctuation">{</span> list<span class="token punctuation">,</span> <span class="token literal-property property">fetched</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">isFetching</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token literal-property property">error</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></pre></div><ol start="4"> <li>serverside render serverside render with <code>app</code> and <code>multiRoutesRenderer</code></li> </ol> <div class="highlight highlight-source-js"><pre class="language-js"><span class="token keyword">const</span> db <span class="token operator">=</span> mongodb<span class="token punctuation">;</span> <span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">App</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">'path/to/app'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// register collectors</span> app<span class="token punctuation">.</span><span class="token function">registerCollector</span><span class="token punctuation">(</span><span class="token string">"head"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">HeadCollector</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> app<span class="token punctuation">.</span><span class="token function">registerCollector</span><span class="token punctuation">(</span><span class="token string">"routes"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">RoutesCollector</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">componentProps</span><span class="token operator">:</span> <span class="token punctuation">{</span> db <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> app<span class="token punctuation">.</span><span class="token function">registerCollector</span><span class="token punctuation">(</span><span class="token string">"redux"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">ImmutableReduxCollector</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">componentProps</span><span class="token operator">:</span> <span class="token punctuation">{</span> db <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">reducers</span><span class="token operator">:</span> reducer <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ssr</span> <span class="token keyword">const</span> ssr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MultiRoutesRenderer</span><span class="token punctuation">(</span><span class="token punctuation">{</span> app<span class="token punctuation">,</span> <span class="token comment">// bundle path will be append to html body</span> <span class="token literal-property property">js</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"/bundle.js"</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// get the array of html result</span> ssr<span class="token punctuation">.</span><span class="token function">renderToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">results</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>results<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token parameter">result</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// throw HTML to anywhere you want</span> <span class="token comment">// cached to web server, cache server</span> <span class="token comment">// write to s3, cdn</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token parameter">err</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></div><h2 id="how-to-create-own-collector"><a class="anchor" aria-hidden="true" tabindex="-1" href="#how-to-create-own-collector"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>How to create own Collector</h2><p>Write your own class, implement methods in <a href="#Collector" title="null">Collector</a>.</p> <p>Take a look at built-in collector for reference.</p> <p><a href="https://github.com/Canner/coren/tree/master/server/collectors" title="undefined" rel="noopener noreferrer">https://github.com/Canner/coren/tree/master/server/collectors</a></p> <h2 id="example"><a class="anchor" aria-hidden="true" tabindex="-1" href="#example"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Example</h2><p>Here's a example repo using this module. <a href="https://github.com/Canner/coren-example" title="undefined" rel="noopener noreferrer">https://github.com/Canner/coren-example</a></p> <h2 id="中文簡介"><a class="anchor" aria-hidden="true" tabindex="-1" href="#中文簡介"><svg class="octicon octicon-link" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>中文簡介</h2><p><a href="https://medium.com/canner-io-%E6%98%93%E9%96%8B%E7%A7%91%E6%8A%80/react-composite-server-side-render-a85a90f841f5" title="null" rel="noopener noreferrer">Meduim 文章:Coren: React Composite Server-side Render</a></p> </section></jspm-packages-readme></details></main></section><footer><section class="maintainers"><h3>Collaborators</h3><ul><li><a href="https://www.github.com/ctxhou"><figure><img loading="lazy" alt="ctxhou" src="https://unavatar.io/vjack070707@gmail.com" width="75" height="75" /></figure></a></li><li><a href="https://www.github.com/wwwy3y3"><figure><img loading="lazy" alt="wwwy3y3" src="https://unavatar.io/wwwy3y3@gmail.com" width="75" height="75" /></figure></a></li></ul></section><section class="keywords"><h3>Keywords</h3><ul><li><a href="/search?keyword=coren">#coren</a></li><li><a href="/search?keyword=react">#react</a></li><li><a href="/search?keyword=react server side render">#react server side render</a></li><li><a href="/search?keyword=ssr">#ssr</a></li></ul></section><section><h3>Dependencies</h3><ul><li><a href="/package/babel-load-config">babel-load-config</a></li><li><a href="/package/babel-preset-es2015">babel-preset-es2015</a></li><li><a href="/package/bluebird">bluebird</a></li><li><a href="/package/chalk">chalk</a></li><li><a href="/package/cheerio">cheerio</a></li><li><a href="/package/co">co</a></li><li><a href="/package/extract-text-webpack-plugin">extract-text-webpack-plugin</a></li><li><a href="/package/lodash">lodash</a></li><li><a href="/package/mkdirp">mkdirp</a></li><li><a href="/package/path-to-regexp">path-to-regexp</a></li><li><a href="/package/react">react</a></li><li><a href="/package/react-dom">react-dom</a></li><li><a href="/package/react-redux">react-redux</a></li><li><a href="/package/react-router-dom">react-router-dom</a></li><li><a href="/package/redux">redux</a></li><li><a href="/package/shortid">shortid</a></li><li><a href="/package/webpack">webpack</a></li><li><a href="/package/webpack-node-externals">webpack-node-externals</a></li></ul></section></footer></section></jspm-packages-package> </jspm-packages> <script type="module"> import '@jspm/packages/package-dom'; </script> </body> </html>