Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

create-react-app-ssr

Package Overview
Dependencies
Maintainers
1
Versions
63
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

create-react-app-ssr - npm Package Compare versions

Comparing version 2.0.10 to 2.0.11

howto/setup.md

1

index.js

@@ -7,2 +7,3 @@

invalidateSSRCache: require('./lib/memcached').invalidateCache,
webpackReactLoadable: require('./lib/webpack-react-loadable').webpackReactLoadable,
}

@@ -12,2 +12,6 @@ 'use strict';

var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _express = require('express');

@@ -35,13 +39,49 @@

var defaultSettings = {
// do you want to run ssr or not?
// @TODO: this might be a function so to make this decision dynamic
enabled: String(process.env.REACT_APP_SSR_ENABLED || 'yes'),
cwd: String(process.env.REACT_APP_SSR_CWD || process.cwd()),
root: String(process.env.REACT_APP_SSR_ROOT || 'src'),
build: String(process.env.REACT_APP_SSR_BUILD || 'build'),
// comma serparated list of routes that will skip ssr
blacklist: String(process.env.REACT_APP_SSR_BLACKLIST || ''),
// react app's folders (absolute path)
// we need to know where to locate your client's source files
// and your ready-to-ship assets.
source: String(process.env.REACT_APP_SSR_ROOT || _path2.default.join(process.cwd(), 'src')),
build: String(process.env.REACT_APP_SSR_BUILD || _path2.default.join(process.cwd(), 'build')),
// @TODO: find out a better way to handle callback urls client-to-server
// durig ssr.
port: String(process.env.REACT_APP_SSR_PORT || '8080'),
// strips away all the javascript tags.
// basically renders a pure HTML static web page.
disableJs: String(process.env.REACT_APP_SSR_DISABLE_JS || 'no'),
blacklist: String(process.env.REACT_APP_SSR_BLACKLIST || ''),
// maximum ssr execution time, useful to reduce server bottlenecks in case
// apis or similar stuff get into the way
renderTimeout: Number(process.env.REACT_APP_SSR_RENDER_TIMEOUT || 5000),
// maximum number of ssr re-rendering waiting for asychronous code to finish
// this is useful if the client enters in loops based on data loading that
// does not preserve the results in between renderings
// @TODO: document this with examples
renderLimit: Number(process.env.REACT_APP_SSR_RENDER_LIMIT || 10),
// CRA settings to handle images that might have beed embedded into the
// shipped bundles, this is used by the "register-hook"
embedExt: String(process.env.REACT_APP_SSR_EMBED_EXT || '.png,.jpg,jpeg,.gif,svg'),
embedLimit: Number(process.env.REACT_APP_SSR_EMBED_LIMIT || 10000)
embedLimit: Number(process.env.REACT_APP_SSR_EMBED_LIMIT || 10000),
// allow the in-memory cache system to kick in.
useCache: String(process.env.REACT_APP_SSR_USE_CACHE || 'yes'),
// by default the SSR middleware will send out the produced HTML to the client
// but this could be avoided if the app will implement some custom
// post-processing logic.
sendHtml: String(process.env.REACT_APP_SSR_SEND_HTML || 'yes'),
// the HTML that is produced after a rendering is appended to the "req"
// context variable for custom post processing.
dataVar: String(process.env.REACT_APP_SSR_DATA_VAR || 'ssrOutput')
};

@@ -48,0 +88,0 @@

112

lib/memcached.js

@@ -141,7 +141,20 @@ "use strict";

case 0:
if (!settings.serializer) {
_context2.next = 4;
break;
}
_context2.next = 3;
return settings.serializer.remove(toBeRemoved);
case 3:
return _context2.abrupt("return");
case 4:
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context2.prev = 3;
_context2.prev = 7;
for (_iterator = toBeRemoved[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {

@@ -153,14 +166,14 @@ key = _step.value;

}
_context2.next = 11;
_context2.next = 15;
break;
case 7:
_context2.prev = 7;
_context2.t0 = _context2["catch"](3);
case 11:
_context2.prev = 11;
_context2.t0 = _context2["catch"](7);
_didIteratorError = true;
_iteratorError = _context2.t0;
case 11:
_context2.prev = 11;
_context2.prev = 12;
case 15:
_context2.prev = 15;
_context2.prev = 16;

@@ -171,7 +184,7 @@ if (!_iteratorNormalCompletion && _iterator.return) {

case 14:
_context2.prev = 14;
case 18:
_context2.prev = 18;
if (!_didIteratorError) {
_context2.next = 17;
_context2.next = 21;
break;

@@ -182,9 +195,9 @@ }

case 17:
return _context2.finish(14);
case 21:
return _context2.finish(18);
case 18:
return _context2.finish(11);
case 22:
return _context2.finish(15);
case 19:
case 23:
case "end":

@@ -194,3 +207,3 @@ return _context2.stop();

}
}, _callee2, undefined, [[3, 7, 11, 19], [12,, 14, 18]]);
}, _callee2, undefined, [[7, 11, 15, 23], [16,, 18, 22]]);
}));

@@ -205,3 +218,3 @@

var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(req, res, html) {
var key;
var key, cacheObject;
return _regenerator2.default.wrap(function _callee3$(_context3) {

@@ -228,10 +241,26 @@ while (1) {

key = _context3.sent;
cache[key.value] = {
cacheObject = {
ctm: Date.now(),
exp: settings.getCacheExpiry(req, res),
cnt: settings.onCacheWrites(req, res, html)
// custom serializer implementation
};
case 8:
if (!settings.serializer) {
_context3.next = 12;
break;
}
_context3.next = 11;
return settings.serializer.set(key, cacheObject);
case 11:
return _context3.abrupt("return");
case 12:
cache[key.value] = cacheObject;
case 13:
case "end":

@@ -251,3 +280,3 @@ return _context3.stop();

var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(req, res) {
var key;
var key, cacheObject;
return _regenerator2.default.wrap(function _callee4$(_context4) {

@@ -263,25 +292,44 @@ while (1) {

if (cache[key.value]) {
_context4.next = 5;
if (!settings.serializer) {
_context4.next = 9;
break;
}
_context4.next = 6;
return settings.serializer.get(key);
case 6:
_context4.t0 = _context4.sent;
_context4.next = 10;
break;
case 9:
_context4.t0 = cache[key.value];
case 10:
cacheObject = _context4.t0;
if (cacheObject) {
_context4.next = 13;
break;
}
return _context4.abrupt("return");
case 5:
if (!(cache[key.value].exp < Date.now())) {
_context4.next = 9;
case 13:
if (!(cacheObject.exp < Date.now())) {
_context4.next = 17;
break;
}
_context4.next = 8;
_context4.next = 16;
return remove(key.value);
case 8:
case 16:
return _context4.abrupt("return");
case 9:
return _context4.abrupt("return", settings.onCacheRead(req, res, cache[key.value]));
case 17:
return _context4.abrupt("return", settings.onCacheRead(req, res, cacheObject));
case 10:
case 18:
case "end":

@@ -288,0 +336,0 @@ return _context4.stop();

@@ -14,3 +14,4 @@ 'use strict';

var readSourceFile = function readSourceFile(filePath) {
var encoding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'utf8';
var parseJson = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var encoding = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'utf8';
return new Promise(function (resolve, reject) {

@@ -27,4 +28,16 @@ if (readSourceFile.cache[filePath]) {

}
readSourceFile.cache[filePath] = data;
resolve(data);
// optional json parse applied to the file
var content = data;
if (parseJson) {
try {
content = JSON.parse(data);
} catch (err) {
reject(err);
return;
}
}
readSourceFile.cache[filePath] = content;
resolve(content);
});

@@ -31,0 +44,0 @@ } catch (err) {

@@ -26,4 +26,6 @@ 'use strict';

var _webpack = require('react-loadable/webpack');
var _mapModulesToBundles = require('./map-modules-to-bundles');
var _mapModulesToBundles2 = _interopRequireDefault(_mapModulesToBundles);
var _readSourceFile = require('./read-source-file');

@@ -64,3 +66,3 @@

var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(req, res, next) {
var cachedHTML, filePath, htmlTemplate, initialState, prerender, helmet, jsBundles, cssBundles, bundleStats, html;
var cachedHTML, filePath, htmlTemplate, initialState, prerender, helmet, mappedBundles, html;
return _regenerator2.default.wrap(function _callee$(_context) {

@@ -70,11 +72,16 @@ while (1) {

case 0:
_context.prev = 0;
_context.next = 3;
if (!(settings.useCache === 'yes')) {
_context.next = 13;
break;
}
_context.prev = 1;
_context.next = 4;
return cache.get(req, res);
case 3:
case 4:
cachedHTML = _context.sent;
if (!(typeof cachedHTML === 'string')) {
_context.next = 7;
_context.next = 8;
break;

@@ -86,14 +93,14 @@ }

case 7:
_context.next = 12;
case 8:
_context.next = 13;
break;
case 9:
_context.prev = 9;
_context.t0 = _context['catch'](0);
case 10:
_context.prev = 10;
_context.t0 = _context['catch'](1);
console.log('[ssr] read cache error for "' + req.url + '" - ' + _context.t0.message);
case 12:
_context.prev = 12;
case 13:
_context.prev = 13;

@@ -105,12 +112,12 @@ console.log('[ssr] ' + req.url);

if (staticRender) {
_context.next = 28;
_context.next = 29;
break;
}
_context.prev = 15;
_context.prev = 16;
staticRender = require(_path2.default.join(settings.cwd, settings.root, 'app/ssr')).staticRender;
staticRender = require(_path2.default.join(settings.source, 'app/ssr')).staticRender;
if (staticRender) {
_context.next = 19;
_context.next = 20;
break;

@@ -121,5 +128,5 @@ }

case 19:
case 20:
if (!(typeof staticRender !== 'function')) {
_context.next = 21;
_context.next = 22;
break;

@@ -130,5 +137,5 @@ }

case 21:
case 22:
if (!(staticRender.ssrVersion !== _currentVersion2.default)) {
_context.next = 23;
_context.next = 24;
break;

@@ -139,9 +146,9 @@ }

case 23:
_context.next = 28;
case 24:
_context.next = 29;
break;
case 25:
_context.prev = 25;
_context.t1 = _context['catch'](15);
case 26:
_context.prev = 26;
_context.t1 = _context['catch'](16);

@@ -157,8 +164,8 @@ // fallback on a default static render that will visualize the error

case 28:
case 29:
filePath = _path2.default.resolve(_path2.default.join(settings.build, 'index.html'));
_context.next = 31;
_context.next = 32;
return (0, _readSourceFile2.default)(filePath);
case 31:
case 32:
htmlTemplate = _context.sent;

@@ -178,3 +185,3 @@ initialState = {

};
_context.next = 35;
_context.next = 36;
return staticRender(req.url, initialState, {

@@ -187,7 +194,7 @@ req: req, res: res, // proxy express handlers

case 35:
case 36:
prerender = _context.sent;
if (!prerender.context.url) {
_context.next = 39;
_context.next = 40;
break;

@@ -199,3 +206,3 @@ }

case 39:
case 40:

@@ -205,31 +212,9 @@ // get SEO headers for the page

// react-loadable -- get rendered chunks, if eny exists
// include dynamically requested bundles (via react-loadable)
jsBundles = [];
cssBundles = [];
_context.next = 43;
return (0, _mapModulesToBundles2.default)(settings, prerender.modules);
console.log(prerender.modules);
try {
bundleStats = require(_path2.default.join(settings.build, 'react-loadable.json'));
jsBundles = (0, _webpack.getBundles)(bundleStats, prerender.modules).filter(function (bundle) {
return bundle.file.indexOf('.js.map') === -1;
}) // remove sourcemaps
.filter(function (bundle) {
return bundle.file.indexOf('.css') === -1;
}) // remove css
.map(function (bundle) {
return '<script type="text/javascript" src="' + bundle.publicPath + '"></script>';
});
cssBundles = (0, _webpack.getBundles)(bundleStats, prerender.modules).filter(function (bundle) {
return bundle.file.indexOf('.css') !== -1;
}) // remove css
.filter(function (bundle) {
return bundle.file.indexOf('.map') === -1;
}) // remove maps
.map(function (bundle) {
return '<link href="' + bundle.publicPath + '" rel="stylesheet">';
});
} catch (err) {}
case 43:
mappedBundles = _context.sent;
html = (0, _prepHtml2.default)(htmlTemplate, (0, _extends3.default)({}, settings, {

@@ -240,4 +225,4 @@ html: helmet.htmlAttributes.toString(),

state: prerender.initialState,
jsBundles: jsBundles,
cssBundles: cssBundles
jsBundles: mappedBundles.js,
cssBundles: mappedBundles.css
}));

@@ -247,20 +232,44 @@

res.send(html);
if (settings.sendHtml === 'yes') {
res.send(html);
}
// store a cache version of the rendered html
// try {
// await cache.set(req, res, html)
// } catch (err) {
// console.log(`[ssr] write cache error for "${req.url}" - ${err.message}`)
// }
_context.next = 51;
if (!(settings.useCache === 'yes')) {
_context.next = 55;
break;
}
_context.prev = 47;
_context.next = 50;
return cache.set(req, res, html);
case 50:
_context.next = 55;
break;
case 48:
_context.prev = 48;
_context.t2 = _context['catch'](12);
case 52:
_context.prev = 52;
_context.t2 = _context['catch'](47);
next(_context.t2);
console.log('[ssr] write cache error for "' + req.url + '" - ' + _context.t2.message);
case 51:
case 55:
// decorate the request with the produced html so to allow
// the implementation of custom caching mechanism or post
// rendering filters
req[settings.dataVar] = html;
next();
_context.next = 62;
break;
case 59:
_context.prev = 59;
_context.t3 = _context['catch'](13);
next(_context.t3);
case 62:
case 'end':

@@ -270,3 +279,3 @@ return _context.stop();

}
}, _callee, undefined, [[0, 9], [12, 48], [15, 25]]);
}, _callee, undefined, [[1, 10], [13, 59], [16, 26], [47, 52]]);
}));

@@ -273,0 +282,0 @@

@@ -23,5 +23,9 @@ 'use strict';

config.plugins = [].concat((0, _toConsumableArray3.default)(config.plugins), [new _webpack.ReactLoadablePlugin({
filename: settings.target || './build/react-loadable.json'
})]);
// it's possible to skip the plugin as with CRA there is already a
// "asset-manifest.json" that SSR can use to map dynamically loaded bundles.
if (settings.skipPlugin !== true) {
config.plugins = [].concat((0, _toConsumableArray3.default)(config.plugins), [new _webpack.ReactLoadablePlugin({
filename: settings.target || './build/react-loadable.json'
})]);
}

@@ -28,0 +32,0 @@ // "chunks:all" generates some unpredictable chunks based on "node_modules"

{
"name": "create-react-app-ssr",
"version": "2.0.10",
"version": "2.0.11",
"description": "Server Side Rendering for CRA 2.x (with redux, router, code splitting, ...)",

@@ -9,3 +9,4 @@ "main": "index.js",

"start": "node_modules/babel-cli/bin/babel.js --watch src --out-dir lib",
"test": "echo \"Error: no test specified\" && exit 1"
"book:serve": "node_modules/.bin/gitbook serve",
"book:build": "node_modules/.bin/gitbook build . docs"
},

@@ -47,2 +48,3 @@ "babel": {

"babel-runtime": "^6.26.0",
"gitbook-cli": "^2.3.2",
"install-peers": "^1.0.3"

@@ -49,0 +51,0 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc