-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathserialize.js
143 lines (127 loc) · 3.87 KB
/
serialize.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
137
138
139
140
141
142
143
var fs = require('fs');
var path = require('path');
var requireRelative = require('require-relative');
var normalizePreset = require('./normalize-preset');
var join = path.join;
var dirname = path.dirname;
var relative = path.relative;
function getModulePath(filepath) {
return filepath.replace(/(.*([\\/]node_modules|\.\.)[\\/](@[^\\/]+[\\/])?[^\\/]+)([\\/].*)?$/g, '$1')
}
// Attempt to require a module, returning false on error
function req(name) {
try {
return require(name);
} catch (err) {
return false;
}
}
// Attempt to resolve a module, returning `undefined` on error
function resolve(name, relativeTo) {
var path = false;
try {
path = requireRelative.resolve(name, relativeTo);
} catch (err) {
console.log('resolve failed for "'+name+'": '+err);
}
return path;
}
// fast npm always use symlink
// and it resulted in module duplicated
// or alias
function fillAliasMap(path, list, map) {
return list.reduce(function (symlinkedList, mod) {
var realPath = relative(path, fs.realpathSync(join(path, mod)));
if (realPath !== mod) {
symlinkedList[realPath] = (mod);
}
return symlinkedList;
}, map || {});
}
// Get a list of child module names for the given module path
function getChildren(path, type, alias) {
var modules;
try {
modules = fs.readdirSync(join(path, 'node_modules'));
} catch (err) {
path = path.replace(/([\\/]node_modules)([\\/].*)?$/g, '$1');
modules = fs.readdirSync(path);
}
var children = (modules || [])
.filter( realFile )
.sort( reverseSorter(type==='plugin' ? isPlugin : isPreset) );
fillAliasMap(path, children, alias);
return children;
}
// is a filename an actual file
function realFile(f) {
return f && f.charAt(0)!=='.';
}
// ascending sort based on the truthiness of a function
function reverseSorter(comparison) {
return function(a, b) {
var ca = comparison(a),
cb = comparison(b);
return ca===cb ? 0 : (ca ? 1 : cb ? -1 : 0);
}
}
function isPreset(name) { return name && name.match(/^babel\-preset\-/g); }
function isPlugin(name) { return name && name.match(/^babel\-plugin\-/g); }
// find the matching module *instance* in a list of module paths, remove and return it
function findAndRemove(preset, path, list) {
for (var i=list.length; i--; ) {
var p = resolve(list[i], path),
v = p && req(p);
if (v && v===preset) {
list.splice(i, 1);
return p;
}
}
}
/** Resolve & serialize a Babel preset to a filename-based representation.
* Nested filepaths are relative to `relativeTo` if specified.
* Presets referenced as Strings (uncommon) are treated as dependencies of the preset that returned them.
*/
function loadPreset(name, opts, relativeTo) {
var path = resolve(name, relativeTo),
mod = normalizePreset(path && req(path), null, opts.options);
if (!mod) throw new Error('Preset "'+name+'" not found.');
path = dirname(path);
var out = {
alias: {}
};
if (mod.presets) {
var availablePresets = getChildren(path, 'preset', out.alias);
out.presets = mod.presets.map(function(preset) {
if (typeof preset!=='string') {
preset = findAndRemove(preset, path, availablePresets);
}
return loadPreset(preset, opts, path);
});
}
if (mod.plugins) {
var availablePlugins = getChildren(path, 'plugin', out.alias);
out.plugins = mod.plugins.map(function(plugin) {
var name = Array.isArray(plugin) ? plugin[0] : plugin;
if (typeof name!=='string') {
if (name._original_name) {
// console.log('using _original_name: ', name._original_name);
name = name._original_name;
}
else {
name = findAndRemove(name, path, availablePlugins);
}
}
if (!name) return plugin;
name = resolve(name, path);
name = getModulePath(name);
if (opts) {
if (opts.cwd) name = relative(opts.cwd, name);
if (opts.transform) name = opts.transform(name);
}
return Array.isArray(plugin) ? [name].concat(plugin.slice(1)) : name;
});
}
return out;
}
module.exports = loadPreset;