builder-isv
Version:
ISV 模块本地预览与云构建器
120 lines (104 loc) • 3.25 kB
JavaScript
/**
* @author 龙喜<xiaolong.lxl@alibaba-inc.com>
* @description 渲染器
*/
;
const fs = require('fs');
const path = require('path');
const xtpl = require('xtpl');
const utils = require('./utils');
const rendererFactory = new (require('../models/rendererFactory'));
const moduleFactory = new (require('../models/moduleFactory'));
module.exports = class Renderer {
/**
* 渲染 solution
* @param req
* @param resp
*/
static *renderPage(req, resp) {
let queries = req.query;
let params = req.params;
// 如果是 native bundle 需要返回 js 代码(这块逻辑最好移到 renderers/xxx/index.js 里)
if ((queries['wh_weex'] === 'true' && /weex/i.test(req.headers['user-agent'])) || queries['wh_ttid'] === 'native' || queries['wh_block'] || queries['wh_chunk']) {
req.params.assets = 'index.native.js';
yield Renderer.renderAssets(req, resp);
} else {
let module = moduleFactory.getModule(params.type, params.name);
let rendererContext = yield rendererFactory.getRenderer(params.type, params.name);
resp.send(yield rendererContext.render(params, req.query, req.headers, module.abcInfo, module.packageInfo));
}
}
/**
* 渲染资源
* @param req
* @param resp
*/
static *renderAssets(req, resp) {
let params = req.params;
let rendererContext = yield rendererFactory.getRenderer(params.type, params.name);
// 等待构建完成
yield rendererContext.waitUntilBundleFinished();
Renderer.renderFile(req, resp, path.join(rendererContext.outputDir, params.name, params.assets));
}
/**
* 渲染一个本地的 XTPL 文件
* @param req
* @param resp
* @param xtplPath 本地资源路径
* @param data
* @returns {Promise}
*/
static renderXTPL(req, resp, xtplPath, data) {
return new Promise((resolve, reject) => {
try {
xtpl.renderFile(path.join(__dirname, `../views/${xtplPath}.xtpl`), data || {}, (err, content) => {
if (err) {
err.message = 'XTPL 渲染异常:' + err.message;
reject(err);
} else {
resp.send(content);
resolve(content);
}
});
} catch (err) {
err.message = 'xtpl 执行异常:' + err.message;
reject(err);
}
});
}
/**
* 渲染文件
* @param req
* @param resp
* @param filePath
* @param type
* @param encoding
* @reference <http://www.iana.org/assignments/media-types/media-types.xhtml>
*/
static renderFile(req, resp, filePath, type, encoding) {
let contentType;
if (!type) {
type = path.extname(filePath).match(/\.(.+)$/);
if (type) {
type = type[1];
} else {
type = 'html';
}
}
if (type === 'js') {
contentType = 'application/javascript';
} else if (type === 'json') {
contentType = 'application/json';
} else if (type === 'css') {
contentType = 'text/css';
} else {
contentType = 'text/html'
}
resp.header('Content-Type', contentType);
try {
resp.send(fs.readFileSync(filePath, encoding || 'utf-8'));
} catch (e) {
throw new Error(`找不到文件:${filePath}`);
}
}
};