Start bootstraping rendering with react in GitBook

This commit is contained in:
Samy Pessé
2016-09-05 14:02:49 +02:00
parent 3f1ec310ca
commit ff31514c66
13 changed files with 121 additions and 43 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"presets": ["es2015", "react", "stage-2"]
}
+8 -1
View File
@@ -7,8 +7,15 @@
"immutable": "^3.8.1",
"react": "^15.3.1",
"react-dom": "^15.3.1",
"react-helmet": "^3.1.0",
"react-redux": "^4.4.5",
"redux": "^3.5.2"
"redux": "^3.5.2",
"redux-thunk": "^2.1.0"
},
"devDependencies": {
"babel-preset-es2015": "^6.14.0",
"babel-preset-react": "^6.11.1",
"babel-preset-stage-2": "^6.13.0"
},
"repository": {
"type": "git",
@@ -1,10 +0,0 @@
const React = require('react');
const { InjectedComponent } = require('./components/InjectedComponent');
const Application = React.createClass({
render() {
return <InjectedComponent matching={{ role: 'Body' }} />
}
});
module.exports = Application;
@@ -1,5 +1,5 @@
const React = require('react');
const connect = require('./connect');
const ReactRedux = require('react-redux');
const UnsafeComponent = require('./UnsafeComponent');
const { findMatchingComponents } = require('../actions/components');
@@ -65,11 +65,11 @@ function mapStateToProps(state, props) {
}
module.exports = {
InjectedComponent: connect(InjectedComponentSet, (state, props) => {
InjectedComponent: ReactRedux.connect(InjectedComponentSet, (state, props) => {
const result = mapStateToProps(state, props);
result.components = result.components.slice(0, 1);
result.withContainer = false;
return result;
}),
InjectedComponentSet: connect(InjectedComponentSet, mapStateToProps)
InjectedComponentSet: ReactRedux.connect(InjectedComponentSet, mapStateToProps)
};
+2
View File
@@ -5,6 +5,7 @@ const connect = require('./connect');
const createPlugin = require('./createPlugin');
const createReducer = require('./createReducer');
const createStore = require('./createStore');
const renderComponent = require('./renderComponent');
module.exports = {
ACTIONS,
@@ -12,6 +13,7 @@ module.exports = {
createPlugin,
createReducer,
createStore,
renderComponent,
registerComponent,
InjectedComponent,
InjectedComponentSet
@@ -0,0 +1,25 @@
const React = require('react');
const Helmet = require('react-helmet');
const ReactRedux = require('react-redux');
const { InjectedComponent } = require('./components/InjectedComponent');
/**
* Render a registered component from a store.
* This method is intended for server-side use in "gitbook".
*
* @param {ReduxStore} store
* @param {Descriptor} matching
* @return {Object} { el, meta }
*/
function renderComponent(store, matching) {
const el = (
<ReactRedux.Provider store={store}>
<InjectedComponent matching={matching} />
</ReactRedux.Provider>
);
const head = Helmet.rewind();
return { el, head };
}
module.exports = renderComponent;
@@ -0,0 +1,3 @@
module.exports = {
};
@@ -2,6 +2,7 @@
"name": "gitbook-plugin-theme-default",
"description": "Default theme for GitBook",
"main": "./index.js",
"browser": "./src/index.js",
"version": "1.0.5",
"engines": {
"gitbook": ">=3.0.0"
+1 -1
View File
@@ -1,3 +1,3 @@
{
"presets": ["es2015", "react"]
"presets": ["es2015", "react", "stage-2"]
}
+5 -2
View File
@@ -67,7 +67,7 @@
"urijs": "1.18.0"
},
"scripts": {
"test": "./node_modules/.bin/mocha ./testing/setup.js \"./lib/**/*/__tests__/*.js\" --bail --reporter=list --timeout=10000",
"test": "./node_modules/.bin/mocha ./testing/setup.js \"./src/**/*/__tests__/*.js\" --bail --reporter=list --timeout=10000 --compilers js:babel-register",
"dist": "rm -rf lib/ && babel --presets es2015 -d lib/ src/",
"prepublish": "npm run dist"
},
@@ -101,6 +101,9 @@
"devDependencies": {
"babel-cli": "^6.14.0",
"babel-preset-es2015": "^6.14.0",
"babel-preset-react": "^6.11.1"
"babel-preset-react": "^6.11.1",
"babel-preset-stage-2": "^6.13.0",
"babel-register": "^6.14.0",
"mocha": "^3.0.2"
}
}
+9 -10
View File
@@ -7,9 +7,10 @@ const JSONUtils = require('../../json');
const LocationUtils = require('../../utils/location');
const Modifiers = require('../modifiers');
const writeFile = require('../helper/writeFile');
const fileToOutput = require('../helper/fileToOutput');
const getModifiers = require('../getModifiers');
const createTemplateEngine = require('./createTemplateEngine');
const fileToOutput = require('../helper/fileToOutput');
const render = require('./render');
/**
* Write a page as a json file
@@ -40,12 +41,12 @@ function onPage(output, page) {
return Modifiers.modifyHTML(page, getModifiers(output, page))
.then(function(resultPage) {
// Generate the context
const context = JSONUtils.encodeOutputWithPage(output, resultPage);
context.plugins = {
const initialState = JSONUtils.encodeOutputWithPage(output, resultPage);
initialState.plugins = {
resources: Plugins.listResources(plugins, resources).toJS()
};
context.template = {
/*context.template = {
getJSContext() {
return {
page: omit(context.page, 'content'),
@@ -58,18 +59,16 @@ function onPage(output, page) {
}
};
}
};
};*/
// We should probabbly move it to "template" or a "site" namespace
context.basePath = basePath;
// context.basePath = basePath;
// Render the theme
return Templating.renderFile(engine, prefix + '/page.html', context)
const html = render(initialState);
// Write it to the disk
.then(function(tplOut) {
return writeFile(output, filePath, tplOut.getContent());
});
return writeFile(output, filePath, html);
});
}
@@ -0,0 +1,44 @@
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const GitBook = require('gitbook-core');
function HTML({head, innerHTML}) {
const attrs = head.htmlAttributes.toComponent();
return (
<html {...attrs}>
<head>
{head.title.toComponent()}
{head.meta.toComponent()}
{head.link.toComponent()}
</head>
<body>
<div id="content" dangerouslySetInnerHTML={{__html: innerHTML}} />
</body>
</html>
);
}
HTML.propTypes = {
head: React.PropTypes.object,
innerHTML: React.PropTypes.string
};
/**
* Render a page
* @param {Object} initialState
* @return {String} html
*/
function render(initialState) {
const plugins = [];
const store = GitBook.createStore(plugins, initialState);
const { el, head } = GitBook.renderComponent(store, {
role: 'Body'
});
const innerHTML = ReactDOMServer.renderToString(el);
const htmlEl = <HTML head={head} innerHTML={innerHTML} />;
return ReactDOMServer.renderToStaticMarkup(htmlEl);
}
module.exports = render;
+17 -16
View File
@@ -1,17 +1,18 @@
var is = require('is');
var path = require('path');
var fs = require('fs');
var expect = require('expect');
var cheerio = require('cheerio');
const is = require('is');
const path = require('path');
const fs = require('fs');
const expect = require('expect');
const cheerio = require('cheerio');
expect.extend({
/**
* Check that a file is created in a directory:
* expect('myFolder').toHaveFile('hello.md');
*/
toHaveFile: function(fileName) {
var filePath = path.join(this.actual, fileName);
var exists = fs.existsSync(filePath);
toHaveFile(fileName) {
const filePath = path.join(this.actual, fileName);
const exists = fs.existsSync(filePath);
expect.assert(
exists,
@@ -21,9 +22,9 @@ expect.extend({
);
return this;
},
toNotHaveFile: function(fileName) {
var filePath = path.join(this.actual, fileName);
var exists = fs.existsSync(filePath);
toNotHaveFile(fileName) {
const filePath = path.join(this.actual, fileName);
const exists = fs.existsSync(filePath);
expect.assert(
!exists,
@@ -37,7 +38,7 @@ expect.extend({
/**
* Check that a value is defined (not null nor undefined)
*/
toBeDefined: function() {
toBeDefined() {
expect.assert(
!(is.undefined(this.actual) || is.null(this.actual)),
'expected to be defined'
@@ -48,7 +49,7 @@ expect.extend({
/**
* Check that a value is defined (not null nor undefined)
*/
toNotBeDefined: function() {
toNotBeDefined() {
expect.assert(
(is.undefined(this.actual) || is.null(this.actual)),
'expected %s to be not defined',
@@ -61,9 +62,9 @@ expect.extend({
* Check that a dom element exists in HTML
* @param {String} selector
*/
toHaveDOMElement: function(selector) {
var $ = cheerio.load(this.actual);
var $el = $(selector);
toHaveDOMElement(selector) {
const $ = cheerio.load(this.actual);
const $el = $(selector);
expect.assert($el.length > 0, 'expected HTML to contains %s', selector);
}