Skip to content

Commit a63291c

Browse files
committed
Performance improvements and es2015 transpilation with vue-template-es2015-compiler
1 parent d906c54 commit a63291c

File tree

3 files changed

+125
-136
lines changed

3 files changed

+125
-136
lines changed

packages/vue-component/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.8.1 - 2017-01-04
4+
5+
- Performance improvements and es2015 transpilation with `vue-template-es2015-compiler`.
6+
37
## 0.8.0 - 2017-01-02
48

59
- The components `name` option will be set by default depending on the filename. #99

packages/vue-component/package.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package.describe({
22
name: 'akryum:vue-component',
3-
version: '0.8.0',
3+
version: '0.8.1',
44
summary: 'VueJS single-file components that hot-reloads',
55
git: 'https://github.com/Akryum/meteor-vue-component',
66
documentation: 'README.md'
@@ -30,6 +30,7 @@ Package.registerBuildPlugin({
3030
'async': '1.4.0',
3131
'lodash': '4.13.1',
3232
'vue-template-compiler': '2.1.8',
33+
'vue-template-es2015-compiler': '1.4.2',
3334
'hash-sum': '1.0.2',
3435
'source-map': '0.5.6',
3536
'source-map-merger': '0.2.0',

packages/vue-component/plugin/vue-compiler.js

Lines changed: 119 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import async from 'async';
55
import { Meteor } from 'meteor/meteor';
66
import { EventEmitter } from 'events';
77
import _ from 'lodash';
8+
import transpile from 'vue-template-es2015-compiler';
89

910
IGNORE_FILE = '.vueignore';
1011
CWD = path.resolve('./');
@@ -168,9 +169,9 @@ VueComponentCompiler = class VueCompo extends CachingCompiler {
168169
}
169170

170171
addCompileResult(inputFile, compileResult) {
171-
let inputFilePath = inputFile.getPathInPackage();
172-
let vueId = 'data-v-' + FileHash(inputFile);;
173-
let isDev = isDevelopment();
172+
const inputFilePath = inputFile.getPathInPackage();
173+
const vueId = 'data-v-' + FileHash(inputFile);
174+
const isDev = isDevelopment();
174175

175176
// Style
176177
let css = '';
@@ -194,96 +195,11 @@ VueComponentCompiler = class VueCompo extends CachingCompiler {
194195
}
195196
}
196197

197-
let js = compileResult.code;
198-
let jsHash = Hash(js);
198+
let jsHash = Hash(compileResult.code);
199199

200200
//console.log(`js hash: ${jsHash}`);
201201

202-
js = 'var __vue_script__, __vue_template__;' + js;
203-
js += `__vue_script__ = __vue_script__ || {};`;
204-
js += `var __vue_options__ = (typeof __vue_script__ === "function" ?
205-
(__vue_script__.options || (__vue_script__.options = {}))
206-
: __vue_script__);`;
207-
208-
let templateHash;
209-
if (compileResult.template) {
210-
211-
templateHash = Hash(compileResult.template);
212-
213-
if(vueVersion === 1) {
214-
// Fix quotes
215-
compileResult.template = compileResult.template.replace(quoteReg, ''').replace(lineReg, '');
216-
js += "__vue_template__ = '" + compileResult.template + "';";
217-
218-
// Template option
219-
js += `__vue_options__.template = __vue_template__;`;
220-
} else if(vueVersion === 2) {
221-
const templateCompilationResult = templateCompiler.compile(compileResult.template);
222-
if(templateCompilationResult.errors && templateCompilationResult.errors.length !== 0) {
223-
console.error(templateCompilationResult.errors);
224-
js += `__vue_options__.render = function(){};\n`;
225-
js += `__vue_options__.staticRenderFns = [];\n`;
226-
} else {
227-
js += `__vue_options__.render = ${toFunction(templateCompilationResult.render)};\n`;
228-
js += `__vue_options__.staticRenderFns = [${templateCompilationResult.staticRenderFns.map(toFunction).join(',')}];\n`;
229-
}
230-
}
231-
232-
//console.log(`template hash: ${templateHash}`);
233-
}
234-
235-
// Scope
236-
if(vueVersion === 2) {
237-
js += `__vue_options__._scopeId = '${vueId}';`;
238-
}
239-
240-
// Package context
241-
js += `__vue_options__.packageName = '${inputFile.getPackageName()}';`;
242-
243-
// Export
244-
js += `module.export('default', exports.default = __vue_script__);`;
245-
246-
// Hot-reloading
247-
if (isDev) {
248-
js += `\nif(!window.__vue_hot__){
249-
window.__vue_hot_pending__ = window.__vue_hot_pending__ || {};
250-
window.__vue_hot_pending__['${vueId}'] = __vue_script__;
251-
} else {
252-
window.__vue_hot__.createRecord('${vueId}', __vue_script__);
253-
}`;
254-
}
255-
256-
// Auto register
257-
let ext = (isGlobalName ? '.global' : '') + '.vue';
258-
259-
let name = Plugin.path.basename(inputFilePath);
260-
name = name.substring(0, name.lastIndexOf(ext));
261-
262-
// Remove special characters
263-
name = name.replace(nonWordCharReg, match => {
264-
if (match !== '-') {
265-
return ''
266-
} else {
267-
return match
268-
}
269-
});
270-
271-
// Kebab case
272-
name = name.replace(capitalLetterReg, (match) => {
273-
return '-' + match.toLowerCase();
274-
});
275-
name = name.replace(trimDashReg, '');
276-
277-
// Auto default name
278-
js += `\n__vue_options__.name = __vue_options__.name || '${name}';`
279-
280-
let isGlobalName = globalFileNameReg.test(inputFilePath);
281-
let isOutsideImports = inputFilePath.split('/').indexOf('imports') === -1;
282-
if (isOutsideImports || isGlobalName) {
283-
// Component registration
284-
js += `\nvar _Vue = require('vue');
285-
_Vue.component(__vue_options__.name, __vue_script__);`;
286-
}
202+
const { js, templateHash } = generateJs(vueId, inputFile, compileResult)
287203

288204
// Add JS Source file
289205
inputFile.addJavaScript({
@@ -448,11 +364,10 @@ const hotCompile = Meteor.bindEnvironment(function hotCompile(filePath, inputFil
448364
}
449365

450366
// JS & Template
451-
let js, jsHash, template, templateHash;
367+
let jsHash, template, templateHash;
452368
if(parts.script || parts.template) {
453369
if(parts.script) {
454-
js = compileResult.code;
455-
jsHash = Hash(js);
370+
jsHash = Hash(compileResult.code);
456371
}
457372
if(parts.template) {
458373
template = compileResult.template;
@@ -468,55 +383,14 @@ const hotCompile = Meteor.bindEnvironment(function hotCompile(filePath, inputFil
468383

469384
const path = (inputFile.getPackageName() ? `packages/${inputFile.getPackageName()}` : '') + inputFile.getPathInPackage();
470385

471-
// Require to absolute
472-
js = js.replace(requireRelativeFileReg, `require('/${inputFilePath}/`);
473-
474-
js = 'var __vue_script__, __vue_template__;' + js;
475-
js += `__vue_script__ = __vue_script__ || {};`;
476-
js += `var __vue_options__ = (typeof __vue_script__ === "function" ?
477-
(__vue_script__.options || (__vue_script__.options = {}))
478-
: __vue_script__);`;
479-
480-
let render, staticRenderFns;
481-
482-
if (template) {
483-
if(vueVersion === 1) {
484-
// Fix quotes
485-
template = template.replace(quoteReg, ''').replace(lineReg, '');
486-
js += "__vue_template__ = '" + template + "';";
487-
488-
// Template option
489-
js += `__vue_options__.template = __vue_template__;`;
490-
} else if(vueVersion === 2) {
491-
const templateCompilationResult = templateCompiler.compile(template);
492-
if(templateCompilationResult.errors && templateCompilationResult.errors.length !== 0) {
493-
console.error(templateCompilationResult.errors);
494-
js += `__vue_options__.render = function(){};\n`;
495-
js += `__vue_options__.staticRenderFns = [];\n`;
496-
} else {
497-
js += `__vue_options__.render = ${render = toFunction(templateCompilationResult.render)};\n`;
498-
js += `__vue_options__.staticRenderFns = ${staticRenderFns = `[${templateCompilationResult.staticRenderFns.map(toFunction).join(',')}]`};\n`;
499-
}
500-
}
501-
}
386+
const { js, render, staticRenderFns } = generateJs(vueId, inputFile, compileResult, true)
502387

503388
if(vueVersion === 2 && cache.js === jsHash) {
504389
global._dev_server.emit('render', { hash: vueId, template:`{
505390
render: ${render},
506391
staticRenderFns: ${staticRenderFns}
507392
}`, path });
508393
} else {
509-
// Scope
510-
if(vueVersion === 2) {
511-
js += `__vue_options__._scopeId = '${vueId}';`;
512-
}
513-
514-
// Package context
515-
js += `__vue_options__.packageName = '${inputFile.getPackageName()}';`;
516-
517-
// Export
518-
js += `module.export('default', exports.default = __vue_script__);`;
519-
520394
global._dev_server.emit('js', { hash: vueId, js, template, path });
521395
}
522396
}
@@ -675,3 +549,113 @@ function compileOneFileWithContents(inputFile, contents, parts, babelOptions) {
675549
}
676550
}
677551
}
552+
553+
function generateJs (vueId, inputFile, compileResult, isHotReload = false) {
554+
const isDev = isDevelopment();
555+
const inputFilePath = inputFile.getPathInPackage();
556+
557+
let js = 'var __vue_script__, __vue_template__;' + compileResult.code;
558+
js += `__vue_script__ = __vue_script__ || {};`;
559+
js += `var __vue_options__ = (typeof __vue_script__ === "function" ?
560+
(__vue_script__.options || (__vue_script__.options = {}))
561+
: __vue_script__);`;
562+
563+
let render, staticRenderFns;
564+
565+
let templateHash;
566+
if (compileResult.template) {
567+
568+
if (!isHotReload) {
569+
templateHash = Hash(compileResult.template);
570+
}
571+
572+
if(vueVersion === 1) {
573+
// Fix quotes
574+
compileResult.template = compileResult.template.replace(quoteReg, ''').replace(lineReg, '');
575+
js += "__vue_template__ = '" + compileResult.template + "';";
576+
577+
// Template option
578+
js += `__vue_options__.template = __vue_template__;\n`;
579+
} else if(vueVersion === 2) {
580+
const templateCompilationResult = templateCompiler.compile(compileResult.template);
581+
if(templateCompilationResult.errors && templateCompilationResult.errors.length !== 0) {
582+
console.error(templateCompilationResult.errors);
583+
js += `__vue_options__.render = function(){};\n`;
584+
js += `__vue_options__.staticRenderFns = [];\n`;
585+
} else {
586+
render = toFunction(templateCompilationResult.render)
587+
staticRenderFns = `[${ templateCompilationResult.staticRenderFns.map(toFunction).join(',')}]`
588+
let renderJs = `__vue_options__.render = ${render};\n`;
589+
renderJs += `__vue_options__.staticRenderFns = ${staticRenderFns};\n`;
590+
renderJs = transpile(renderJs);
591+
if (isDev) {
592+
renderJs += `__vue_options__.render._withStripped = true;\n`
593+
}
594+
js += renderJs;
595+
}
596+
}
597+
598+
//console.log(`template hash: ${templateHash}`);
599+
}
600+
601+
// Scope
602+
if(vueVersion === 2) {
603+
js += `__vue_options__._scopeId = '${vueId}';`;
604+
}
605+
606+
// Package context
607+
js += `__vue_options__.packageName = '${inputFile.getPackageName()}';`;
608+
609+
// Export
610+
js += `module.export('default', exports.default = __vue_script__);`;
611+
612+
if (!isHotReload) {
613+
// Hot-reloading
614+
if (isDev) {
615+
js += `\nif(!window.__vue_hot__){
616+
window.__vue_hot_pending__ = window.__vue_hot_pending__ || {};
617+
window.__vue_hot_pending__['${vueId}'] = __vue_script__;
618+
} else {
619+
window.__vue_hot__.createRecord('${vueId}', __vue_script__);
620+
}`;
621+
}
622+
623+
// Auto register
624+
let isGlobalName = globalFileNameReg.test(inputFilePath);
625+
let ext = (isGlobalName ? '.global' : '') + '.vue';
626+
627+
let name = Plugin.path.basename(inputFilePath);
628+
name = name.substring(0, name.lastIndexOf(ext));
629+
630+
// Remove special characters
631+
name = name.replace(nonWordCharReg, match => {
632+
if (match !== '-') {
633+
return ''
634+
} else {
635+
return match
636+
}
637+
});
638+
639+
// Kebab case
640+
name = name.replace(capitalLetterReg, (match) => {
641+
return '-' + match.toLowerCase();
642+
});
643+
name = name.replace(trimDashReg, '');
644+
645+
// Auto default name
646+
js += `\n__vue_options__.name = __vue_options__.name || '${name}';`
647+
let isOutsideImports = inputFilePath.split('/').indexOf('imports') === -1;
648+
if (isOutsideImports || isGlobalName) {
649+
// Component registration
650+
js += `\nvar _Vue = require('vue');
651+
_Vue.component(__vue_options__.name, __vue_script__);`;
652+
}
653+
}
654+
655+
return {
656+
js,
657+
templateHash,
658+
render,
659+
staticRenderFns,
660+
}
661+
}

0 commit comments

Comments
 (0)