Authored by 陈峰

cache

... ... @@ -7,7 +7,35 @@ const pkg = require('../../package.json');
const logger = global.yoho.logger;
const {createBundleRenderer} = require('vue-server-renderer');
const isDev = process.env.NODE_ENV === 'development' || !process.env.NODE_ENV;
const routes = [
{
route: /product\/\d+/,
cache: true,
disable: true
},
{
route: '/channel',
cache: true
},
{
route: '/channel/search',
cache: true
},
{
route: '/channel/men',
cache: true
},
{
route: '/channel/women',
cache: true
},
{
route: '/about',
cache: true
},
];
const isDev = false;//process.env.NODE_ENV === 'development' || !process.env.NODE_ENV;
let renderer;
let template = fs.readFileSync(path.join(__dirname, '../../src/index.html'), 'utf-8');
... ... @@ -16,7 +44,8 @@ const microCache = LRU({ // eslint-disable-line
maxAge: 2000
});
const isCacheable = () => {
const isCacheable = (req) => {
console.log(req.route.path.toString())
return false;
};
... ... @@ -35,29 +64,61 @@ const getContext = (req) => {
};
};
const render = (req, res, next) => {
const cacheable = isCacheable(req);
const render = (options) => {
return (req, res, next) => {
if (options.cache) {
const html = microCache.get(req.url);
if (cacheable) {
const html = microCache.get(req.url);
if (html) {
console.log('cache', req.url);
return res.send(html);
}
}
let context = getContext(req);
if (html) {
renderer.renderToString(context, (err, html) => {
if (err) {
// TODO 处理错误类型
return next(err);
}
if (options.cache) {
microCache.set(req.url, html);
}
return res.send(html);
}
}
let context = getContext(req);
});
};
};
const devRender = () => {
return (req, res, next) => {
let context = getContext(req);
process.send({action: 'ssr_request', context});
let event = msg => {
process.removeListener('message', event);
if (msg.action === 'ssr_request') {
if (msg.err) {
try {
const err = JSON.parse(msg.err);
if (err.code === 404) {
return next();
}
return next(err);
} catch (e) {
return next({
code: 500,
message: msg.err
});
}
}
return res.end(msg.html);
}
};
renderer.renderToString(context, (err, html) => {
if (err) {
// TODO 处理错误类型
return next(err);
}
if (cacheable) {
microCache.set(req.url, html);
}
return res.send(html);
});
process.on('message', event);
};
};
const loadBundle = async (errorCount = 0) => {
if (!isDev) {
if (errorCount > 5) {
... ... @@ -91,46 +152,15 @@ const loadBundle = async (errorCount = 0) => {
}
};
const ssrRender = isDev ? (req, res, next) => {
let context = getContext(req);
process.send({action: 'ssr_request', context});
let event = msg => {
process.removeListener('message', event);
if (msg.action === 'ssr_request') {
if (msg.err) {
try {
const err = JSON.parse(msg.err);
if (err.code === 404) {
return next();
}
return next(err);
} catch (e) {
return next({
code: 500,
message: msg.err
});
}
}
return res.end(msg.html);
}
};
process.on('message', event);
} : render;
const routes = [
/product\/\d+/,
'/channel',
'/channel/search',
'/channel/men',
'/channel/women',
'/about'
];
const ssrRender = options => isDev ? devRender(options) : render(options);
module.exports = async (app) => {
await loadBundle();
_.each(routes, r => app.get(r, ssrRender));
_.each(routes, r => {
if (!r.disable) {
app.get(r.route, ssrRender({
cache: r.cache
}));
}
});
};
... ...