vuetc-gulp
Version:
Vue template compiler for Gulp. Gulp-plugin for compiling and bundling VueJS templates.
145 lines (117 loc) • 4.44 kB
JavaScript
var through = require('through2');
var path = require('path');
var File = require('vinyl');
var compiler = require('vue-template-compiler');
// file can be a vinyl file object or a string
// when a string it will construct a new one
module.exports = function (file, opt) {
if (!file) {
throw new Error('vuetc-gulp: Missing file option');
}
opt = opt || {};
var indent = typeof(opt.indent) === 'number' ? ' '.repeat(opt.indent) : ' '.repeat(2);
if (typeof (opt.indent) === 'string') indent = ' '.repeat(opt.indent.length);
var pushMinify = opt.minify;
var newLine = typeof(opt.newLine) === 'string' ? opt.newLine : '\n';
var latestFile;
var latestMod;
var fileName;
var renderedTemplates = [];
if (typeof file === 'string') {
fileName = file;
} else if (typeof file.path === 'string') {
fileName = path.basename(file.path);
} else {
throw new Error('vuetc-gulp: Missing path in file options');
}
function addRenderedPart(content) {
function idAttr(el, idx, arr) {
return el.name === "id";
}
var node = compiler.parseComponent(content.toString()).template;
// ignore empty node content
if (!node) {
return;
}
var res = compiler.compile(node.content);
var staticRenderFns = res.staticRenderFns.map(function(fn) {
return 'function(){' + fn + '}';
});
renderedTemplates.push({
node_id: node.attrs['id'],
render: res.render,
staticRenderFns: '[' + staticRenderFns.join(',') + ']'
});
}
function getJoinedFile(isCompact) {
var nl = isCompact ? '' : newLine;
var tab = isCompact ? '' : indent;
var joinedFile;
var bufferParts = [];
// if file opt was a file path
// clone everything from the latest file
if (typeof file === 'string') {
joinedFile = latestFile.clone({ contents: false });
joinedFile.path = path.join(latestFile.base, file);
} else {
joinedFile = new File(file);
}
if (isCompact) {
var pathObject = path.parse(joinedFile.path);
joinedFile.path = path.format({
dir: pathObject.dir,
name: pathObject.name + '.min',
ext: pathObject.ext
});
}
bufferParts.push(Buffer.from('var RenderedTemplate = {' + nl));
renderedTemplates.forEach(function (item, i) {
var textObj = (i > 0) ? (',' + nl) : '';
textObj += tab + "'" + item.node_id + "': {" + nl
+ tab.repeat(2) + "'render': function() {" + nl
+ tab.repeat(3) + item.render + nl
+ tab.repeat(2) + "}," + nl
+ tab.repeat(2) + "'staticRenderFns': " + (item.staticRenderFns || '[]') + nl
+ tab + "}";
bufferParts.push(Buffer.from(textObj));
})
bufferParts.push(Buffer.from(nl + '};'));
joinedFile.contents = Buffer.concat(bufferParts);
return joinedFile;
}
function bufferContents(file, enc, cb) {
// ignore empty files
if (file.isNull()) {
cb();
return;
}
// we don't do streams (yet)
if (file.isStream()) {
this.emit('error', new Error('vuetc-gulp: Streaming not supported'));
cb();
return;
}
// set latest file if not already set,
// or if the current file was modified more recently.
if (!latestMod || file.stat && file.stat.mtime > latestMod) {
latestFile = file;
latestMod = file.stat && file.stat.mtime;
}
// add file to concat instance
addRenderedPart(file.contents);
cb();
}
function endStream(cb) {
// no files passed in, no file goes out
if (!latestFile || !renderedTemplates) {
cb();
return;
}
this.push(getJoinedFile(false));
if (pushMinify)
this.push(getJoinedFile(true));
cb();
}
return through.obj(bufferContents, endStream);
};
;