/*! * rollup-plugin-vue2 v0.8.0 * (c) 2017 Thomas Ghysels * Release under the MIT License. */ 'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var rollupPluginutils = require('rollup-pluginutils'); var compiler = _interopDefault(require('vue-template-compiler')); var transpile = _interopDefault(require('vue-template-es2015-compiler')); var MagicString = _interopDefault(require('magic-string')); var path = require('path'); var fs = require('fs'); function vue2 (options) { if ( options === void 0 ) options = {}; var filter = rollupPluginutils.createFilter(options.include || '**/*.vue', options.exclude); var styles = {}; var scripts = {}; // catch Vue render functions return { name: 'vue2', resolveId: function resolveId (id) { if (id.indexOf('.vue.component.') !== -1) { return id } }, load: function load (id) { if (id.indexOf('.vue.component.') !== -1) { id = id.slice(0, id.lastIndexOf('.vue.component.') + 4); return styles[id] || '' } }, transform: function transform (code, id) { if (id.endsWith('vue.common.js') || id.endsWith('vue.runtime.common.js')) { return vueCommon(code) } if (!filter(id)) { return } code = vueTransform(code, id, scripts); // Map of every stylesheet styles[id] = code.css; return code } } } function vueCommon (code) { code = code .replace(/process\.env\.VUE_ENV/g, JSON.stringify(process.env.VUE_ENV || '')) .replace(/process\.env\.NODE_ENV/g, JSON.stringify(process.env.NODE_ENV || '')); return { code: code, map: { mappings: '' } } } function vueTransform (code, id, scripts) { var nodes = compiler.parseComponent(code); var s = new MagicString(code); var exportOffset = 0; if (nodes.script) { if (nodes.script.src) { var script = readSrc(id, nodes.script.src); exportOffset = indexOfExport(script, 0); if (exportOffset) { s.overwrite(0, exportOffset, script.slice(0, exportOffset)); s.overwrite(exportOffset, code.length, script.slice(exportOffset)); } } else { s.remove(nodes.script.end, s.original.length); s.remove(0, nodes.script.start); exportOffset = indexOfExport(s.toString(), nodes.script.start); } } // The script cannot be valid so let's overwrite it if (exportOffset < 15) { exportOffset = 16; s.overwrite(0, 16, 'export default {'); s.overwrite(16, code.length, '\nstub: 1\n}'); } // Precompile and inject Vue template if (nodes.template) { scripts[id] = injectTemplate(s, nodes.template, exportOffset, id); } // Import css as a module // Example: import "./src/App.vue.component.css" var css; if (nodes.styles) { nodes.styles.forEach(function (style) { if (style.src) { s.prepend('import ' + JSON.stringify(style.src) + '\n'); } else { var lang = style.lang || 'css'; s.prepend('import ' + JSON.stringify(id + '.component.' + lang) + '\n'); css = (css || '') + style.content; } }); } return { code: s.toString(), map: s.generateMap({ hires: true }), css: css } } function readSrc (id, src) { if (src.startsWith('./') || src.startsWith('/') || src.startsWith('../')) { src = path.resolve(id, '..', src); } else { src = require.resolve(src); } return fs.readFileSync(src, 'utf8') } function indexOfExport (code, start) { var match = /export\s+default\s+\{/.exec(code); if (match && match[0]) { return match.index + match[0].length + start } return 0 } /** * Only support for es5 modules * * @param script * @param template * @returns {string} */ function injectTemplate (s, node, offset, id) { var t = node.src ? readSrc(id, node.src) : node.content; // Compile template var compiled = compiler.compile(t); var renderFuncs = '\nrender: ' + toFunction(compiled.render) + ',' + '\nstaticRenderFns: [' + compiled.staticRenderFns.map(toFunction).join(',') + '],'; s.appendLeft(offset, renderFuncs); return renderFuncs } /** * Wrap a piece of code in a function * * @param {String} code * @return {String} */ function toFunction (code) { return transpile('(function(){' + code + '})').slice(1, -1) } module.exports = vue2;