diff --git a/CHANGELOG.md b/CHANGELOG.md index f4ecd203ad8d..b072cc277546 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [unreleased] - [#1779](https://github.com/teambit/bit/issues/1779) update bit-javascript to prioritize custom-resolve settings +- avoid generating duplicate `require` statements within dependency links files of ES6 +- generate an index.d.ts file for node_modules links generated for custom-resolve-modules of typescript components - [#1808](https://github.com/teambit/bit/issues/1808) support adding dist-path-template as a package-json value, which gets replaced with the calculated dist path upon import - update execa to v2.0.3 - [#1792](https://github.com/teambit/bit/issues/1792) don't generate entry-point files for nested dependencies when their `package.json` is written diff --git a/e2e/flows/es6.e2e.3.js b/e2e/flows/es6.e2e.3.js new file mode 100644 index 000000000000..66f060a75e35 --- /dev/null +++ b/e2e/flows/es6.e2e.3.js @@ -0,0 +1,30 @@ +import { expect } from 'chai'; +import Helper from '../e2e-helper'; + +describe('es6 components', function () { + this.timeout(0); + const helper = new Helper(); + after(() => { + helper.destroyEnv(); + }); + describe('component that requires multiple variables from another component', () => { + before(() => { + helper.setNewLocalAndRemoteScopes(); + helper.createFile('utils', 'index.js', 'export function isType() {}; export function isString() {};'); + helper.createFile('bar', 'foo.js', 'import { isType, isString } from "../utils";'); + helper.addComponent('utils/index.js'); + helper.addComponentBarFoo(); + helper.tagAllComponents(); + helper.exportAllComponents(); + helper.reInitLocalScope(); + helper.addRemoteScope(); + helper.importComponent('bar/foo'); + }); + it('the generated dependency link should not have duplicates', () => { + const dependencyLink = helper.readFile('components/bar/foo/utils/index.js'); + const requireStatement = `require('@bit/${helper.remoteScope}.index');`; + const numOfOccurrences = dependencyLink.split(requireStatement).length - 1; + expect(numOfOccurrences).to.equal(1); + }); + }); +}); diff --git a/e2e/typescript/typescript.e2e.3.js b/e2e/typescript/typescript.e2e.3.js index b86593bbe25a..6ce57c04a89f 100644 --- a/e2e/typescript/typescript.e2e.3.js +++ b/e2e/typescript/typescript.e2e.3.js @@ -381,6 +381,13 @@ export class List extends React.Component { const result = helper.runCmd('node app.js'); expect(result.trim()).to.equal('got is-type and got is-string and got foo'); }); + it('should create index.d.ts file along with the index.js file inside the node_modules/custom-resolve', () => { + const expectedPath = path.join( + helper.localScopePath, + 'components/bar/foo/node_modules/@/utils/is-string/index.d.ts' + ); + expect(expectedPath).to.be.a.file(); + }); }); describe('using bundler compiler that generates a dist file with a different name than the source', () => { before(() => { diff --git a/src/links/dependency-file-link-generator.js b/src/links/dependency-file-link-generator.js index 273c638c8a78..4539e3ff848e 100644 --- a/src/links/dependency-file-link-generator.js +++ b/src/links/dependency-file-link-generator.js @@ -139,6 +139,20 @@ export default class DependencyFileLinkGenerator { this.linkFiles.push(linkFileInNodeModules); } + if (getExt(this.relativePathInDependency) === 'ts') { + // this is needed for when building Angular components inside a capsule, so we don't care + // about the case when dist is outside the components + const linkFileTs = this.prepareLinkFile({ + linkPath: this.getLinkPathForCustomResolve(relativeDistExtInDependency).replace('.js', '.d.ts'), + relativePathInDependency: relativePathInDependency.replace('.js', '.ts'), + depRootDir: isCustomResolvedWithDistInside ? depRootDirDist : depRootDir + }); + if (this.createNpmLinkFiles && linkFile.linkContent) { + linkFileTs.postInstallLink = true; + } + this.linkFiles.push(linkFileTs); + } + return this.linkFiles; } diff --git a/src/links/link-content.js b/src/links/link-content.js index 54ac74e4c5b0..e1fef4fefde6 100644 --- a/src/links/link-content.js +++ b/src/links/link-content.js @@ -1,5 +1,6 @@ // @flow import normalize from 'normalize-path'; +import R from 'ramda'; import fileTypesPlugins from '../plugins/file-types-plugins'; import { getWithoutExt, getExt } from '../utils'; import logger from '../logger/logger'; @@ -147,8 +148,8 @@ function tsTemplateWithImportSpecifiers(importSpecifiers) { } function es6TemplateWithImportSpecifiers(importSpecifiers) { - return importSpecifiers - .map((importSpecifier) => { + return R.uniq( + importSpecifiers.map((importSpecifier) => { if (!importSpecifier.linkFile) { // when no link-file is involved, use the standard non-es6 syntax (a privilege that doesn't exist for TS) return LINKS_CONTENT_TEMPLATES.js; @@ -169,5 +170,5 @@ function es6TemplateWithImportSpecifiers(importSpecifiers) { : `${linkVariable}.${importSpecifier.mainFile.name}`; return `${linkRequire}\n${exportPart} = ${pathPart};`; }) - .join('\n'); + ).join('\n'); }