-
Notifications
You must be signed in to change notification settings - Fork 19
/
index.js
112 lines (91 loc) · 2.77 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
var resolve = require('resolve');
var copy = require('shallow-copy');
var concatMap = require('concat-map');
var path = require('path');
var parse = require('css').parse;
var fs = require('fs');
var ABS_URL = /^url\(|:\/\//;
var QUOTED = /^['"]|['"]$/g;
var RELATIVE = /^\./;
var SEPARATOR = '/';
module.exports = reworkNPM;
function reworkNPM(opts) {
opts = opts || {};
var root = opts.root || process.cwd();
var prefilter = opts.prefilter || identity;
var shim = opts.shim || {};
var alias = opts.alias || {};
function inline(scope, style) {
style.rules = concatMap(style.rules, function(rule) {
return (
(rule.type === 'import') ? getImport(scope, rule) :
(rule.rules) ? inline(copy(scope), rule) :
rule);
});
return style;
}
function getImport(scope, rule) {
var file = resolveImport(rule);
if (!file) {
return rule;
}
if (scope.indexOf(file) !== -1) {
return [];
}
scope.push(file);
var contents = fs.readFileSync(file, 'utf8');
contents = prefilter(contents, file);
contents = parse(contents, { source: path.relative(root, file) });
return inline(scope, contents.stylesheet).rules;
}
function resolveImport(rule) {
var name = rule.import.replace(QUOTED, '');
if (!isNpmImport(name)) {
return null;
}
if (!RELATIVE.test(name)) {
name = resolveAlias(name) || name;
}
var source = rule.position.source;
var dir = source ? path.dirname(path.resolve(root, source)) : root;
var file = resolve.sync(name, {
basedir: dir,
extensions: ['.css'],
packageFilter: processPackage
});
return path.normalize(file);
}
function resolveAlias(name) {
if (hasOwn(alias, name)) {
return path.resolve(root, alias[name]);
}
var segments = name.split(SEPARATOR);
if (segments.length > 1) {
var current = segments.pop();
var parent = resolveAlias(segments.join(SEPARATOR));
if (parent) {
return path.join(parent, current);
}
}
return null;
}
function processPackage(pkg) {
pkg.main =
(hasOwn(shim, pkg.name) && shim[pkg.name]) ||
pkg.style || 'index.css';
return pkg;
}
return function(style) {
return inline([], style);
};
}
function identity(value) {
return value;
}
function hasOwn(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
function isNpmImport(path) {
// Do not import absolute URLs */
return !ABS_URL.test(path);
}