koriym / baracoa
A JavaScript server side rendering interface
Installs: 3 776
Dependents: 2
Suggesters: 1
Security: 0
Stars: 12
Watchers: 5
Forks: 2
Open Issues: 0
Requires
- php: >=7.1.0
- nacmartin/phpexecjs: ^0.8.7
- psr/simple-cache: ^1.0
Requires (Dev)
- phpmd/phpmd: ^2.6.0
- phpunit/phpunit: ^6.1
- phpv8/v8js-stubs: ^1.2.0
- squizlabs/php_codesniffer: ^2.8.0
- symfony/cache: ^v3.3.0-BETA1
Suggests
- ext-v8js: Needed to support V8
README
A JavaScript server side rendering interface
Bracoa provides a simple interface for JavaScript server side rendering in PHP.
Prerequisites
- php7.1
- V8Js
Installation
composer require koriym/baracoa
Basic
In a JS renderer application, implement render
function which takes parameter(s) and return html string.
const render = state => ( `Hello ${state.name}` )
Call the render()
method with JS app name and values to assign to redner.
$baracoa = new Baracoa($jsDir, new ExceptionHandler()); $html = $baracoa->render('min', ['name' => 'World']); echo $html; // Hello World
In this example, you need to place min.bundle.js
JS file in $jsDir
directory.
Every page needs own JS view application which is bundled single file by bundler tool like webpack.
Typical entry file is like following code.
import render from './render';
global.render = render;
In next section we see the example of Redux with React applicaiton example.
Redux React
The Server Side
Inject an initial component HTML and initial state into a template to be rendered on the client side.
To pass along the state, we add a <script>
tag that will attach preloadedState
to window.__PRELOADED_STATE__
.
The preloadedState will then be available on the client side by accessing window.__PRELOADED_STATE__
.
We also include our bundle file for the client-side application via a <script>
tag.
This is whatever output your bundling tool provides for your client entry point.
render.js
import React from 'react'; import { renderToString } from 'react-dom/server'; import { Provider } from 'react-redux'; import escape from 'escape-html'; import serialize from 'serialize-javascript'; import App from '../containers/App'; import configureStore from '../store/configureStore'; const render = (preloadedState, metas) => { const store = configureStore(preloadedState); const root = renderToString( <Provider store={store}> <App /> </Provider>, ); return `<!doctype html> <html> <head> <title>${escape(metas.title)}</title> </head> <body> <div id="root">${root}</div> <script> window.__PRELOADED_STATE__ = ${serialize(preloadedState)} </script> <script src="/build/index.bundle.js"></script> </body> </html> `; }; export default render;
render()
method can pass second parameter as SSR meta data which is only available in server side rendering. Typically this value is used in <header>
such as for OGP.
$meta = ['title => 'awesome page']; $html = $baracoa->render('min', ['name' => 'World'], $meta);
The Client Side
We need to do is grab the initial state from window.__PRELOADED_STATE__
which is rendered in server side, and pass it to our createStore()
function as the initial state.
import React from 'react'; import { render } from 'react-dom'; import { Provider } from 'react-redux'; import configureStore from '../store/configureStore'; import App from '../containers/App'; const preloadedState = window.__PRELOADED_STATE__; const store = configureStore(preloadedState); render( <Provider store={store}> <App /> </Provider>, document.getElementById('root'), );
Performance boost
$cache = new FilesystemCache() // PSR-16 $baracoa = new CacheBaracoa($appBundleJsPath, new ExceptionHandler(), $cache);
An external "snapshot" is saved to increase performance in each app with CacheBaracoa
.
Highly recommended in production site.
Consider internal snapshot for more performance.
See more detail in this blog post.
Run demo
min
git clone git@github.com:koriym/Koriym.Baracoa.git
cd Koriym.Baracoa
composer install
cd docs/example/min
php index.php
// HelloWorld
handlebar
cd docs/example/handlesbar
yarn install
yarn run build
php public/index.php
// <!doctype html>
// ...
redux react
cd docs/example/redux
yarn install
yarn run build
yarn start
Install V8Js
OSX
brew update
brew install homebrew/php/php71-v8js
edit php.ini
or add 'V8Js.ini'
extension="/usr/local/opt/php71-v8js/v8js.so"
JS UI Application Skeleton
UiSkeleton is a Javascript UI application skeleton with hot module loader, browsersync, test, lint and more for development.