From 96aa2365ae7913e010a6f4fbf84b42db477c0166 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Thu, 30 Mar 2017 23:31:22 +0200 Subject: [PATCH] fix(tsc-wrapped): ensure valid path separators in metadata * Fixes that `tsc-wrapped` stores invalid path separators in the bundled metadata files. Previous errors could have been: `Cannot find module '.corecoordinationnique-selection-dispatcher'.` (See https://github.com/angular/material2/issues/3834) * Fixes failing tests on Windows. Now all tooling tests are green on Windows. Related to #15403 --- tools/@angular/tsc-wrapped/src/bundler.ts | 8 +++++--- tools/@angular/tsc-wrapped/test/bundler_spec.ts | 14 +++++++++++++- .../@angular/tsc-wrapped/test/typescript.mocks.ts | 4 +++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tools/@angular/tsc-wrapped/src/bundler.ts b/tools/@angular/tsc-wrapped/src/bundler.ts index b29db71b73..95f0bee0fa 100644 --- a/tools/@angular/tsc-wrapped/src/bundler.ts +++ b/tools/@angular/tsc-wrapped/src/bundler.ts @@ -522,12 +522,14 @@ export class CompilerHostAdapter implements MetadataBundlerHost { function resolveModule(importName: string, from: string): string { if (importName.startsWith('.') && from) { - const normalPath = path.normalize(path.join(path.dirname(from), importName)); + let normalPath = path.normalize(path.join(path.dirname(from), importName)); if (!normalPath.startsWith('.') && from.startsWith('.')) { // path.normalize() preserves leading '../' but not './'. This adds it back. - return `.${path.sep}${normalPath}`; + normalPath = `.${path.sep}${normalPath}`; } - return normalPath; + // Replace windows path delimiters with forward-slashes. Otherwise the paths are not + // TypeScript compatible when building the bundle. + return normalPath.replace(/\\/g, '/'); } return importName; } diff --git a/tools/@angular/tsc-wrapped/test/bundler_spec.ts b/tools/@angular/tsc-wrapped/test/bundler_spec.ts index cca3b433ae..90569628f4 100644 --- a/tools/@angular/tsc-wrapped/test/bundler_spec.ts +++ b/tools/@angular/tsc-wrapped/test/bundler_spec.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import * as fs from 'fs'; import * as path from 'path'; import * as ts from 'typescript'; @@ -84,6 +83,19 @@ describe('metadata bundler', () => { ]); }); + it('should not output windows paths in metadata', () => { + const host = new MockStringBundlerHost('/', { + 'index.ts': ` + export * from './exports/test'; + `, + 'exports': {'test.ts': `export class TestExport {}`} + }); + const bundler = new MetadataBundler('/index', undefined, host); + const result = bundler.getMetadataBundle(); + + expect(result.metadata.origins).toEqual({'TestExport': './exports/test'}); + }); + it('should convert re-exported to the export', () => { const host = new MockStringBundlerHost('/', { 'index.ts': ` diff --git a/tools/@angular/tsc-wrapped/test/typescript.mocks.ts b/tools/@angular/tsc-wrapped/test/typescript.mocks.ts index 57787e8730..c270cc0f8c 100644 --- a/tools/@angular/tsc-wrapped/test/typescript.mocks.ts +++ b/tools/@angular/tsc-wrapped/test/typescript.mocks.ts @@ -54,7 +54,9 @@ export class Host implements ts.LanguageServiceHost { } export function open(directory: Directory, fileName: string): Directory|string|undefined { - const names = fileName.split('/'); + // Path might be normalized by the current node environment. But it could also happen that this + // path directly comes from the compiler in POSIX format. Support both separators for development. + const names = fileName.split(/[\\/]/); let current: Directory|string = directory; if (names.length && names[0] === '') names.shift(); for (const name of names) {