-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.js
95 lines (84 loc) · 2.95 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/
var // imports
child_process = require('child_process')
fs = require('fs'),
os = require('os'),
path = require('path'),
async = require("async"),
process = require('process'),
loaderUtils = require("loader-utils")
;
module.exports = function(content) {
this.cacheable();
// css-loader will trigger the original loader for @import statements,
// so we could possibly be triggered for normal css files which sass can't handle properly
// so we just return them
if(!this.resource.match(/\.s(c|a)ss$/)) {
return content;
}
var callback = this.async();
var addDependency = this.addDependency.bind(this);
var query = loaderUtils.parseQuery(this.query);
var args = [];
if(query.compass) {
args.push('--compass');
}
if(query.outputStyle) {
args.push('--style=' + query.outputStyle);
}
if(query.includePaths) {
query.includePaths.forEach(function(path) {
args.push('--load-path=' + path);
});
}
if(query.requires) {
query.requires.forEach(function(require) {
args.push('--require=' + require);
});
}
var cwd = query.cwd ? path.resolve(process.cwd(), query.cwd) : this.context;
// we always use a sourcemap to determine the dependencies, also
// we have to use 'inline' so webpack can always determine the
// actual content of the original file for the sourcemap
args.push('--sourcemap=inline')
var buildPath = query.buildPath ? query.buildPath : path.normalize(os.tmpdir() + '/ruby-sass-loader/');
var cachePath = path.normalize(buildPath + '/sass-cache/');
var outputPath = query.outputFile ? path.normalize(buildPath + '/' + query.outputFile) : buildPath + (Math.random(0, 1000) + path.parse(this.resource).name) + '.css' ;
var outputMapPath = outputPath + '.map';
// loader-runner doesn't define the error/warning functions, hence we define some simple shims
// for test runs
var emitError = this.emitError || function(msg) { console.log("ERROR: " + msg); };
var emitWarning = this.emitWarning || function(msg) { console.log("WARNING: " + msg); };
args = args.concat(['--cache-location=' + cachePath, this.resource, outputPath]);
var sass = process.platform === "win32" ? "sass.bat" : "sass";
child_process.execFile(sass, args, {cwd: cwd}, function(err, stdout, stderr) {
if(err) {
if(stderr) {
emitError(stderr);
}
callback(err);
} else {
if(stderr) {
emitWarning(stderr);
}
fs.readFile(outputPath, 'utf8', function(err, cssData) {
/* istanbul ignore if */
if(err) {
return callback(err);
}
cssData = cssData.replace(/\/\*#\s*sourceMappingURL=.*\.css\.map\s*\*\//, '');
fs.readFile(outputMapPath, 'utf8', function(err, mapData) {
/* istanbul ignore if */
if(err) {
return callback(err);
}
// make sure webpack recompiles when an included file changes
JSON.parse(mapData).sources.map(addDependency);
callback(null, cssData, query.sourceMap ? mapData : null);
});
});
}
}.bind(this));
}