Skip to content
This repository was archived by the owner on Aug 16, 2022. It is now read-only.

Commit 79193bd

Browse files
committed
support registering custom compilers
1 parent 88156eb commit 79193bd

File tree

4 files changed

+107
-30
lines changed

4 files changed

+107
-30
lines changed

compilers/index.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// built-in compilers
2+
var compilers = module.exports = {
3+
script: {
4+
coffee: require('./coffee'),
5+
es6: require('./es6')
6+
},
7+
style: {
8+
less: require('./less'),
9+
sass: require('./sass'),
10+
scss: require('./sass'),
11+
stylus: require('./stylus'),
12+
myth: require('./myth')
13+
},
14+
template: {
15+
jade: require('./jade')
16+
}
17+
}
18+
19+
// check for config file
20+
var fs = require('fs')
21+
var path = require('path')
22+
var configPath = path.resolve(process.cwd(), 'vue.config.js')
23+
if (fs.existsSync(configPath)) {
24+
require(configPath)({
25+
register: registerCompiler
26+
})
27+
}
28+
29+
/**
30+
* Register a compiler for a given file extension.
31+
*
32+
* @param {Object} opts
33+
* - extension {String}
34+
* - type {String}
35+
* - compile {Function}
36+
*/
37+
function registerCompiler (opts) {
38+
if (!opts.extension) {
39+
return warn('missing file extension')
40+
}
41+
if (!opts.type) {
42+
return warn('missing file type')
43+
}
44+
if (!opts.compile || typeof opts.compile !== 'function') {
45+
return warn('missing compile function')
46+
}
47+
if (!compilers[opts.type]) {
48+
return warn(
49+
'invalid file type: ' + opts.type +
50+
' (valid types: script|style|template)'
51+
)
52+
}
53+
compilers[opts.type][opts.extension] = opts.compile
54+
}
55+
56+
function warn (msg) {
57+
console.warn('[vue-component-compiler] ' + msg);
58+
}

index.js

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,15 @@ var parse5 = require('parse5')
66
var parser = new parse5.Parser()
77
var serializer = new parse5.TreeSerializer()
88
var async = require('async')
9+
var compilers = require('./compilers')
910

10-
var scriptLangs = [
11-
'coffee',
12-
'es6'
13-
]
14-
15-
var styleLangs = [
16-
'less',
17-
'sass',
18-
'stylus',
19-
'myth'
20-
]
21-
22-
var templateLangs = [
23-
'jade'
24-
]
25-
11+
/**
12+
* Compile a .vue file.
13+
*
14+
* @param {String} content
15+
* @param {String} [filePath]
16+
* @param {Function} cb
17+
*/
2618
exports.compile = function (content, filePath, cb) {
2719
// path is optional
2820
if (typeof filePath === 'function') {
@@ -38,56 +30,68 @@ exports.compile = function (content, filePath, cb) {
3830
var output = ''
3931
var jobs = []
4032

33+
// parse the file into an HTML tree
4134
var fragment = parser.parseFragment(content)
35+
36+
// Walk through the top level nodes and check for their
37+
// types & languages. If there are pre-processing needed,
38+
// push it into a jobs list.
4239
fragment.childNodes.forEach(function (node) {
4340
switch (node.nodeName) {
41+
42+
// Tempalte
4443
case 'template':
4544
template = checkSrc(node, filePath) || serializeTemplate(node)
4645
var lang = checkLang(node)
47-
if (templateLangs.indexOf(lang) < 0) {
46+
var compiler = compilers.template[lang]
47+
if (!compiler) {
4848
break
4949
}
5050
jobs.push(function (cb) {
51-
require('./compilers/' + lang)(template, function (err, res) {
51+
compiler(template, function (err, res) {
5252
template = res
5353
cb(err)
5454
})
5555
})
5656
break
57+
58+
// Style
5759
case 'style':
5860
var rawStyle = checkSrc(node, filePath) || serializer.serialize(node)
5961
var lang = checkLang(node)
60-
if (lang === 'scss') {
61-
lang = 'sass'
62-
}
63-
if (styleLangs.indexOf(lang) < 0) {
62+
var compiler = compilers.style[lang]
63+
if (!compiler) {
6464
style += rawStyle
6565
break
6666
}
6767
jobs.push(function (cb) {
68-
require('./compilers/' + lang)(rawStyle, function (err, res) {
68+
compiler(rawStyle, function (err, res) {
6969
style += res
7070
cb(err)
7171
})
7272
})
7373
break
74+
75+
// Script
7476
case 'script':
7577
var rawScript = checkSrc(node, filePath) || serializer.serialize(node).trim()
7678
var lang = checkLang(node)
77-
if (scriptLangs.indexOf(lang) < 0) {
79+
var compiler = compilers.script[lang]
80+
if (!compiler) {
7881
script += (script ? '\n' : '') + rawScript
7982
break
8083
}
8184
jobs.push(function (cb) {
82-
require('./compilers/' + lang)(rawScript, function (err, res) {
85+
compiler(rawScript, function (err, res) {
8386
script += (script ? '\n' : '') + res
8487
cb(err)
8588
})
8689
})
8790
break
8891
}
8992
})
90-
93+
94+
// process all pre-processing jobs in parallel
9195
async.parallel(jobs, function (err) {
9296
if (err) return cb(err)
9397
// style
@@ -119,6 +123,12 @@ exports.compile = function (content, filePath, cb) {
119123
})
120124
}
121125

126+
/**
127+
* Check the lang attribute of a parse5 node.
128+
*
129+
* @param {Node} node
130+
* @return {String|undefined}
131+
*/
122132
function checkLang (node) {
123133
if (node.attrs) {
124134
var i = node.attrs.length
@@ -131,6 +141,15 @@ function checkLang (node) {
131141
}
132142
}
133143

144+
/**
145+
* Check src import for a node, relative to the filePath if
146+
* available. Using readFileSync for now since this is a
147+
* rare use case.
148+
*
149+
* @param {Node} node
150+
* @param {String} filePath
151+
* @return {String}
152+
*/
134153
function checkSrc (node, filePath) {
135154
var dir = path.dirname(filePath)
136155
if (node.attrs) {

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
"parse5": "^1.1.4"
2828
},
2929
"devDependencies": {
30-
"babel": "^4.4.5",
30+
"babel": "^5.0.12",
3131
"coffee-script": "^1.9.1",
3232
"jade": "^1.9.2",
33-
"less": "^2.4.0",
33+
"less": "^2.5.0",
3434
"mocha": "^2.1.0",
35-
"myth": "^1.3.0",
35+
"myth": "^1.4.0",
3636
"node-sass": "^2.0.1",
3737
"stylus": "^0.50.0"
3838
}

test/expects/multiple-scripts.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ b = x(function() {
77

88
"use strict";
99

10-
var p = function (x) {
10+
var p = function p(x) {
1111
return x || 5;
1212
};

0 commit comments

Comments
 (0)