Skip to content
This repository was archived by the owner on Dec 26, 2018. It is now read-only.

Commit b90ffef

Browse files
committed
support relative path imports for less & sass + improve less depenedncy tracking
1 parent 22ba651 commit b90ffef

File tree

12 files changed

+75
-61
lines changed

12 files changed

+75
-61
lines changed

lib/compiler.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,8 @@ compiler.compile = function (content, filePath, cb) {
9494
}
9595
})
9696
.filter(function (p) { return p }))
97-
.then(mergeParts)
98-
.catch(function (err) {
99-
console.log(err.stack)
100-
cb(err)
101-
})
97+
.then(mergeParts, cb)
98+
.catch(cb)
10299

103100
function mergeParts (parts) {
104101
var output = ''
@@ -198,7 +195,7 @@ function isScoped (node) {
198195
function processTemplate (node, filePath, id, hasScopedStyle) {
199196
var template = checkSrc(node, filePath) || serializeTemplate(node)
200197
var lang = checkLang(node)
201-
return compileAsPromise('template', template, lang)
198+
return compileAsPromise('template', template, lang, filePath)
202199
.then(function (res) {
203200
if (hasScopedStyle) {
204201
return rewriteTemplate(id, res.source)
@@ -226,7 +223,7 @@ function processTemplate (node, filePath, id, hasScopedStyle) {
226223
function processStyle (node, filePath, id) {
227224
var style = checkSrc(node, filePath) || serializer.serialize(node)
228225
var lang = checkLang(node)
229-
return compileAsPromise('style', style, lang)
226+
return compileAsPromise('style', style, lang, filePath)
230227
.then(function (res) {
231228
return rewriteStyle(id, res.source, isScoped(node))
232229
})
@@ -243,7 +240,7 @@ function processStyle (node, filePath, id) {
243240
function processScript (node, filePath) {
244241
var script = checkSrc(node, filePath) || serializer.serialize(node).trim()
245242
var lang = checkLang(node) || 'babel'
246-
return compileAsPromise('script', script, lang)
243+
return compileAsPromise('script', script, lang, filePath)
247244
}
248245

249246
/**
@@ -316,10 +313,11 @@ function serializeTemplate (node) {
316313
* @param {String} type
317314
* @param {String} source
318315
* @param {String} lang
316+
* @param {String} filePath
319317
* @return {Promise}
320318
*/
321319

322-
function compileAsPromise (type, source, lang) {
320+
function compileAsPromise (type, source, lang, filePath) {
323321
var compile = compilers[lang]
324322
if (compile) {
325323
return new Promise(function (resolve, reject) {
@@ -329,7 +327,7 @@ function compileAsPromise (type, source, lang) {
329327
source: res,
330328
type: type
331329
})
332-
}, compiler)
330+
}, compiler, filePath)
333331
})
334332
} else {
335333
return Promise.resolve({

lib/compilers/less.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,36 @@
11
var options = require('./options')
2+
var assign = require('object-assign')
3+
var path = require('path')
24

3-
module.exports = function (raw, cb) {
5+
module.exports = function (raw, cb, compiler, filePath) {
46
try {
57
var less = require('less')
68
} catch (err) {
79
return cb(err)
810
}
9-
less.render(raw, options.less || {}, function (err, res) {
11+
12+
var opts = assign({
13+
filename: path.basename(filePath)
14+
}, options.less)
15+
16+
// provide import path
17+
var dir = path.dirname(filePath)
18+
var paths = [dir, process.cwd()]
19+
opts.paths = opts.paths
20+
? opts.paths.concat(paths)
21+
: paths
22+
23+
less.render(raw, opts, function (err, res) {
24+
if (err) {
25+
return cb(err)
26+
}
1027
// Less 2.0 returns an object instead rendered string
1128
if (typeof res === 'object') {
29+
res.imports.forEach(function (file) {
30+
compiler.emit('dependency', file)
31+
})
1232
res = res.css
1333
}
14-
cb(err, res)
34+
cb(null, res)
1535
})
1636
}

lib/compilers/sass.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
var options = require('./options')
2+
var assign = require('object-assign')
3+
var path = require('path')
24

3-
module.exports = function (raw, cb, compiler) {
5+
module.exports = function (raw, cb, compiler, filePath) {
46
try {
57
var sass = require('node-sass')
68
} catch (err) {
79
return cb(err)
810
}
911

10-
var sassOptions = extend({
12+
var sassOptions = assign({
1113
data: raw,
1214
success: function (res) {
1315
if (typeof res === 'object') {
@@ -19,7 +21,13 @@ module.exports = function (raw, cb, compiler) {
1921
error: function (err) {
2022
cb(err)
2123
}
22-
}, options.sass || {})
24+
}, options.sass)
25+
26+
var dir = path.dirname(filePath)
27+
var paths = [dir, process.cwd()]
28+
sassOptions.includePaths = sassOptions.includePaths
29+
? sassOptions.includePaths.concat(paths)
30+
: paths
2331

2432
sass.render(
2533
sassOptions,
@@ -36,10 +44,3 @@ module.exports = function (raw, cb, compiler) {
3644
}
3745
)
3846
}
39-
40-
function extend (a, b) {
41-
for (var key in b) {
42-
a[key] = b[key]
43-
}
44-
return a
45-
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"hash-sum": "^1.0.2",
2929
"html-minifier": "^0.8.0",
3030
"lru-cache": "^2.7.0",
31+
"object-assign": "^4.0.1",
3132
"parse5": "^1.5.0",
3233
"postcss": "^5.0.10",
3334
"postcss-selector-parser": "^1.3.0",
@@ -45,7 +46,6 @@
4546
"jade": "^1.11.0",
4647
"less": "^2.5.1",
4748
"mocha": "^2.3.3",
48-
"myth": "^1.5.0",
4949
"node-sass": "^3.3.3",
5050
"stylus": "^0.52.4"
5151
}

test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Promise.all([
2+
new Promise(function (resolve, reject) {
3+
reject(new Error('fuck'))
4+
})
5+
])
6+
.then(function (res) {
7+
console.log(res)
8+
}, function (err) {
9+
console.log(err)
10+
}).catch(function (err) {
11+
throw err
12+
})

test/expects/myth.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/fixtures/imports/import.less

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@base: #f938ab;

test/fixtures/imports/import.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
$font-stack: Helvetica, sans-serif;
2+
$primary-color: #333;

test/fixtures/less.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<style lang="less">
2-
@base: #f938ab;
2+
@import './imports/import.less';
33
44
.box-shadow(@style, @c) when (iscolor(@c)) {
55
-webkit-box-shadow: @style @c;

test/fixtures/myth.vue

Lines changed: 0 additions & 15 deletions
This file was deleted.

test/fixtures/sass.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<style lang="sass">
2-
$font-stack: Helvetica, sans-serif;
3-
$primary-color: #333;
2+
@import './imports/import.scss';
43
54
body {
65
font: 100% $font-stack;
76
color: $primary-color;
87
}
9-
</style>
8+
</style>

test/test.js

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,20 @@ function test (name) {
4545
fileContent,
4646
path.resolve(__dirname, filePath),
4747
function (err, result) {
48-
assert(!err)
49-
try {
50-
assert.equal(result, expected)
51-
} catch (e) {
52-
console.log('expected:\n\n' + expected + '\n')
53-
console.log('result:\n\n' + result + '\n')
54-
assert(!e)
55-
}
56-
57-
if (name === 'src') {
58-
compiler.removeListener('dependency', addDep)
59-
assert.equal(deps[0], __dirname + '/fixtures/test.html')
60-
assert.equal(deps[1], __dirname + '/fixtures/test.styl')
61-
assert.equal(deps[2], __dirname + '/fixtures/src/test.js')
62-
}
63-
64-
done()
48+
// the cb is handled by a Promise, so the assertion
49+
// errors gets swallowed and the test never fails.
50+
// do it in a separate tick.
51+
setTimeout(function () {
52+
if (err) throw err
53+
assert.equal(result, expected, 'should compile correctly')
54+
if (name === 'src') {
55+
compiler.removeListener('dependency', addDep)
56+
assert.equal(deps[0], __dirname + '/fixtures/test.html')
57+
assert.equal(deps[1], __dirname + '/fixtures/test.styl')
58+
assert.equal(deps[2], __dirname + '/fixtures/src/test.js')
59+
}
60+
done()
61+
}, 0)
6562
}
6663
)
6764
})

0 commit comments

Comments
 (0)