-
Notifications
You must be signed in to change notification settings - Fork 1
/
slim.js
117 lines (96 loc) · 3.21 KB
/
slim.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
module.exports = function(stealRequire) {
var conditionalRegEx = /#\{[^\}]+\}|#\?.+$/;
var superResolve = stealRequire.resolve;
stealRequire.resolve = function(id, config) {
return isConditional(id)
? resolveFinalModuleId(id, config)
: superResolve(id, config);
};
function resolveFinalModuleId(id, config) {
return new Promise(function(resolve, reject) {
var finalModuleId = getFinalModuleId(id, config);
if (finalModuleId === "@empty") {
resolve("@empty");
} else {
var slimModuleId = config.map[getFinalModuleId(id, config)];
if (typeof slimModuleId === "undefined") {
reject(new Error("Cannot find module: " + finalModuleId));
}
return stealRequire
.dynamic(slimModuleId)
.then(function() {
resolve(slimModuleId);
})
.catch(reject);
}
});
}
function isConditional(identifier) {
return Boolean(getConditionParts(identifier).length);
}
function getConditionParts(identifier) {
return identifier.match(conditionalRegEx);
}
function readMemberExpression(p, value) {
var parts = p.split(".");
while (parts.length) {
value = value[parts.shift()];
}
return value;
}
function getFinalModuleId(condition, config) {
var moduleId = condition;
var conditionalMatch =
typeof moduleId === "string" ? getConditionParts(moduleId) : null;
if (conditionalMatch) {
var substitution = conditionalMatch[0][1] !== "?";
var conditionModule = substitution
? conditionalMatch[0].substr(2, conditionalMatch[0].length - 3)
: conditionalMatch[0].substr(2);
var conditionExport = "default";
/**
* Get the index where the member expression is located (if any)
*
* The conditionModule can look like any of the examples below:
*
* ./foo/bar.needsPolyfill
* ../foo/bar.needsPolyfill
* bar.needsPolyfill
*
* 1) split './' or '../' in relative names
* 2) get the index of the member expression "." from the last index
* of the relative paths if any.
*/
var conditionExportParts = conditionModule.match(/^(?:\.\/|\.\.\/)+/);
var conditionExportIndex = conditionModule.indexOf(
".",
conditionExportParts && conditionExportParts[0].length
);
if (conditionExportIndex !== -1) {
conditionExport = conditionModule.substr(conditionExportIndex + 1);
conditionModule = conditionModule.substr(0, conditionExportIndex);
}
var booleanNegation = !substitution && conditionModule[0] === "~";
if (booleanNegation) {
conditionModule = conditionModule.substr(1);
}
// need to turn conditionModule into a numeric id somehow.
var actualConditionModule = stealRequire(config.map[conditionModule]);
var conditionValue =
typeof actualConditionModule === "object"
? readMemberExpression(conditionExport, actualConditionModule)
: actualConditionModule;
if (substitution) {
moduleId = moduleId.replace(conditionalRegEx, conditionValue);
} else {
if (booleanNegation) {
conditionValue = !conditionValue;
}
moduleId = conditionValue
? moduleId.replace(conditionalRegEx, "")
: "@empty";
}
}
return moduleId;
}
};