...
|
...
|
@@ -9,6 +9,7 @@ const routes = require('../../config/ssr-routes'); |
|
|
const redis = require('../../utils/redis');
|
|
|
const routeEncode = require('../../utils/route-encode');
|
|
|
const {createBundleRenderer} = require('vue-server-renderer');
|
|
|
const Handlebars = require('handlebars');
|
|
|
const logger = global.yoho.logger;
|
|
|
const config = global.yoho.config;
|
|
|
|
...
|
...
|
@@ -18,8 +19,11 @@ let renderer; |
|
|
let serverBundle;
|
|
|
let degradeHtml;
|
|
|
|
|
|
const hbs = fs.readFileSync(path.join(__dirname, '../views/index.hbs'), 'utf-8');
|
|
|
|
|
|
const template = Handlebars.compile(hbs);
|
|
|
|
|
|
if (!isDev) {
|
|
|
const template = fs.readFileSync(path.join(__dirname, '../../index.html'), 'utf-8');
|
|
|
|
|
|
degradeHtml = fs.readFileSync(path.join(__dirname, '../../degrade.html'), 'utf-8');
|
|
|
|
...
|
...
|
@@ -28,11 +32,28 @@ if (!isDev) { |
|
|
|
|
|
renderer = createBundleRenderer(serverBundle, {
|
|
|
runInNewContext: false,
|
|
|
template,
|
|
|
clientManifest
|
|
|
clientManifest,
|
|
|
inject: false
|
|
|
});
|
|
|
}
|
|
|
|
|
|
const REG_SCRIPT = /src="([^"]+)"/g;
|
|
|
|
|
|
const asyncLoadScripts = (renderScripts) => {
|
|
|
let match;
|
|
|
const scripts = [];
|
|
|
|
|
|
while ((match = REG_SCRIPT.exec(renderScripts))) {
|
|
|
scripts.push({
|
|
|
src: match[1],
|
|
|
index: scripts.length
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return scripts;
|
|
|
};
|
|
|
|
|
|
|
|
|
const getContext = (req) => {
|
|
|
return {
|
|
|
url: req.url,
|
...
|
...
|
@@ -103,13 +124,33 @@ const render = (route) => { |
|
|
let context = getContext(req);
|
|
|
|
|
|
renderer.renderToString(context, (err, html) => {
|
|
|
|
|
|
if (err) {
|
|
|
return handlerError(err, req, res, next);
|
|
|
}
|
|
|
const styles = context.renderStyles();
|
|
|
let scripts = context.renderScripts();
|
|
|
const resources = context.renderResourceHints();
|
|
|
const states = context.renderState();
|
|
|
let asyncScripts;
|
|
|
|
|
|
if (req.yoho.isiOS) {
|
|
|
asyncScripts = asyncLoadScripts(scripts);
|
|
|
}
|
|
|
|
|
|
const result = template({
|
|
|
html,
|
|
|
styles,
|
|
|
scripts,
|
|
|
asyncScripts,
|
|
|
resources,
|
|
|
states
|
|
|
});
|
|
|
|
|
|
if (config.useCache && route.cache && ck) {
|
|
|
redis.setex(ck, route.cacheTime || 60, html);
|
|
|
redis.setex(ck, route.cacheTime || 60, result);
|
|
|
}
|
|
|
return res.send(html);
|
|
|
return res.send(result);
|
|
|
});
|
|
|
} catch (error) {
|
|
|
return next(error);
|
...
|
...
|
@@ -158,10 +199,21 @@ const devRender = (route) => { |
|
|
} catch (error) {} // eslint-disable-line
|
|
|
return handlerError(err, req, res, next);
|
|
|
}
|
|
|
let {styles, scripts, resources, states, html} = msg;
|
|
|
|
|
|
const result = template({
|
|
|
html,
|
|
|
styles,
|
|
|
scripts,
|
|
|
resources,
|
|
|
states
|
|
|
});
|
|
|
|
|
|
|
|
|
if (config.useCache && route.cache && ck) {
|
|
|
redis.setex(ck, route.cacheTime || 60, msg.html);
|
|
|
redis.setex(ck, route.cacheTime || 60, result);
|
|
|
}
|
|
|
return res.end(msg.html);
|
|
|
return res.end(result);
|
|
|
}
|
|
|
};
|
|
|
|
...
|
...
|
|