UNPKG

5.57 kBJavaScriptView Raw
1var Path = require('path');
2var required = require('required');
3var fs = require('fs-extra');
4require('colors');
5var debugMode;
6
7var crypto = require('crypto');
8
9var modules;
10var index;
11
12
13
14//same id, same file, different requirers
15//same id, different file, different requirers
16
17//same id, same file, same requirer //all the time
18
19//different id, different file, different requirers //all the time
20//different id, different file, same requirer //all the time
21
22//different id, same file, different requirers //possible but rare
23//different id, same file, same requirer //rare but possible
24
25//same id, different file, same requirer //not possible
26
27function pushSet(arr, el) {
28 arr = arr || [];
29 if (arr.indexOf(el) === -1) arr.push(el);
30 return arr;
31}
32
33function reset() {
34 modules = [];
35 index = 0;
36}
37
38function getList(module) {
39 //TODO!! modules has to be emptied for every build run of demodularify TODO!!!!
40 //TODO!! node_modules_index has to be zerod for every build run of demodularify TODO!!!!
41 var path = [];
42
43 function walk(module) {
44 if (module.core) {
45 //the id does -NOT- start with '.', '..' or '/'
46 //so doesn't clash with any relative require ids
47 //these will have to be supplied by the server!!
48 modules[module.id] = module;
49 return;
50 }
51 if (module.walked) return;
52 modules[module.filename] = module;
53 path.push(module.id);
54 module.walked = true;
55 module.index = -1;
56 module.deps.forEach(function(d) {
57 var dep_id = d.id;
58 d = modules[d.filename] || d;
59 d.requirers = pushSet(d.requirers, module.filename);
60 d.ids = pushSet(d.ids, dep_id);
61
62 walk(d);
63 if (d.index < 0) {
64 var str = "Module " + module.id + " is dependent on module " + d.id +
65 '. However, module ' + d.id + ' is also directly or indirectly dependent on module ' +
66 module.id + ".\nDependency path to this point: \n" + path.join(' relies on \n') +
67 ' relies on ' + d.id;
68 console.log(str.red);
69 }
70 });
71 module.index = index++;
72 path.pop();
73 }
74 walk(module);
75 return modules;
76}
77
78function endsWith(str, trail) {
79 return (str.substr(str.length-trail.length, str.length-1) === trail);
80};
81
82function trailWith(str, trail) {
83 return str ? (str + (!endsWith(str, trail) ? trail : '')) : undefined;
84};
85
86function resolve(www, parent, id, cb, tags, isDebug) {
87 // console.log('-------------------', www, parent);
88 debugMode = isDebug;
89 try
90 { www = Path.resolve(www);
91 parent = Path.resolve(www, parent);
92 console.log('Resolving: ' + id + ' in directory ' + parent);
93 var fileName = Path.resolve(parent, trailWith(id, '.js'));
94 try {
95 fs.statSync(fileName);
96 } catch(e) { cb(e,null);
97 return;}
98
99 required(fileName, {
100 includeSource: false,
101 ignoreMissing: function(name, parent) {
102 var out = name + ' in ' + parent;
103 console.log('Missing module:'.red.bold, out.yellow);
104 }
105 // resolve: ..
106 }, function(err, deps) {
107 if (err) throw err;
108 else {
109 var modules = getList(
110 { id: id,
111 filename: fileName,
112 deps: deps,
113 index: -1
114 }
115 );
116
117 var list = Object.keys(modules).map(function(m) {
118 m = modules[m];
119 if (m.core) {
120 m.route = '_core_modules/' + m.id;
121 }
122 else {
123 var startWithWwwPath = m.filename.indexOf(www) === 0;
124 if (!startWithWwwPath) {
125 var hash = crypto.createHash('md5').update(m.filename).digest('hex');
126 m.route = '_node_modules/' + hash + '_' + Path.basename(m.filename);
127 m.lib = true;
128 // m.route = m.filename;
129 //TODO set softlinks to filename in www/node_modules dir
130 //possibly do deduplication?
131 // console.log( 'Warning: ' + m.id + ' was found outside the www directory (' + www + ')');
132 }
133 else m.route = m.filename.slice(www.length+1);
134
135 m.deps = m.deps.map(function(d) { return d.id; });
136 }
137 // debug('module:',m);
138 delete m.id;
139 return m;
140 }).sort(function(a, b) {
141 return a.index > b.index;
142 }).map(function(m) {
143 return !tags ?
144 m :
145 // { id: m.id, route: m.route, filename: m.filename } :
146 "<script type=\"text/javascript\" src=\"" + m.route + "\"></script>";
147 });
148 // debug('Debug:\n', list);
149 cb(null, list);
150 }
151 });
152 } catch(e) {
153 cb(e, null);
154 }
155};
156
157function debug() {
158 if (debugMode) console.log.apply(console, arguments);
159}
160
161module.exports = {
162 resolve: resolve,
163 reset: reset
164
165};
166
167
168// console.log(exports.script.toString());
169
170// list('../', './test', './m3', function(err, tags) {
171// console.log();
172// console.log(tags);
173// }, true);