diff --git a/e2e/schematics/tslint.test.ts b/e2e/schematics/tslint.test.ts index 34fdd2fbbf246..2b6b5c60a3f10 100644 --- a/e2e/schematics/tslint.test.ts +++ b/e2e/schematics/tslint.test.ts @@ -23,7 +23,7 @@ describe('Lint', () => { ); const out = runCLI('lint --type-check', { silenceError: true }); - expect(out).toContain('relative imports of libraries are forbidden'); + expect(out).toContain('library imports must start with @nrwl/'); expect(out).toContain('import of lazy-loaded libraries are forbidden'); expect(out).toContain('deep imports into libraries are forbidden'); }, diff --git a/packages/schematics/src/tslint/nxEnforceModuleBoundariesRule.spec.ts b/packages/schematics/src/tslint/nxEnforceModuleBoundariesRule.spec.ts index 4bff2555fe91c..2670c53620da5 100644 --- a/packages/schematics/src/tslint/nxEnforceModuleBoundariesRule.spec.ts +++ b/packages/schematics/src/tslint/nxEnforceModuleBoundariesRule.spec.ts @@ -21,7 +21,14 @@ describe('Enforce Module Boundaries', () => { const failures = runRule({}, `import '../../../libs/mylib';`); expect(failures.length).toEqual(1); - expect(failures[0].getFailure()).toEqual('relative imports of libraries are forbidden'); + expect(failures[0].getFailure()).toEqual('library imports must start with @mycompany/'); + }); + + it('should error on absolute imports into libraries without using the npm scope', () => { + const failures = runRule({}, `import 'libs/mylib';`); + + expect(failures.length).toEqual(1); + expect(failures[0].getFailure()).toEqual('library imports must start with @mycompany/'); }); it('should error about deep imports into libraries', () => { diff --git a/packages/schematics/src/tslint/nxEnforceModuleBoundariesRule.ts b/packages/schematics/src/tslint/nxEnforceModuleBoundariesRule.ts index dffe5ccbaa20b..feb8ce135293e 100644 --- a/packages/schematics/src/tslint/nxEnforceModuleBoundariesRule.ts +++ b/packages/schematics/src/tslint/nxEnforceModuleBoundariesRule.ts @@ -58,8 +58,8 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker { return; } - if (this.isRelative(imp) && this.isRelativeImportIntoAnotherProject(imp)) { - this.addFailureAt(node.getStart(), node.getWidth(), 'relative imports of libraries are forbidden'); + if (this.isRelativeImportIntoAnotherProject(imp) || this.isAbsoluteImportIntoAnotherProject(imp)) { + this.addFailureAt(node.getStart(), node.getWidth(), `library imports must start with @${this.npmScope}/`); return; } @@ -73,6 +73,7 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker { } private isRelativeImportIntoAnotherProject(imp: string): boolean { + if (!this.isRelative(imp)) return false; const sourceFile = this.getSourceFile().fileName.substring(this.projectPath.length); const targetFile = path.resolve(path.dirname(sourceFile), imp); if (this.workspacePath(sourceFile) && this.workspacePath(targetFile)) { @@ -83,6 +84,10 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker { return false; } + private isAbsoluteImportIntoAnotherProject(imp: string): boolean { + return imp.startsWith('libs/') || (imp.startsWith('/libs/') && imp.startsWith('apps/')) || imp.startsWith('/apps/'); + } + private workspacePath(s: string): boolean { return s.startsWith('/apps/') || s.startsWith('/libs/'); }