1 | const fse = require('fs-extra');
|
2 | const path = require('path');
|
3 |
|
4 | const getRenderedTemplate = (template, opts)=>{
|
5 | const paths = opts.paths;
|
6 | const head = `<script>vitreum_props=\${propsString};</script>
|
7 | <link rel='stylesheet' type='text/css' href='/${opts.entry.name}/${paths.style}' />
|
8 | \${headtags}`;
|
9 | const body = `<main id='vitreum-root'>\${component}</main>`;
|
10 | const tail = `<script src='/${paths.libs}'></script>
|
11 | <script src='/${opts.entry.name}/${paths.code}'></script>
|
12 | <script>
|
13 | (function(){
|
14 | require('react-dom').hydrate(
|
15 | require('react').createElement(${opts.entry.name}, vitreum_props),
|
16 | document.getElementById('vitreum-root')
|
17 | );
|
18 | })();
|
19 | </script>`;
|
20 | return template(head, body, tail);
|
21 | };
|
22 | module.exports = async (opts={})=>{
|
23 | const paths = opts.paths;
|
24 | const code = `const ReactDOMServer = require('react-dom/server');
|
25 | const React = require('react');
|
26 | const Headtags = require('vitreum/headtags.js');
|
27 | let cache = {};
|
28 | ${opts.dev ? `require('source-map-support/register');` : ''}
|
29 |
|
30 | module.exports = (props, opts={})=>{
|
31 | opts = Object.assign({render:true, cache:false}, opts);
|
32 | let component = '', headtags = '';
|
33 | const propsString = JSON.stringify(props);
|
34 | if(opts.cache && cache[propsString]) return cache[propsString];
|
35 | if(opts.render){
|
36 | ${opts.dev ? `delete require.cache[require.resolve('./${paths.code}')];` : ''}
|
37 | global.vitreum_props = props;
|
38 | const Element = require('./${paths.code}');
|
39 | if(!Object.keys(Element).length && typeof Element !== 'function'){
|
40 | throw new Error('${opts.entry.name} component was improperly built. Check the /build folder.');
|
41 | }
|
42 | component = ReactDOMServer.renderToString(React.createElement(Element, props));
|
43 | headtags = Headtags.generate();
|
44 | }
|
45 | const html = \`${getRenderedTemplate(opts.template, opts)}\`;
|
46 | if(opts.cache) cache[propsString] = html;
|
47 | return html;
|
48 | };`;
|
49 | await fse.writeFile(`${paths.build}/${opts.entry.name}/${paths.render}`, code);
|
50 | if(opts.static){
|
51 |
|
52 | const renderer = require(path.resolve(process.cwd(), `${paths.build}/${opts.entry.name}/${paths.render}`));
|
53 | await fse.writeFile(`${paths.build}/${opts.entry.name}/${paths.static}`, renderer())
|
54 | }
|
55 | };
|