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

Commit d1fb445

Browse files
authored
fix identification of link files to take into account not only the import statements but also export (#98)
1 parent a764694 commit d1fb445

File tree

14 files changed

+85
-10
lines changed

14 files changed

+85
-10
lines changed

CHANGELOG.md

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

88
## [unreleased]
99

10+
## [2.0.6-dev.1] - 2019-05-10
11+
12+
- fix identification of link files to take into account not only the `import` statements but also `export`
13+
1014
## [2.0.5] - 2019-05-01
1115

1216
- fix es6 with dynamic import to not show as missing dependencies
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import { varX } from './file-b';
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { varX } from './file-c';
2+
3+
// export { varX }; // uncomment to make the following test fail "fileA imports varX from fileB, fileB imports varX from fileC but not export it"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const varX = 4;
2+
export { varX };
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
import { isString } from '.'; // cycle with ./index.js
2-
export default function() {}
2+
export default isString;

fixtures/path-map.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"importSpecifiers": [
2828
{
2929
"isDefault": true,
30-
"name": "isString"
30+
"name": "isString",
31+
"exported": true
3132
}
3233
]
3334
},
@@ -37,7 +38,8 @@
3738
"importSpecifiers": [
3839
{
3940
"isDefault": true,
40-
"name": "isArray"
41+
"name": "isArray",
42+
"exported": true
4143
}
4244
]
4345
}
@@ -52,7 +54,8 @@
5254
"importSpecifiers": [
5355
{
5456
"isDefault": true,
55-
"name": "isString"
57+
"name": "isString",
58+
"exported": true
5659
}
5760
]
5861
}
@@ -71,7 +74,8 @@
7174
"importSpecifiers": [
7275
{
7376
"isDefault": true,
74-
"name": "isArray"
77+
"name": "isArray",
78+
"exported": true
7579
}
7680
]
7781
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bit-javascript",
3-
"version": "2.0.5",
3+
"version": "2.0.6-dev.1",
44
"scripts": {
55
"flow": "flow; test $? -eq 0 -o $? -eq 2",
66
"lint": "eslint src && flow check || true",

src/dependency-builder/build-tree.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,20 @@ describe('buildTree', () => {
129129
});
130130
});
131131
});
132+
describe('fileA imports varX from fileB, fileB imports varX from fileC but not export it', () => {
133+
let results;
134+
before(async () => {
135+
dependencyTreeParams.filePaths = [`${buildTreeFixtures}/not-link-file/file-a.js`];
136+
results = await buildTree.getDependencyTree(dependencyTreeParams);
137+
});
138+
it('should not mark fileB as a link file', () => {
139+
const fileA = 'fixtures/build-tree/not-link-file/file-a.js';
140+
expect(results.tree[fileA].files)
141+
.to.be.an('array')
142+
.with.lengthOf(1);
143+
const fileBDep = results.tree[fileA].files[0];
144+
expect(fileBDep).to.not.have.property('isLink');
145+
});
146+
});
132147
});
133148
});

src/dependency-builder/detectives/detective-es6/index.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ module.exports = function (src) {
2626
dependencies[dependency].importSpecifiers = [importSpecifier];
2727
}
2828
};
29+
const addExportedToImportSpecifier = (name) => {
30+
Object.keys(dependencies).forEach((dependency) => {
31+
if (!dependencies[dependency].importSpecifiers) return;
32+
const specifier = dependencies[dependency].importSpecifiers.find(i => i.name === name);
33+
if (specifier) specifier.exported = true;
34+
});
35+
};
2936

3037
if (typeof src === 'undefined') {
3138
throw new Error('src not given');
@@ -60,13 +67,21 @@ module.exports = function (src) {
6067
node.specifiers.forEach((specifier) => {
6168
const specifierValue = {
6269
isDefault: !specifier.local || specifier.local.name === 'default', // e.g. export { default as isArray } from './is-array';
63-
name: specifier.exported.name
70+
name: specifier.exported.name,
71+
exported: true
6472
};
6573
addImportSpecifier(dependency, specifierValue);
6674
});
6775
}
76+
} else if (node.specifiers && node.specifiers.length) {
77+
node.specifiers.forEach((exportSpecifier) => {
78+
addExportedToImportSpecifier(exportSpecifier.exported.name);
79+
});
6880
}
6981
break;
82+
case 'ExportDefaultDeclaration':
83+
addExportedToImportSpecifier(node.declaration.name);
84+
break;
7085
case 'CallExpression':
7186
if (node.callee.type === 'Import' && node.arguments.length && node.arguments[0].value) {
7287
addDependency(node.arguments[0].value);

src/dependency-builder/detectives/detective-es6/index.spec.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,21 @@ describe('detective-es6', () => {
146146
expect(deps).to.have.property('foo');
147147
expect(deps.foo).to.not.have.property('importSpecifiers');
148148
});
149+
it('should add "exported": true if the same variable has been imported and exported', () => {
150+
const deps = detective('import { foo } from "foo"; export default foo;');
151+
expect(deps).to.have.property('foo');
152+
expect(deps.foo).to.have.property('importSpecifiers');
153+
const importSpecifier = deps.foo.importSpecifiers[0];
154+
expect(importSpecifier.name).to.equal('foo');
155+
expect(importSpecifier.exported).to.be.true;
156+
});
157+
it('should not add "exported" property if the variable has been imported but not exported', () => {
158+
const deps = detective('import { foo } from "foo";');
159+
expect(deps).to.have.property('foo');
160+
expect(deps.foo).to.have.property('importSpecifiers');
161+
const importSpecifier = deps.foo.importSpecifiers[0];
162+
expect(importSpecifier.name).to.equal('foo');
163+
expect(importSpecifier).to.not.have.property('exported');
164+
});
149165
});
150166
});

src/dependency-builder/detectives/detective-stylable/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ module.exports = function (src, options = {}) {
2525
if (!stNamed) return;
2626
const specifierValue = {
2727
isDefault: false, // @todo,
28-
name: stNamed.value
28+
name: stNamed.value,
29+
exported: true
2930
};
3031
addImportSpecifier(stFromValue, specifierValue);
3132
});

src/dependency-builder/detectives/detective-typescript/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ module.exports = function (src, options = {}) {
3030
dependencies[dependency].importSpecifiers = [importSpecifier];
3131
}
3232
};
33+
const addExportedToImportSpecifier = (name) => {
34+
Object.keys(dependencies).forEach((dependency) => {
35+
const specifier = dependencies[dependency].importSpecifiers.find(i => i.name === name);
36+
if (specifier) specifier.exported = true;
37+
});
38+
};
3339

3440
if (typeof src === 'undefined') {
3541
throw new Error('src not given');
@@ -59,8 +65,15 @@ module.exports = function (src, options = {}) {
5965
case 'ExportAllDeclaration':
6066
if (node.source && node.source.value) {
6167
addDependency(node.source.value);
68+
} else if (node.specifiers && node.specifiers.length) {
69+
node.specifiers.forEach((exportSpecifier) => {
70+
addExportedToImportSpecifier(exportSpecifier.exported.name);
71+
});
6272
}
6373
break;
74+
case 'ExportDefaultDeclaration':
75+
addExportedToImportSpecifier(node.declaration.name);
76+
break;
6477
case 'TSExternalModuleReference':
6578
if (node.expression && node.expression.value) {
6679
addDependency(node.expression.value);

src/dependency-builder/path-map.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ function findTheRealDependency(
7878
visitedFiles.push(currentPathMap.file);
7979
const currentRealDep: ?PathMapDependency = currentPathMap.dependencies.find((dep) => {
8080
if (!dep.importSpecifiers) return false;
81-
return dep.importSpecifiers.find(depSpecifier => depSpecifier.name === specifier.name);
81+
return dep.importSpecifiers.find(depSpecifier => depSpecifier.name === specifier.name && depSpecifier.exported);
8282
});
8383
if (!currentRealDep) {
8484
// the currentRealDep is not the real dependency, return the last real we found

src/dependency-builder/types/dependency-tree-type.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
*/
88
export type Specifier = {
99
isDefault: boolean,
10-
name: string
10+
name: string,
11+
exported?: boolean
1112
};
1213

1314
/**

0 commit comments

Comments
 (0)