-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
113 lines (91 loc) · 3.36 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
const fs = require('fs');
const path = require('path');
const merge = require('lodash.merge');
const reExt = /\.(css|scss|sass)$/;
const defaults = {
prev: '',
includePaths: [],
nodeModules: './node_modules'
};
function isExternal(filePath) {
return filePath.startsWith('http://') || filePath.startsWith('https://') || filePath.startsWith('//') || filePath.startsWith('\\\\') || filePath.startsWith('url(');
}
function _resolve( options ) {
const opts = merge( {}, defaults, options );
const {
file,
prev,
nodeModules
} = opts;
let { includePaths } = opts;
let candidte;
let cwd = path.extname(prev) ? path.dirname(prev) : prev;
let meta = path.parse(file);
let matches = new Set();
// Skip external stylesheets
if (isExternal(file)) {
return [ file ];
}
// Absolute path
if (path.isAbsolute(file)) {
cwd = '';
includePaths = [];
}
// node_modules import
if (file.startsWith('~')) {
meta = path.parse(file.slice(1));
cwd = path.resolve(nodeModules);
includePaths = [];
}
// Import from parent
if (file.startsWith('.')) {
includePaths = [];
}
// Only unique paths
includePaths = new Set([ cwd, ...includePaths ]);
includePaths.forEach(( dir ) => {
candidte = path.resolve(dir, path.format(meta));
// Has extension
if ( reExt.test(candidte) ) {
matches.add(candidte);
} else {
// No extension
if (meta.base.startsWith('_')) {
matches.add(path.resolve(dir, meta.dir, `${meta.base}.css`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}.scss`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}.sass`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}/index.scss`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}/index.sass`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}/_index.scss`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}/_index.sass`));
} else {
matches.add(path.resolve(dir, meta.dir, `${meta.base}.css`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}.scss`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}.sass`));
matches.add(path.resolve(dir, meta.dir, `_${meta.base}.scss`));
matches.add(path.resolve(dir, meta.dir, `_${meta.base}.sass`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}/index.scss`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}/index.sass`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}/_index.scss`));
matches.add(path.resolve(dir, meta.dir, `${meta.base}/_index.sass`));
}
}
});
return [ ...matches ];
}
function resolve( options ) {
let file = options.file;
let resolved = _resolve(options);
let existing = [];
if (resolved.length && isExternal(resolved[0])) {
return file;
}
resolved.forEach((candidate) => {
if (fs.existsSync(candidate)) {
existing.push(candidate);
}
});
return existing[0] || file;
}
module.exports.resolve = resolve;
module.exports._resolve = _resolve;