No Description

render.js 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. let renderFragment = (() => {
  6. var _ref = _asyncToGenerator(function* (createApp, routes, url, initialState, timeout, verbose) {
  7. const history = (0, _history.createMemoryHistory)();
  8. history.push(url);
  9. const context = {};
  10. const app = createApp({
  11. history,
  12. initialState
  13. });
  14. if (!existSSRModel(app)) {
  15. app.model(_ssrModel2.default);
  16. }
  17. app.router(function (options) {
  18. return _react2.default.createElement(
  19. _reactRouter.StaticRouter,
  20. { location: url, context: options.context },
  21. _react2.default.createElement(
  22. 'div',
  23. null,
  24. routes
  25. )
  26. );
  27. });
  28. const asyncActions = getAsyncActions(app);
  29. const branch = (0, _utils.findRouteByUrl)(routes, url);
  30. if (branch.length === 0) {
  31. return {};
  32. }
  33. const sync = findSync(branch);
  34. if (!sync && asyncActions && asyncActions.length > 0) {
  35. const id = (0, _uid2.default)(10);
  36. app.use((0, _dvaServerSync2.default)(id, function (action) {
  37. if (asyncActions.indexOf(action.type) > -1) {
  38. return true;
  39. }
  40. return false;
  41. }, _block2.default));
  42. const appDOM = app.start()({
  43. context
  44. });
  45. if (verbose) {
  46. console.time(`${url}: async wait time`);
  47. }
  48. const result = yield new Promise(function (resolve, reject) {
  49. const timer = setTimeout(function () {
  50. reject(new Error('render timeout'));
  51. }, timeout);
  52. _block2.default.wait(id, function () {
  53. if (verbose) {
  54. console.timeEnd(`${url}: async wait time`);
  55. }
  56. clearTimeout(timer);
  57. const curState = appDOM.props.store.getState();
  58. const html = (0, _server.renderToStaticMarkup)(appDOM);
  59. resolve({ html, state: curState, context });
  60. });
  61. });
  62. return result;
  63. }
  64. const appDOM = app.start()({
  65. context
  66. });
  67. const html = (0, _server.renderToStaticMarkup)(appDOM);
  68. const curState = appDOM.props.store.getState();
  69. return { html, state: curState, context };
  70. });
  71. return function renderFragment(_x, _x2, _x3, _x4, _x5, _x6) {
  72. return _ref.apply(this, arguments);
  73. };
  74. })();
  75. var _react = require('react');
  76. var _react2 = _interopRequireDefault(_react);
  77. var _uid = require('uid');
  78. var _uid2 = _interopRequireDefault(_uid);
  79. var _reactRouter = require('react-router');
  80. var _history = require('history');
  81. var _lodash = require('lodash.merge');
  82. var _lodash2 = _interopRequireDefault(_lodash);
  83. var _server = require('react-dom/server');
  84. var _ssrModel = require('./ssrModel');
  85. var _ssrModel2 = _interopRequireDefault(_ssrModel);
  86. var _utils = require('./utils');
  87. var _dvaServerSync = require('./dvaServerSync');
  88. var _dvaServerSync2 = _interopRequireDefault(_dvaServerSync);
  89. var _block = require('./block');
  90. var _block2 = _interopRequireDefault(_block);
  91. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  92. function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
  93. function existSSRModel(app) {
  94. try {
  95. let model = null;
  96. app._models.forEach(m => {
  97. if (m.namespace === 'ssr') {
  98. model = m;
  99. }
  100. });
  101. return !!model;
  102. } catch (e) {
  103. return false;
  104. }
  105. }
  106. function getAsyncActions(app) {
  107. try {
  108. let actions = [];
  109. app._models.forEach(model => {
  110. if (model.effects) {
  111. actions = actions.concat(Object.keys(model.effects));
  112. }
  113. });
  114. return actions;
  115. } catch (e) {
  116. return [];
  117. }
  118. }
  119. function findSync(branch) {
  120. let sync = false;
  121. branch.forEach(b => {
  122. sync = !!b.props.sync;
  123. });
  124. return sync;
  125. }
  126. exports.default = (() => {
  127. var _ref2 = _asyncToGenerator(function* ({
  128. url, env, routes, renderFullPage, createApp, initialState, onRenderSuccess, timeout = 6000, verbose = true
  129. }) {
  130. try {
  131. if (verbose) {
  132. console.log(`[${url}]`);
  133. console.time(`${url}: render time`);
  134. }
  135. const state = (0, _lodash2.default)({}, initialState || {}, {
  136. ssr: {
  137. env
  138. }
  139. });
  140. const fragment = yield renderFragment(createApp, routes, url, state, timeout, verbose);
  141. if (verbose) {
  142. console.timeEnd(`${url}: render time`);
  143. }
  144. const context = fragment.context;
  145. if (!context) {
  146. return { code: 404, url, env };
  147. } else if (context.url) {
  148. return {
  149. code: 302, url, env, redirect: context.url
  150. };
  151. }
  152. const html = yield renderFullPage(fragment);
  153. if (onRenderSuccess) {
  154. yield onRenderSuccess({
  155. html, url, env, state: fragment.state
  156. });
  157. }
  158. return {
  159. code: 200, url, env, html
  160. };
  161. } catch (e) {
  162. console.error(e);
  163. return {
  164. code: 500, url, env, error: e
  165. };
  166. }
  167. });
  168. function render(_x7) {
  169. return _ref2.apply(this, arguments);
  170. }
  171. return render;
  172. })();
  173. module.exports = exports['default'];