Skip to content

Commit

Permalink
v2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
danielcherubini committed Oct 26, 2016
1 parent 88741a1 commit 223a013
Show file tree
Hide file tree
Showing 15 changed files with 642 additions and 184 deletions.
3 changes: 3 additions & 0 deletions .flowconfig
@@ -0,0 +1,3 @@
[ignore]
.*/node_modules/vue/src/*.
.*/dist/*.
30 changes: 30 additions & 0 deletions dist/defaults.js
@@ -0,0 +1,30 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Types = function Types() {
_classCallCheck(this, Types);

this.COMPONENT = 'COMPONENT';
this.SUBCOMPONENT = 'SUBCOMPONENT';
this.LAYOUT = 'LAYOUT';
};

var Defaults = function Defaults() {
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

_classCallCheck(this, Defaults);

this.rootPath = obj.rootPath || __dirname + '/../';
this.layoutsDir = obj.rootPath + obj.layoutsDir || '/app/routes/';
this.componentsDir = obj.rootPath + obj.componentsDir || '/app/components/';
this.defaultLayout = obj.defaultLayout || 'layout';
this.options = obj.options || undefined;
};

exports.Types = Types;
exports.Defaults = Defaults;
89 changes: 22 additions & 67 deletions dist/index.js
Expand Up @@ -3,84 +3,39 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
var fs = require('fs');
var bodyRegx = /(<template>)([\s\S]*?)(<\/template>)/gm;
var scriptRegex = /(export default {)([\s\S]*?)(^};?$)/gm;
var dataRegex = /(\'\$parent\').(\w*)/gm;
var layoutRegex = /{{{body}}}/igm;
var defaults = {
layoutsDir: '/app/components/',
defaultLayout: 'layout',
options: undefined
};

function expressVue(filePath, options, callback) {
var _defaults = require('./defaults');

defaults = options.settings.vue;
defaults.layoutPath = defaults.layoutsDir + defaults.defaultLayout + '.vue';
defaults.options = options;
var _parser = require('./parser');

Promise.all([layoutParser(defaults.layoutPath), componentParser(filePath)]).then(function (data) {
var layout = data[0];
var template = data[1];
var html = layout.replace(layoutRegex, template);
var _utils = require('./utils');

callback(null, html);
}, function (error) {
callback(new Error(error));
});
}
function expressVue(componentPath, options, callback) {

function bodyParser(body) {
var bodyString = body.match(bodyRegx)[0];
if (bodyString) {
bodyString = bodyString.replace(bodyRegx, '$2');
}
return bodyString;
}
var defaults = new _defaults.Defaults(options.settings.vue);
var types = new _defaults.Types();
defaults.layoutPath = defaults.layoutsDir + defaults.defaultLayout + '.vue';
defaults.options = options;

function scriptParser(script) {
var scriptString = script.match(scriptRegex)[0];
if (scriptString) {
scriptString = scriptString.replace(scriptRegex, '({$2})').replace(dataRegex, function (match, p1, p2) {
return JSON.stringify(defaults.options[p2]);
});
}
return scriptString;
}
var componentArray = [(0, _parser.layoutParser)(defaults.layoutPath, defaults, types.LAYOUT), (0, _parser.componentParser)(componentPath, defaults, types.COMPONENT)];

function layoutParser(layoutPath) {
return new Promise(function (resolve, reject) {
fs.readFile(layoutPath, function (err, content) {
if (err) {
reject(new Error(err));
if (defaults.options.components) {
for (var component in defaults.options.components) {
if (defaults.options.components.hasOwnProperty(component)) {
var componentFile = defaults.componentsDir + defaults.options.components[component] + '.vue';
componentArray.push((0, _parser.componentParser)(componentFile, defaults, types.SUBCOMPONENT));
}
var contentString = content.toString();
var body = bodyParser(contentString);
var script = scriptParser(contentString);

var layout = body.replace('{{{script}}}', '<script>new Vue(' + script + ')</script>');
}
}

resolve(layout);
});
Promise.all(componentArray).then(function (components) {
var html = (0, _utils.renderHtmlUtil)(components, defaults);
callback(null, html);
}, function (error) {
callback(new Error(error));
});
}

function componentParser(template) {
return new Promise(function (resolve, reject) {
fs.readFile(template, function (err, content) {
if (err) {
reject(new Error(err));
}
var contentString = content.toString();
var body = bodyParser(contentString);
var script = scriptParser(contentString);

var template = body + '<script>new Vue(' + script + ')</script>';

resolve(template);
});
});
}
expressVue.componentParser = _parser.componentParser;

exports.default = expressVue;
135 changes: 135 additions & 0 deletions dist/parser/index.js
@@ -0,0 +1,135 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.layoutParser = exports.componentParser = undefined;

var _fs = require('fs');

var _fs2 = _interopRequireDefault(_fs);

var _htmlMinifier = require('html-minifier');

var _htmlMinifier2 = _interopRequireDefault(_htmlMinifier);

var _defaults = require('../defaults');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var htmlMinifier = _htmlMinifier2.default.minify;
var htmlRegex = /(<template?.*>)([\s\S]*?)(<\/template>)/gm;
var scriptRegex = /(<script?.*>)([\s\S]*?)(<\/script>)/gm;
var types = new _defaults.Types();

function htmlParser(body, minify) {
var bodyString = body.match(htmlRegex)[0];
if (bodyString) {
bodyString = bodyString.replace(htmlRegex, '$2');
}

if (minify) {
bodyString = htmlMinifier(bodyString, {
collapseWhitespace: true
});
}

return bodyString;
}

function dataMatcher(vueData, controllerData, type) {
var obj = {};
for (var controllerDataKey in controllerData) {
if (controllerData.hasOwnProperty(controllerDataKey)) {
for (var vueDataKey in vueData) {
if (vueData.hasOwnProperty(vueDataKey)) {
switch (type) {
case types.LAYOUT:
break;
case types.COMPONENT:
obj[controllerDataKey] = controllerData[controllerDataKey];
obj[vueDataKey] = vueData[vueDataKey];
break;
case types.SUBCOMPONENT:
obj[vueDataKey] = vueData[vueDataKey];
break;
}
}
}
}
}
var output = 'data: () => {return ' + JSON.stringify(obj) + ';};';
return output;
}

function dataParser(script, defaults, type) {
var finalScript = {};
for (var element in script) {
if (script.hasOwnProperty(element)) {
if (element === 'data') {
var data = script.data();
var output = dataMatcher(data, defaults.options.data, type);
finalScript[element] = eval(output);
} else {
finalScript[element] = script[element];
}
}
}
return finalScript;
}

function scriptParser(script, defaults, type) {
var scriptString = script.match(scriptRegex)[0].replace(scriptRegex, '$2');
var babelScript = require('babel-core').transform(scriptString, { 'presets': ['es2015'] }).code;
var evalScript = eval(babelScript);
var finalScript = dataParser(evalScript, defaults, type);
return finalScript;
}

function layoutParser(layoutPath, defaults, type) {

return new Promise(function (resolve, reject) {
_fs2.default.readFile(layoutPath, function (err, content) {
if (err) {
reject(new Error(err));
}
var layoutString = content.toString();
var body = htmlParser(layoutString);
layoutString = layoutString.replace(htmlRegex, '');
var script = scriptParser(layoutString, defaults, type);
resolve({
type: type,
template: body,
script: script
});
});
});
}

function componentParser(templatePath, defaults, type) {
return new Promise(function (resolve, reject) {
_fs2.default.readFile(templatePath, function (err, content) {
if (err) {
reject(new Error(err));
}

var componentString = content.toString();

var body = htmlParser(componentString, true);
componentString = componentString.replace(htmlRegex, '');
var script = scriptParser(componentString, defaults, type);

var componentScript = script;
componentScript.template = body;

resolve({
type: type,
name: templatePath.match(/\w*\.vue/g)[0].replace('\.vue', ''),
script: componentScript
});
});
});
}

exports.componentParser = componentParser;
exports.layoutParser = layoutParser;
15 changes: 15 additions & 0 deletions dist/utils/index.js
@@ -0,0 +1,15 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.scriptToString = exports.renderHtmlUtil = exports.layoutUtil = exports.renderUtil = undefined;

var _render = require('./render');

var _string = require('./string');

exports.renderUtil = _render.renderUtil;
exports.layoutUtil = _render.layoutUtil;
exports.renderHtmlUtil = _render.renderHtmlUtil;
exports.scriptToString = _string.scriptToString;
97 changes: 97 additions & 0 deletions dist/utils/render.js
@@ -0,0 +1,97 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.renderHtmlUtil = exports.layoutUtil = exports.renderUtil = undefined;

var _defaults = require('../defaults');

var _string = require('./string');

var renderer = require('vue-server-renderer').createRenderer();
var appRegex = /{{{app}}}/igm;
var scriptRegex = /{{{script}}}/igm;
var titleRegex = /{{{title}}}/igm;
var types = new _defaults.Types();

function createApp(script) {
return new Vue(script);
if (typeof module !== 'undefined' && module.exports) {
module.exports = createApp;
} else {
this.app = createApp();
}
}

function layoutUtil(components) {
var layout = {};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;

try {
for (var _iterator = components[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var component = _step.value;

switch (component.type) {
case types.LAYOUT:
layout = component;
break;
case types.COMPONENT:
layout.template = layout.template.replace(appRegex, '<div id="app">' + component.script.template + '</div>');
layout.script = component.script;
break;
case types.SUBCOMPONENT:
if (layout.script.components) {
layout.script.components[component.name] = component.script;
} else {
layout.script.components = {};
layout.script.components[component.name] = component.script;
}
break;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}

return layout;
}

function renderUtil(layout, renderedScriptString, defaults) {
var html = '';
global.Vue = require('vue');
renderer.renderToString(createApp(layout.script), function (error, renderedHtml) {
html = layout.template.replace(appRegex, '<div id="app">' + renderedHtml + '</div>');
html = html.replace(scriptRegex, renderedScriptString);
html = html.replace(titleRegex, layout.script.data.title || defaults.options.title);
});
return html;
}

function renderedScript(script) {
var scriptString = (0, _string.scriptToString)(script);
return '<script>\n (function () {\n \'use strict\'\n var createApp = function () {\n return new Vue(\n ' + scriptString + '\n )\n }\n if (typeof module !== \'undefined\' && module.exports) {\n module.exports = createApp\n } else {\n this.app = createApp()\n }\n }).call(this)\n </script>';
}

function renderHtmlUtil(components, defaults) {
var layout = layoutUtil(components);
var renderedScriptString = renderedScript(layout.script);
return renderUtil(layout, renderedScriptString, defaults);
}

exports.renderUtil = renderUtil;
exports.layoutUtil = layoutUtil;
exports.renderHtmlUtil = renderHtmlUtil;

0 comments on commit 223a013

Please sign in to comment.