UNPKG

vuetc-gulp

Version:

Vue template compiler for Gulp. Gulp-plugin for compiling and bundling VueJS templates.

145 lines (117 loc) 4.44 kB
'use strict'; 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); };