UNPKG

ala-cli

Version:

aladdin develop utils

235 lines (186 loc) 5.73 kB
/** * * @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 };