forked from reactjs/express-react-views
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
76 lines (65 loc) · 2.56 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
var React = require('react');
var beautifyHTML = require('js-beautify').html;
var nodeJSX = require('node-jsx');
var assign = require('object-assign');
var DEFAULT_OPTIONS = {
jsx: {
extension: '.jsx',
harmony: false,
stripTypes: false
},
doctype: '<!DOCTYPE html>',
beautify: false
};
function createEngine(engineOptions) {
engineOptions = engineOptions || {};
// Merge was nice because it did nest objects. assign doesn't. So we're going
// to assign the JSX options then the rest. If there were more than a single
// nested option, this would be really dumb. As is, it looks pretty stupid but
// it keeps our dependencies slim.
var jsxOptions = assign({}, DEFAULT_OPTIONS.jsx, engineOptions.jsx);
// Since we're passing an object with jsx as the key, it'll override the rest.
engineOptions = assign({}, DEFAULT_OPTIONS, engineOptions, {jsx: jsxOptions});
// Don't install the require until the engine is created. This lets us leave
// the option of using harmony features up to the consumer.
nodeJSX.install(engineOptions.jsx);
var moduleDetectRegEx = new RegExp('\\' + engineOptions.jsx.extension + '$');
function renderFile(filename, options, cb) {
try {
var markup = engineOptions.doctype;
var component = require(filename);
// Transpiled ES6 may export components as { default: Component }
component = component.default || component;
markup +=
React.renderToStaticMarkup(React.createElement(component, options));
} catch (e) {
return cb(e);
}
if (engineOptions.beautify) {
// NOTE: This will screw up some things where whitespace is important, and be
// subtly different than prod.
markup = beautifyHTML(markup);
}
if (options.settings.env === 'development') {
// Remove all files from the module cache that use our extension. If we're
// using .js, this could be sloooow. On the plus side, we can now make changes
// to our views without needing to restart the server.
Object.keys(require.cache).forEach(function(module) {
if (moduleDetectRegEx.test(require.cache[module].filename)) {
delete require.cache[module];
}
});
}
cb(null, markup);
}
return renderFile;
}
exports.createEngine = createEngine;