Skip to content
This repository was archived by the owner on Dec 4, 2022. It is now read-only.

Commit 809529c

Browse files
author
David First
authored
insert dependency-resolutions packages code into this repo (#49)
most of this code was forked into teambit awhile ago and was changed to the point that it'd be difficult to keep up with the original repos. the reason why we don't send PRs to the original repos is mostly that the changes needed for our purposes are fundamental and very often. the external packages (originated outside teambit) are: precinct, filing-cabinet, dependency-tree, detective-es6 and detective-typescript. the internal packages (originated from teambit) are: detective-stylable, detective-vue and vue-lookup.
1 parent 92862ec commit 809529c

File tree

12 files changed

+987
-6
lines changed

12 files changed

+987
-6
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [unreleased]
99

10+
- insert dependency-resolutions packages code into this repo.
11+
1012
## [0.10.11] - 2018-02-27
1113

12-
- support dependency detection for Vue files
14+
- support dependency detection for Vue files
1315

1416
## [0.10.10] - 2018-01-30
1517

@@ -36,7 +38,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3638
- Stylable support
3739
- improve stability and performance of resolving dependencies
3840
- change post install hook to work with symlink
39-
- bug fix - components that require dependencies with custom binding prefix were not recognized
41+
- bug fix - components that require dependencies with custom binding prefix were not recognized
4042

4143
## [0.10.6] - 2017-11-12
4244

package.json

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,40 @@
3131
],
3232
"main": "dist/index.js",
3333
"dependencies": {
34+
"app-module-path": "^2.2.0",
3435
"camelcase": "^4.0.0",
3536
"caporal": "^0.5.0",
3637
"chalk": "^1.1.3",
37-
"dependency-tree": "teambit/node-dependency-tree",
38+
"commander": "^2.14.1",
39+
"debug": "^3.1.0",
40+
"detective-amd": "^2.4.0",
41+
"detective-cjs": "^2.0.0",
42+
"detective-less": "^1.0.1",
43+
"detective-sass": "^2.0.1",
44+
"detective-scss": "^1.0.1",
45+
"detective-stylus": "^1.0.0",
46+
"enhanced-resolve": "^4.0.0",
3847
"fs-extra": "^4.0.2",
3948
"glob": "^7.1.1",
49+
"is-relative-path": "^2.0.0",
50+
"lodash.flatten": "^4.4.0",
4051
"lodash.partition": "^4.6.0",
52+
"module-definition": "^2.2.4",
53+
"module-lookup-amd": "^5.0.1",
54+
"node-source-walk": "^3.3.0",
55+
"object-assign": "^4.1.1",
4156
"ora": "^1.2.0",
4257
"parents": "^1.0.1",
4358
"ramda": "^0.22.1",
44-
"regenerator-runtime": "^0.10.5"
59+
"regenerator-runtime": "^0.10.5",
60+
"resolve": "^1.5.0",
61+
"resolve-dependency-path": "^1.0.2",
62+
"sass-lookup": "^1.1.0",
63+
"stylable": "^5.2.2",
64+
"stylus-lookup": "^1.0.2",
65+
"typescript": "^2.7.2",
66+
"typescript-eslint-parser": "^14.0.0",
67+
"vue-template-compiler": "^2.5.13"
4568
},
4669
"devDependencies": {
4770
"babel-cli": "^6.24.0",
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* this file had been forked from https://github.com/dependents/node-dependency-tree
3+
*/
4+
5+
var path = require('path');
6+
var debug = require('debug')('tree');
7+
8+
function Config(options) {
9+
this.filename = options.filename;
10+
this.directory = options.directory || options.root;
11+
this.visited = options.visited || {};
12+
this.nonExistent = options.nonExistent || [];
13+
this.isListForm = options.isListForm;
14+
this.requireConfig = options.config || options.requireConfig;
15+
this.webpackConfig = options.webpackConfig;
16+
this.detectiveConfig = options.detective || options.detectiveConfig || {};
17+
this.pathMap = options.pathMap || [];
18+
19+
this.filter = options.filter;
20+
21+
if (!this.filename) { throw new Error('filename not given'); }
22+
if (!this.directory) { throw new Error('directory not given'); }
23+
if (this.filter && typeof this.filter !== 'function') { throw new Error('filter must be a function'); }
24+
25+
debug('given filename: ' + this.filename);
26+
27+
this.filename = path.resolve(process.cwd(), this.filename);
28+
29+
debug('resolved filename: ' + this.filename);
30+
debug('visited: ', this.visited);
31+
}
32+
33+
Config.prototype.clone = function() {
34+
return new Config(this);
35+
};
36+
37+
module.exports = Config;
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/**
2+
* this file had been forked from https://github.com/dependents/node-dependency-tree
3+
*/
4+
5+
var precinct = require('../precinct');
6+
var path = require('path');
7+
var fs = require('fs');
8+
var cabinet = require('../filing-cabinet');
9+
var debug = require('debug')('tree');
10+
var Config = require('./Config');
11+
12+
/**
13+
* Recursively find all dependencies (avoiding circular) traversing the entire dependency tree
14+
* and returns a flat list of all unique, visited nodes
15+
*
16+
* @param {Object} options
17+
* @param {String} options.filename - The path of the module whose tree to traverse
18+
* @param {String} options.directory - The directory containing all JS files
19+
* @param {String} [options.requireConfig] - The path to a requirejs config
20+
* @param {String} [options.webpackConfig] - The path to a webpack config
21+
* @param {Object} [options.visited] - Cache of visited, absolutely pathed files that should not be reprocessed.
22+
* Format is a filename -> tree as list lookup table
23+
* @param {Array} [options.nonExistent] - List of partials that do not exist
24+
* @param {Boolean} [options.isListForm=false]
25+
* @return {Object}
26+
*/
27+
module.exports = function(options) {
28+
var config = new Config(options);
29+
30+
if (!fs.existsSync(config.filename)) {
31+
debug('file ' + config.filename + ' does not exist');
32+
return config.isListForm ? [] : {};
33+
}
34+
35+
var results = traverse(config);
36+
debug('traversal complete', results);
37+
38+
dedupeNonExistent(config.nonExistent);
39+
debug('deduped list of nonExistent partials: ', config.nonExistent);
40+
41+
var tree;
42+
if (config.isListForm) {
43+
debug('list form of results requested');
44+
45+
tree = removeDups(results);
46+
debug('removed dups from the resulting list');
47+
48+
} else {
49+
debug('object form of results requested');
50+
51+
tree = {};
52+
tree[config.filename] = results;
53+
}
54+
55+
debug('final tree', tree);
56+
return tree;
57+
};
58+
59+
/**
60+
* Executes a post-order depth first search on the dependency tree and returns a
61+
* list of absolute file paths. The order of files in the list will be the
62+
* proper concatenation order for bundling.
63+
*
64+
* In other words, for any file in the list, all of that file's dependencies (direct or indirect) will appear at
65+
* lower indices in the list. The root (entry point) file will therefore appear last.
66+
*
67+
* The list will not contain duplicates.
68+
*
69+
* Params are those of module.exports
70+
*/
71+
module.exports.toList = function(options) {
72+
options.isListForm = true;
73+
74+
return module.exports(options);
75+
};
76+
77+
/**
78+
* Returns the list of dependencies for the given filename
79+
*
80+
* Protected for testing
81+
*
82+
* @param {Config} config
83+
* @return {Array}
84+
*/
85+
module.exports._getDependencies = function(config) {
86+
var dependencies;
87+
var precinctOptions = config.detectiveConfig;
88+
precinctOptions.includeCore = false;
89+
90+
try {
91+
dependencies = precinct.paperwork(config.filename, precinctOptions);
92+
93+
debug('extracted ' + dependencies.length + ' dependencies: ', dependencies);
94+
95+
} catch (e) {
96+
debug('error getting dependencies: ' + e.message);
97+
debug(e.stack);
98+
return [];
99+
}
100+
101+
var resolvedDependencies = [];
102+
var pathMapDependencies = [];
103+
var pathMapFile = { file: config.filename };
104+
105+
for (var i = 0, l = dependencies.length; i < l; i++) {
106+
var dep = dependencies[i];
107+
const isVue = (!Array.isArray(dep) && dep.isScript);
108+
var result;
109+
if (!Array.isArray(dep) && dep.isScript!== undefined) { // used for vue - return array of objects
110+
result = cabinet({
111+
partial: dep.dep,
112+
filename: config.filename,
113+
directory: config.directory,
114+
ast: precinct.ast,
115+
config: config.requireConfig,
116+
webpackConfig: config.webpackConfig,
117+
isScript: dep.isScript
118+
});
119+
} else {
120+
result = cabinet({
121+
partial: dep,
122+
filename: config.filename,
123+
directory: config.directory,
124+
ast: precinct.ast,
125+
config: config.requireConfig,
126+
webpackConfig: config.webpackConfig
127+
});
128+
}
129+
if (!result) {
130+
debug('skipping an empty filepath resolution for partial: ' + dep);
131+
config.nonExistent.push(isVue? dep.dep : dep);
132+
continue;
133+
}
134+
135+
var exists = fs.existsSync(result);
136+
137+
if (!exists) {
138+
config.nonExistent.push(isVue? dep.dep : dep);
139+
debug('skipping non-empty but non-existent resolution: ' + result + ' for partial: ' + dep);
140+
continue;
141+
}
142+
var pathMap = { dep: isVue ? dep.dep : dep , resolvedDep: result};
143+
var importSpecifiersSupportedLang = ['es6', 'ts', 'stylable'];
144+
importSpecifiersSupportedLang.forEach((lang) => {
145+
if (precinctOptions[lang] && precinctOptions[lang].importSpecifiers && precinctOptions[lang].importSpecifiers[dep]) {
146+
pathMap.importSpecifiers = precinctOptions[lang].importSpecifiers[dep];
147+
}
148+
});
149+
150+
pathMapDependencies.push(pathMap);
151+
152+
resolvedDependencies.push(result);
153+
}
154+
pathMapFile.dependencies = pathMapDependencies;
155+
config.pathMap.push(pathMapFile);
156+
157+
return resolvedDependencies;
158+
};
159+
160+
/**
161+
* @param {Config} config
162+
* @return {Object|String[]}
163+
*/
164+
function traverse(config) {
165+
var subTree = config.isListForm ? [] : {};
166+
167+
debug('traversing ' + config.filename);
168+
169+
if (config.visited[config.filename]) {
170+
debug('already visited ' + config.filename);
171+
return config.visited[config.filename];
172+
}
173+
174+
var dependencies = module.exports._getDependencies(config);
175+
176+
debug('cabinet-resolved all dependencies: ', dependencies);
177+
// Prevents cycles by eagerly marking the current file as read
178+
// so that any dependent dependencies exit
179+
config.visited[config.filename] = config.isListForm ? [] : {};
180+
181+
if (config.filter) {
182+
debug('using filter function to filter out dependencies');
183+
debug('unfiltered number of dependencies: ' + dependencies.length);
184+
dependencies = dependencies.filter(function(filePath) {
185+
return config.filter(filePath, config.filename);
186+
});
187+
debug('filtered number of dependencies: ' + dependencies.length);
188+
}
189+
190+
for (var i = 0, l = dependencies.length; i < l; i++) {
191+
var d = dependencies[i];
192+
var localConfig = config.clone();
193+
localConfig.filename = d;
194+
195+
if (localConfig.isListForm) {
196+
subTree = subTree.concat(traverse(localConfig));
197+
} else {
198+
subTree[d] = traverse(localConfig);
199+
}
200+
}
201+
202+
if (config.isListForm) {
203+
// Prevents redundancy about each memoized step
204+
subTree = removeDups(subTree);
205+
subTree.push(config.filename);
206+
config.visited[config.filename] = config.visited[config.filename].concat(subTree);
207+
208+
} else {
209+
config.visited[config.filename] = subTree;
210+
}
211+
212+
return subTree;
213+
}
214+
215+
/**
216+
* Returns a list of unique items from the array
217+
*
218+
* @param {String[]} list
219+
* @return {String[]}
220+
*/
221+
function removeDups(list) {
222+
var cache = {};
223+
var unique = [];
224+
225+
list.forEach(function(item) {
226+
if (!cache[item]) {
227+
unique.push(item);
228+
cache[item] = true;
229+
}
230+
});
231+
232+
return unique;
233+
}
234+
235+
// Mutate the list input to do a dereferenced modification of the user-supplied list
236+
function dedupeNonExistent(nonExistent) {
237+
var deduped = removeDups(nonExistent);
238+
nonExistent.length = deduped.length;
239+
240+
for (var i = 0, l = deduped.length; i < l; i++) {
241+
nonExistent[i] = deduped[i];
242+
}
243+
}

0 commit comments

Comments
 (0)