ala-cli
Version:
aladdin develop utils
235 lines (186 loc) • 5.73 kB
JavaScript
/**
*
* @file vue解析
* @author alafe
* @date 2017/5/8
*
*/
const fs = require('fs');
const path = require('path');
const vipRender = require('vip-server-renderer');
let dirRoot = process.cwd();
let appConf = require(path.join(dirRoot, 'app.conf'));
// 去掉换行和空格符
function trim (str) {
return str.replace(/\s*\r*\n+\s*/g, '');
}
// 处理php特殊字符
function output (str) {
return trim(str).replace(/\$/g, '\\' + '$');
}
function toCss (vueObj) {
let styles = vueObj.root.styles;
let text = '';
for (let i in styles) {
text += styles[i];
}
return text;
}
function toJs (vueObj) {
let scripts = vueObj.root.scripts;
let script = scripts[vueObj.name];
let data = (vueObj.instance.data && vueObj.instance.data()) || {};
let compText = '';
let text = '';
for (let i in vueObj.instance.components) {
compText += compText ? ',' : '';
compText += i + ':require(\'' + 'static/' + vueObj.root.components[i] + '\')';
}
text += `
define(function (require) {
var module = {
exports: {}
}
var vueObj;
(function (module) {
${script}
})(module);
vueObj = module.exports;
vueObj.template = ${JSON.stringify(vueObj.instance.template)};
vueObj.props = ${JSON.stringify(vueObj.instance.props)};
vueObj.data = function () { return ${JSON.stringify(data)}; };
vueObj.components = {${compText}};
return vueObj;
});
`;
return text;
}
// 获取接口模板
function getTemplate (fileName, instance) {
let props = instance.props;
let bindProps = [];
let bindStr = '';
if (props) {
if (props instanceof Array) {
props.forEach((a) => {
bindProps.push(a);
});
}
else if (props instanceof Object) {
for (let a in props) {
bindProps.push(a);
}
}
}
bindProps.forEach((a) => {
bindStr += `:${a}="${a}" `;
});
return '<App ' + bindStr + '/>';
}
// 获取组件路径
function getCompPath (fileName) {
let list = fileName.split('/');
let len = list.length;
return list[len-2] + '/' + list[len-1];
}
// 获取组件名称
function getCompName (fileName) {
let list = fileName.split('/');
let len = list.length;
if (list[len-1] === 'index') {
return list[len-2];
} else {
return list[len-1];
}
}
// 解析vue模板成对象
function parse (fileName, root) {
// 调试代码报错
try {
let compPath = getCompPath(fileName);
let compName = getCompName(fileName);
let file = path.join(appConf.root, appConf.modules.app, compPath + '.vue');
let content = fs.readFileSync(file, 'utf8');
let blocks = vipRender.compile({
content: content,
mode: 'amd',
jsPath(path, tmpVal) {
return 'static/' + tmpVal.replace('../', '');
},
phpPath(tmpPath, tmpVal) {
return 'aladdin/' + tmpVal.replace('../', '') + '.php';
}
}).blocks;
console.log(blocks);
// 判断是否是根节点
let isRoot = !root;
// 实例化对象,用于服务端渲染
let instance = {};
let template = blocks.template.code || '<div></div>';
if (/lang="jade"/.test(content)) {
// template = jade.render(template);
} else {
template = trim(template);
}
let style = (blocks.styles && blocks.styles[0] && blocks.styles[0].code) || '';
if (/lang="stylus"/.test(content)) {
// style = stylus.render(style);
} else {
style = trim(style);
}
let config = (blocks.config && blocks.config.code) || '{}';
try {
config = (new Function(`return ${trim(config)};`))();
} catch (e) {
console.log('config 解析错误: ' + e);
config = {};
}
let script = (blocks.script && blocks.script.code) || '';
// vue实例化对象
instance.template = template;
if (config.props) {
instance.props = config.props;
}
if (config.data) {
instance.data = new Function(`return ${JSON.stringify(config.data)}`);
}
if (isRoot) {
root = {
template: getTemplate(fileName, instance),
styles: {},
scripts: {},
components: {}
};
// 只遍历根节点组件
if (config.components) {
let components = {};
let comp;
for (let i in config.components) {
comp = parse(fileName.replace(/\/index$/, '') + '/' + config.components[i], root);
components[i] = comp.instance;
}
instance.components = components;
}
}
// 获取样式,脚本集合
root.styles[compName] = style;
root.scripts[compName] = script;
root.components[compName] = compPath;
return {
instance: instance,
name: compName,
path: compPath,
root: root
};
// 调试代码报错
} catch (e) {
console.log('parse-error: ', e);
}
}
module.exports = {
trim: trim,
output: output,
toCss: toCss,
toJs: toJs,
parse: parse
};