Skip to content

Commit

Permalink
fix(webpack): pull-request comment updates
Browse files Browse the repository at this point in the history
  • Loading branch information
jsleuth authored and pat841 committed Oct 16, 2018
1 parent 1263657 commit 5426b42
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 60 deletions.
4 changes: 2 additions & 2 deletions src/AureliaDependenciesPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class AureliaDependency extends IncludeDependency {
class Template {
apply(dep: AureliaDependency, source: Webpack.Source) {
// Get the module id, fallback to using the module request
let moduleId: string = dep.request;
if (dep.module && typeof dep.module[preserveModuleName] === 'string') {
let moduleId = dep.request;
if (dep.module && typeof dep.module[preserveModuleName] === "string") {
moduleId = dep.module[preserveModuleName];
}

Expand Down
106 changes: 49 additions & 57 deletions src/PreserveModuleNamePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* - The path to the module itself: /home/usr/pkg/node_modules
* - The module name: mod
* - The relative path: dir/file.js
* - Map the parsed path data to _nodeModuleResourcesMap by the parsed module name and its resource location
* - Map the parsed path data to nodeModuleResourcesMap by the parsed module name and its resource location
* - Example Map:
* {
* 'aurelia-templating-router': {
Expand Down Expand Up @@ -52,7 +52,7 @@
* - If there are multiple entry points:
* - Pick the most shallow resource
* - If they are both as shallow as possible choose index over module name match
* - Map the normalized module id to _nodeModuleResourceIdMap by the resource file
* - Map the normalized module id to nodeModuleResourceIdMap by the resource file
* - Example Map:
* {
* '/home/usr/pkg/node_modules/aurelia-templating-router/dist/native-modules/router-view.js': 'aurelia-templating-router/router-view.js',
Expand Down Expand Up @@ -92,8 +92,8 @@ import path = require("path");
export const preserveModuleName = Symbol();

// node_module maps
const _nodeModuleResourcesMap: NodeModule.ResourcesMap = {};
const _nodeModuleResourceIdMap: NodeModule.ResourceIdMap = {};
const nodeModuleResourcesMap: NodeModule.ResourcesMap = {};
const nodeModuleResourceIdMap: NodeModule.ResourceIdMap = {};

const TAP_NAME = "Aurelia:PreserveModuleName";

Expand Down Expand Up @@ -124,7 +124,7 @@ export class PreserveModuleNamePlugin {
}

// Map and parse the modules if needed
modulesBeforeConcat.forEach((m) => mapNodeModule(m));
modulesBeforeConcat.forEach(mapNodeModule);
parseNodeModules();

for (let module of getPreservedModules(modules)) {
Expand All @@ -137,8 +137,6 @@ export class PreserveModuleNamePlugin {

// Get the module id
let id = getModuleId(realModule, roots, alias);
if (!id)
throw new Error(`Can't figure out a normalized module name for ${realModule.rawRequest}, please call PLATFORM.moduleName() somewhere to help.`);

// Remove default extensions
normalizers.forEach(n => id = id!.replace(n, ""));
Expand All @@ -147,6 +145,7 @@ export class PreserveModuleNamePlugin {
if (/^async[?!]/.test(realModule.rawRequest))
id = "async!" + id;

id = id.replace(/\\/g, "/");
if (module.buildMeta) // meta can be null if the module contains errors
module.buildMeta["aurelia-id"] = id;
if (!this.isDll) {
Expand All @@ -168,21 +167,13 @@ function getPreservedModules(modules: Webpack.Module[]) {
}

// Preserve the module if its dependencies are also preserved
const reasons = (m.reasons && Array.isArray(m.reasons)) ? m.reasons : [];
return reasons.some((reason) => Boolean(reason.dependency && reason.dependency[preserveModuleName]));
return m.reasons.some(reason => (reason.dependency && reason.dependency[preserveModuleName]));
})
);
}

/**
* Check if a module exists in node_modules/
*
* @param {Webpack.Module} module The module to check
*
* @return {Boolean} True if it exists in node_modules/, false otherwise
*/
function isNodeModule(module: Webpack.Module): boolean {
return !(!module || !module.resource || !(/\bnode_modules\b/i.test(module.resource)));
function isNodeModule(module: Webpack.Module) {
return (module.resource && /\bnode_modules\b/i.test(module.resource));
}

/**
Expand Down Expand Up @@ -234,10 +225,10 @@ function mapNodeModule(module: Webpack.Module) {
}

// Map it
if (!_nodeModuleResourcesMap[moduleData.name]) {
_nodeModuleResourcesMap[moduleData.name] = {};
if (!nodeModuleResourcesMap[moduleData.name]) {
nodeModuleResourcesMap[moduleData.name] = {};
}
_nodeModuleResourcesMap[moduleData.name][module.resource] = moduleData;
nodeModuleResourcesMap[moduleData.name][module.resource] = moduleData;
}

/**
Expand Down Expand Up @@ -266,13 +257,13 @@ function mapNodeModule(module: Webpack.Module) {
* @return {undefined}
*/
function parseNodeModules() {
if (!_nodeModuleResourcesMap || !Object.keys(_nodeModuleResourcesMap).length) {
if (!nodeModuleResourcesMap || !Object.keys(nodeModuleResourcesMap).length) {
return;
}

// Parse each module
for (const moduleKey in _nodeModuleResourcesMap) {
const moduleResources: NodeModule.ModuleResource = _nodeModuleResourcesMap[moduleKey];
for (const moduleKey in nodeModuleResourcesMap) {
const moduleResources: NodeModule.ModuleResource = nodeModuleResourcesMap[moduleKey];

// Keep track of the common resource path and possible module entry points
let commonPathParts: string[] = [];
Expand All @@ -281,15 +272,15 @@ function parseNodeModules() {
// Parse each resource in the module
for (const resource in moduleResources) {
const data: NodeModule.Data = moduleResources[resource];
const pathParts: string[] = data.relative.split('/');
const pathParts = data.relative.split("/");
const resourceFile: string | null = pathParts.splice(-1)[0];
if (!resourceFile) {
continue;
}

// Entry?
const resourceName: string = resourceFile.replace(/\..*/, '');
if (resourceName === moduleKey || resourceName === 'index') {
const resourceName = resourceFile.replace(/\..*/, "");
if (resourceName === moduleKey || resourceName === "index") {
possibleEntryPoints.push(resource);
}

Expand All @@ -314,12 +305,12 @@ function parseNodeModules() {
}

// Convert common path to string
let commonPath: string = commonPathParts.join('/');
commonPath = (commonPath.startsWith('/')) ? commonPath : `/${commonPath}`;
let commonPath = commonPathParts.join("/");
commonPath = (commonPath.startsWith("/")) ? commonPath : `/${commonPath}`;

// If there is more than one possible entry point, use the most shallow resource
let moduleEntry: string | null = null;
possibleEntryPoints.forEach((resource: string) => {
possibleEntryPoints.forEach((resource) => {
const data: NodeModule.Data = moduleResources[resource];

// No entry yet?
Expand All @@ -328,7 +319,7 @@ function parseNodeModules() {
}

// Shallow?
else if (moduleEntry.split('/').length > data.relative.split('/').length) {
else if (moduleEntry.split("/").length > data.relative.split("/").length) {
moduleEntry = data.relative;
}

Expand All @@ -340,25 +331,25 @@ function parseNodeModules() {
});

// If an entry point still hasnt been found and there is only one resource, use that
const resourceKeys: string[] = Object.keys(moduleResources);
const resourceKeys = Object.keys(moduleResources);
if (!moduleEntry && resourceKeys.length === 1) {
moduleEntry = moduleResources[resourceKeys[0]].relative;
}

// Map the resources to the module id
resourceKeys.forEach((resource: string) => {
resourceKeys.forEach((resource) => {
const data: NodeModule.Data = moduleResources[resource];

// Entry?
if (moduleEntry === data.relative) {
_nodeModuleResourceIdMap[resource] = moduleKey;
nodeModuleResourceIdMap[resource] = moduleKey;
return;
}

// Build the id from the resources common path
let key: string = data.relative.replace(new RegExp(`^${escapeString(commonPath)}`), '');
key = (key.startsWith('/')) ? key : `/${key}`;
_nodeModuleResourceIdMap[resource] = `${moduleKey}${key}`;
let key = data.relative.replace(new RegExp(`^${escapeString(commonPath)}`), "");
key = (key.startsWith("/")) ? key : `/${key}`;
nodeModuleResourceIdMap[resource] = `${moduleKey}${key}`;
});
}
}
Expand All @@ -373,14 +364,14 @@ function parseNodeModules() {
* @return {string|null} The relative path if available, null otherwise
*/
function getRelativeModule(module: Webpack.Module, paths: string[]): string | null {
if (!module || !module.resource || !paths || !paths.length) {
if (!module.resource || !paths || !paths.length) {
return null;
}

// Try to find the module in the resolver paths
for (let i = 0, len = paths.length; i < len; i++) {
const relative: string = path.relative(paths[i], module.resource);
if (!relative.startsWith('..')) {
const relative = path.relative(paths[i], module.resource);
if (!relative.startsWith("..")) {
return relative;
}
}
Expand All @@ -398,19 +389,19 @@ function getRelativeModule(module: Webpack.Module, paths: string[]): string | nu
* @return {string|null} The alias path if available, null otherwise
*/
function getAliasModule(module: Webpack.Module, aliases: { [key: string]: string } | null): string | null {
if (!module || !module.resource || !aliases || !Object.keys(aliases).length) {
if (!module.resource || !aliases || !Object.keys(aliases).length) {
return null;
}

// Look for the module in each alias
for (let alias in aliases) {
const relative: string = path.relative(path.resolve(aliases[alias]), module.resource);
if (relative.startsWith('..')) {
const relative = path.relative(path.resolve(aliases[alias]), module.resource);
if (relative.startsWith("..")) {
continue;
}

// Absolute alias?
alias = alias.replace(/\$$/, '');
alias = alias.replace(/\$$/, "");
return (relative && relative.length) ? `${alias}/${relative}` : alias;
}

Expand All @@ -425,13 +416,9 @@ function getAliasModule(module: Webpack.Module, aliases: { [key: string]: string
* @param {string[]} paths The webpack resolver module paths
* @param {[{ [key: string]: string }|null} aliases The webpack aliases
*
* @return {string|null} The module id if available, null otherwise
* @return {string} The module id
*/
function getModuleId(module: Webpack.Module, paths: string[], aliases: { [key: string]: string } | null): string | null {
if (!module) {
return null;
}

function getModuleId(module: Webpack.Module, paths: string[], aliases: { [key: string]: string } | null): string {
// Handling module ids can be a bit tricky
// Modules can be included in any of the following ways:
// import { Module } from 'module'
Expand All @@ -456,14 +443,23 @@ function getModuleId(module: Webpack.Module, paths: string[], aliases: { [key: s
// In order to have the aurelia-loader work correctly, we need to coerce everything to absolute ids
// Is it a node_module?
if (isNodeModule(module)) {
return _nodeModuleResourceIdMap[module.resource];
return nodeModuleResourceIdMap[module.resource];
}

// Get the module relative to the webpack resolver paths
let moduleId = getRelativeModule(module, paths);

// Fallback to parsing aliases if needed
return (moduleId) ? moduleId : getAliasModule(module, aliases);
if (!moduleId) {
moduleId = getAliasModule(module, aliases);
}

// Still nothing?
if (!moduleId) {
throw new Error(`Can't figure out a normalized module name for ${module.rawRequest}, please call PLATFORM.moduleName() somewhere to help.`);
}

return moduleId;
}

/**
Expand All @@ -474,9 +470,5 @@ function getModuleId(module: Webpack.Module, paths: string[], aliases: { [key: s
* @return {string|null} The escaped string
*/
function escapeString(str: string): string | null {
if (typeof str !== 'string') {
return null;
}

return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
}
7 changes: 6 additions & 1 deletion src/webpack.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ declare namespace Webpack {
range: [number, number];
// Those types are not correct, but that's enough to compile this project
property: IdentifierExpression;
object: { name: string; type: string; } & MemberExpression;
object: { name: string; type: string; } & (MemberExpression | Identifier);
type: "MemberExpression";
}

export class Identifier {
name: string;
type: "Identifier";
}

export class IdentifierExpression {
range: [number, number];
name: string;
Expand Down

0 comments on commit 5426b42

Please sign in to comment.