/
index.js
136 lines (105 loc) · 3.32 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import path from 'path';
import stylus from 'stylus';
import { getOptions } from 'loader-utils';
import validateOptions from 'schema-utils';
import schema from './options.json';
import createEvaluator from './evaluator';
import { getStylusOptions, readFile, normalizeSourceMap } from './utils';
import resolver from './lib/resolver';
export default async function stylusLoader(source) {
const options = getOptions(this);
validateOptions(schema, options, {
name: 'Stylus Loader',
baseDataPath: 'options',
});
const callback = this.async();
const stylusOptions = getStylusOptions(this, options);
const useSourceMap =
typeof options.sourceMap === 'boolean' ? options.sourceMap : this.sourceMap;
if (useSourceMap) {
stylusOptions.sourcemap = {
comment: false,
sourceRoot: this.rootContext,
basePath: this.rootContext,
};
}
let data = source;
if (typeof options.additionalData !== 'undefined') {
data =
typeof options.additionalData === 'function'
? `${options.additionalData(data, this)}`
: `${options.additionalData}\n${data}`;
}
const styl = stylus(data, stylusOptions);
if (typeof stylusOptions.include !== 'undefined') {
for (const included of stylusOptions.include) {
styl.include(included);
}
}
if (typeof stylusOptions.import !== 'undefined') {
for (const imported of stylusOptions.import) {
styl.import(imported);
}
}
if (stylusOptions.resolveUrl !== false) {
stylusOptions.resolveUrl = {
paths: options.paths,
nocheck: stylusOptions.resolveUrl.noCheck,
};
styl.define('url', resolver(stylusOptions.resolveUrl));
}
if (typeof stylusOptions.define !== 'undefined') {
const definitions = Array.isArray(stylusOptions.define)
? stylusOptions.define
: Object.entries(stylusOptions.define);
for (const defined of definitions) {
styl.define(...defined);
}
}
// include regular CSS on @import
if (stylusOptions.includeCSS) {
styl.set('include css', true);
}
const shouldUseWebpackImporter =
typeof options.webpackImporter === 'boolean'
? options.webpackImporter
: true;
if (shouldUseWebpackImporter) {
styl.set('Evaluator', await createEvaluator(source, stylusOptions, this));
}
// keep track of imported files (used by Stylus CLI watch mode)
// eslint-disable-next-line no-underscore-dangle
stylusOptions._imports = [];
// let stylus do its magic
styl.render(async (error, css) => {
if (error) {
if (error.filename) {
this.addDependency(path.normalize(error.filename));
}
callback(error);
return;
}
// eslint-disable-next-line no-underscore-dangle
if (stylusOptions._imports.length > 0) {
// eslint-disable-next-line no-underscore-dangle
for (const importData of stylusOptions._imports) {
this.addDependency(path.normalize(importData.path));
}
}
let map = styl.sourcemap;
if (map && useSourceMap) {
map = normalizeSourceMap(map, this.rootContext);
try {
map.sourcesContent = await Promise.all(
map.sources.map(async (file) =>
(await readFile(this.fs, file)).toString()
)
);
} catch (fsError) {
callback(fsError);
return;
}
}
callback(null, css, map);
});
}