From e1234681ab15095de6f662d93e1998d840ff8eea Mon Sep 17 00:00:00 2001 From: Pat Herlihy Date: Tue, 5 Sep 2017 13:14:25 -0400 Subject: [PATCH] fix(webpack): Aliased module paths now properly map to the correct aurelia-loader module id --- dist/PreserveModuleNamePlugin.js | 27 +++++++++++++++++++++++++-- src/PreserveModuleNamePlugin.ts | 30 ++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/dist/PreserveModuleNamePlugin.js b/dist/PreserveModuleNamePlugin.js index db2dad3..76c0a5a 100644 --- a/dist/PreserveModuleNamePlugin.js +++ b/dist/PreserveModuleNamePlugin.js @@ -26,7 +26,7 @@ class PreserveModuleNamePlugin { if (m.constructor.name === "ConcatenatedModule") modulesBeforeConcat.splice(i--, 1, ...m["modules"]); } - for (let module of getPreservedModules(modules)) { + for (let module of getPreservedModules(modules, alias)) { // Even though it's imported by Aurelia, it's still possible that the module // became the _root_ of a ConcatenatedModule. // We use `constructor.name` rather than `instanceof` for compat. with Webpack 2. @@ -59,7 +59,7 @@ class PreserveModuleNamePlugin { } exports.PreserveModuleNamePlugin = PreserveModuleNamePlugin; ; -function getPreservedModules(modules) { +function getPreservedModules(modules, aliases) { return new Set(modules.filter(m => { // Some modules might have [preserveModuleName] already set, see ConventionDependenciesPlugin. let value = m[exports.preserveModuleName]; @@ -73,6 +73,29 @@ function getPreservedModules(modules) { m[exports.preserveModuleName] = req; return true; } + // Since its relative, link it with the module alias if possible + const reasonRequest = r.module && r.module.rawRequest; + const moduleDependency = r.dependency && r.dependency.module; + const moduleRequest = moduleDependency && removeLoaders(moduleDependency.request); + if (req && aliases && reasonRequest && moduleRequest) { + const aliasMatches = Object.keys(aliases).filter((alias) => { + const aliasPath = aliases[alias]; + const matchPath = !!(moduleRequest.match(new RegExp(`^${aliasPath}`))); + const matchKey = !!(reasonRequest.match(new RegExp(`^${alias}`))); + // We want to match against the alias file path AND the path that is being requested + // This allows us to use relative files inside aliased files + return (matchPath && matchKey); + }); + // Invalid? + if (aliasMatches.length > 1) { + throw new Error(`Incorrect alias usage. "${reasonRequest}" is duplicated in ${aliasMatches}`); + } + else if (aliasMatches.length === 1) { + const aliasKey = aliasMatches[0]; + m[exports.preserveModuleName] = moduleRequest.replace(aliases[aliasKey], aliasKey); + return true; + } + } } return !!value; })); diff --git a/src/PreserveModuleNamePlugin.ts b/src/PreserveModuleNamePlugin.ts index 0d611b2..6191ecc 100644 --- a/src/PreserveModuleNamePlugin.ts +++ b/src/PreserveModuleNamePlugin.ts @@ -28,7 +28,7 @@ export class PreserveModuleNamePlugin { modulesBeforeConcat.splice(i--, 1, ...m["modules"]); } - for (let module of getPreservedModules(modules)) { + for (let module of getPreservedModules(modules, alias)) { // Even though it's imported by Aurelia, it's still possible that the module // became the _root_ of a ConcatenatedModule. // We use `constructor.name` rather than `instanceof` for compat. with Webpack 2. @@ -66,7 +66,7 @@ export class PreserveModuleNamePlugin { } }; -function getPreservedModules(modules: Webpack.Module[]) { +function getPreservedModules(modules: Webpack.Module[], aliases: {[key: string]: string } | null) { return new Set( modules.filter(m => { // Some modules might have [preserveModuleName] already set, see ConventionDependenciesPlugin. @@ -80,6 +80,32 @@ function getPreservedModules(modules: Webpack.Module[]) { m[preserveModuleName] = req; return true; } + + // Since its relative, link it with the module alias if possible + const reasonRequest: string | null | undefined = r.module && r.module.rawRequest; + const moduleDependency: ModuleDependency | null = r.dependency && (r.dependency.module as any); + const moduleRequest: string | null | undefined = moduleDependency && removeLoaders(moduleDependency.request); + if (req && aliases && reasonRequest && moduleRequest) { + const aliasMatches: string[] = Object.keys(aliases).filter((alias: string): boolean => { + const aliasPath = aliases[alias]; + const matchPath = !!(moduleRequest.match(new RegExp(`^${aliasPath}`))); + const matchKey = !!(reasonRequest.match(new RegExp(`^${alias}`))); + + // We want to match against the alias file path AND the path that is being requested + // This allows us to use relative files inside aliased files + return (matchPath && matchKey); + }); + + // Invalid? + if (aliasMatches.length > 1) { + throw new Error(`Incorrect alias usage. "${reasonRequest}" is duplicated in ${aliasMatches}`); + } + else if (aliasMatches.length === 1) { + const aliasKey: string = aliasMatches[0]; + m[exports.preserveModuleName] = moduleRequest.replace(aliases[aliasKey], aliasKey); + return true; + } + } } return !!value; })