From ee1a92c7f54b1fa2f26bc73632641c8d4d0b726d Mon Sep 17 00:00:00 2001 From: Hans Larsen <hans@hansl.ca> Date: Tue, 22 Aug 2017 13:18:41 -0700 Subject: [PATCH] fix(@ngtools/webpack): fix paths mapping recursive support Some path mappings (see issue) were not resolving properly when they were used in deep paths. Fixes #7341 --- packages/@ngtools/webpack/src/paths-plugin.ts | 38 +++++++++++-------- tests/e2e/tests/build/ts-paths.ts | 19 +++++++--- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/packages/@ngtools/webpack/src/paths-plugin.ts b/packages/@ngtools/webpack/src/paths-plugin.ts index 290ca1082f2b..0c5d16da62c0 100644 --- a/packages/@ngtools/webpack/src/paths-plugin.ts +++ b/packages/@ngtools/webpack/src/paths-plugin.ts @@ -122,29 +122,37 @@ export class PathsPlugin implements Tapable { this._nmf.plugin('before-resolve', (request: NormalModuleFactoryRequest, callback: Callback<any>) => { + // Only work on TypeScript issuers. + if (!request.contextInfo.issuer || !request.contextInfo.issuer.endsWith('.ts')) { + return callback(null, request); + } + for (let mapping of this._mappings) { const match = request.request.match(mapping.aliasPattern); if (!match) { continue; } - let newRequestStr = mapping.target; if (!mapping.onlyModule) { newRequestStr = newRequestStr.replace('*', match[1]); } - - const moduleResolver: ts.ResolvedModuleWithFailedLookupLocations = - ts.nodeModuleNameResolver( - newRequestStr, - this._absoluteBaseUrl, - this._compilerOptions, - this._host - ); - const moduleFilePath = moduleResolver.resolvedModule ? - moduleResolver.resolvedModule.resolvedFileName : ''; - + const moduleResolver = ts.resolveModuleName( + request.request, + request.contextInfo.issuer, + this._compilerOptions, + this._host + ); + let moduleFilePath = moduleResolver.resolvedModule + && moduleResolver.resolvedModule.resolvedFileName; + + // If TypeScript gives us a .d.ts it's probably a node module and we need to let webpack + // do the resolution. + if (moduleFilePath && moduleFilePath.endsWith('.d.ts')) { + moduleFilePath = moduleFilePath.replace(/\.d\.ts$/, '.js'); + if (!this._host.fileExists(moduleFilePath)) { + continue; + } + } if (moduleFilePath) { - return callback(null, Object.assign({}, request, { - request: moduleFilePath.includes('.d.ts') ? newRequestStr : moduleFilePath - })); + return callback(null, Object.assign({}, request, { request: moduleFilePath })); } } diff --git a/tests/e2e/tests/build/ts-paths.ts b/tests/e2e/tests/build/ts-paths.ts index 691fb87e41c0..4978528c0795 100644 --- a/tests/e2e/tests/build/ts-paths.ts +++ b/tests/e2e/tests/build/ts-paths.ts @@ -1,12 +1,12 @@ import {updateTsConfig} from '../../utils/project'; -import {writeMultipleFiles, appendToFile, createDir} from '../../utils/fs'; +import {writeMultipleFiles, appendToFile, createDir, replaceInFile} from '../../utils/fs'; import {ng} from '../../utils/process'; import {stripIndents} from 'common-tags'; export default function() { return updateTsConfig(json => { - json['compilerOptions']['baseUrl'] = '.'; + json['compilerOptions']['baseUrl'] = './'; json['compilerOptions']['paths'] = { '@shared': [ 'app/shared' @@ -14,9 +14,8 @@ export default function() { '@shared/*': [ 'app/shared/*' ], - '*': [ - '*', - 'app/shared/*' + '@root/*': [ + './*' ] }; }) @@ -24,7 +23,15 @@ export default function() { .then(() => writeMultipleFiles({ 'src/meaning-too.ts': 'export var meaning = 42;', 'src/app/shared/meaning.ts': 'export var meaning = 42;', - 'src/app/shared/index.ts': `export * from './meaning'` + 'src/app/shared/index.ts': `export * from './meaning'`, + })) + .then(() => replaceInFile('src/app/app.module.ts', './app.component', '@root/app/app.component')) + .then(() => ng('build')) + .then(() => updateTsConfig(json => { + json['compilerOptions']['paths']['*'] = [ + '*', + 'app/shared/*' + ]; })) .then(() => appendToFile('src/app/app.component.ts', stripIndents` import { meaning } from 'app/shared/meaning';