Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
88741a1
commit 223a013
Showing
15 changed files
with
642 additions
and
184 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[ignore] | ||
.*/node_modules/vue/src/*. | ||
.*/dist/*. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; |
Oops, something went wrong.