UNPKG

fuse-box

Version:

Fuse-Box a bundler that does it right

175 lines (173 loc) • 6.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); let vueCompiler; let vueTranspiler; let typescriptTranspiler; let babelCore; let babelConfig; class VuePluginClass { constructor(options = {}) { this.options = options; this.test = /\.vue$/; } init(context) { context.allowExtension(".vue"); } transform(file) { const context = file.context; if (context.useCache) { let cached = context.cache.getStaticCache(file); if (cached) { file.isLoaded = true; if (cached.sourceMap) { file.sourceMap = cached.sourceMap; } file.analysis.skip(); file.analysis.dependencies = cached.dependencies; file.contents = cached.contents; return; } } file.loadContents(); if (!vueCompiler) { vueCompiler = require("vue-template-compiler"); vueTranspiler = require("vue-template-es2015-compiler"); } let result = vueCompiler.parseComponent(file.contents, this.options); if (result.template && result.template.type === "template") { let templateLang = (result.template.attrs) ? result.template.attrs.lang : null; return compileTemplateContent(context, templateLang, result.template.content).then(html => { var styles = extractStyle(result.styles); if (styles.some) file.addStringDependency("fuse-box-css"); file.contents = compileScript(file, this.options, context, html, result.script, styles); file.analysis.parseUsingAcorn(); file.analysis.analyze(); if (context.useCache) { context.emitJavascriptHotReload(file); context.cache.writeStaticCache(file, file.sourceMap); } return true; }).catch(err => { console.error(err); }); } } } exports.VuePluginClass = VuePluginClass; ; function extractStyle(styleList) { var rv = { scoped: '', global: '', some: false }; if (styleList) for (let s in styleList) { let style = styleList[s], content = style.content; if (style.lang) console.error('Not supported yet: vue single-file-component style languages other than CSS'); if ('style' === style.type) rv[style.scoped ? 'scoped' : 'global'] += content; } rv.some = !!(rv.global || rv.scoped); return rv; } function toFunction(code) { return vueTranspiler('function render () {' + code + '}'); } function compileTemplateContent(context, engine, content) { return new Promise((resolve, reject) => { if (!engine) { return resolve(content); } const cons = require('consolidate'); if (!cons[engine]) { return content; } cons[engine].render(content, { filename: 'base', basedir: context.homeDir, includeDir: context.homeDir }, (err, html) => { if (err) { return reject(err); } resolve(html); }); }); } function compileScript(file, options, context, html, script, styles) { let lang = script.attrs.lang; if (lang === 'babel') { return compileBabel(file, options, context, html, script, styles); } else { return compileTypeScript(file, options, context, html, script, styles); } } function compileTypeScript(file, options, context, html, script, styles) { if (!typescriptTranspiler) { typescriptTranspiler = require("typescript"); } try { const jsTranspiled = typescriptTranspiler.transpileModule(script.content, context.getTypeScriptConfig()); return reduceVueToScript(file, jsTranspiled.outputText, html, styles); } catch (err) { console.log(err); } return ''; } function compileBabel(file, options, context, html, script, styles) { if (!babelCore) { babelCore = require("babel-core"); if (options.babel !== undefined) { babelConfig = options.babel.config; } else { let babelRcPath = path.join(context.appRoot, `.babelrc`); if (fs.existsSync(babelRcPath)) { let babelRcConfig = fs.readFileSync(babelRcPath).toString(); if (babelRcConfig) babelConfig = JSON.parse(babelRcConfig); } } if (babelConfig === undefined) { babelConfig = { plugins: ['transform-es2015-modules-commonjs'] }; } } try { let jsTranspiled = babelCore.transform(script.content, babelConfig); return reduceVueToScript(file, jsTranspiled.code, html, styles); } catch (err) { console.log(err); } return ''; } function reduceVueToScript(file, jsContent, html, styles) { const compiled = vueCompiler.compile(html); var cssInclude = ''; if (styles.global) cssInclude += styles.global; if (styles.scoped) console.error('Functionality not yet supported: scoped style'); if (cssInclude) cssInclude = 'require("fuse-box-css")(' + JSON.stringify(file.info.fuseBoxPath) + ',' + JSON.stringify(cssInclude) + ');'; return `var _p = {}; var _v = function(exports){${jsContent} };${cssInclude} _p.render = ` + toFunction(compiled.render) + ` _p.staticRenderFns = [ ` + compiled.staticRenderFns.map(toFunction).join(',') + ` ]; var _e = {}; _v(_e); Object.assign(_e.default.options||_e.default, _p) module.exports = _e `; } exports.VuePlugin = (options) => { return new VuePluginClass(options); }; //# sourceMappingURL=VuePlugin.js.map