Skip to content

When available, use resolve data already present in most modules #114

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/FileHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ interface FileHandler {
getModule(
filename: string | null | undefined
): LicenseIdentifiedModule | null;
isBuildRoot(filename: string): boolean;
isInModuleDirectory(filename: string): boolean;
}

export { FileHandler };
6 changes: 3 additions & 3 deletions src/LicenseIdentifiedModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Module } from './Module';
import { PackageJson } from './PackageJson';

interface LicenseIdentifiedModule extends Module {
packageJson: PackageJson;
licenseId: string | null;
licenseText: string | null;
packageJson?: PackageJson;
licenseId?: string | null;
licenseText?: string | null;
}

export { LicenseIdentifiedModule };
73 changes: 53 additions & 20 deletions src/PluginChunkReadHandler.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { WebpackChunkHandler } from './WebpackChunkHandler';
import { WebpackChunk } from './WebpackChunk';
import { WebpackChunkModule } from './WebpackChunkModule';
import { WebpackChunkModuleIterator } from './WebpackChunkModuleIterator';
import { WebpackModuleFileIterator } from './WebpackModuleFileIterator';
import { WebpackInnerModuleIterator } from './WebpackInnerModuleIterator';
import { FileHandler } from './FileHandler';
import { LicenseTypeIdentifier } from './LicenseTypeIdentifier';
import { FileSystem } from './FileSystem';
import { PackageJson } from './PackageJson';
import { LicenseTextReader } from './LicenseTextReader';
import { ModuleCache } from './ModuleCache';
import { LicensePolicy } from './LicensePolicy';
import { Module } from './Module';
import { LicenseIdentifiedModule } from './LicenseIdentifiedModule';
import { WebpackCompilation } from './WebpackCompilation';
import { Logger } from './Logger';
import { WebpackStats } from './WebpackStats';

class PluginChunkReadHandler implements WebpackChunkHandler {
private moduleIterator = new WebpackChunkModuleIterator();
private fileIterator = new WebpackModuleFileIterator(require.resolve);
private innerModuleIterator = new WebpackInnerModuleIterator(require.resolve);

constructor(
private logger: Logger,
Expand All @@ -34,15 +34,51 @@ class PluginChunkReadHandler implements WebpackChunkHandler {
moduleCache: ModuleCache,
stats: WebpackStats | undefined
) {
this.moduleIterator.iterateModules(compilation, chunk, stats, module => {
this.fileIterator.iterateFiles(
module,
(filename: string | null | undefined) => {
const module = this.fileHandler.getModule(filename);
this.processModule(compilation, chunk, moduleCache, module);
}
);
});
this.moduleIterator.iterateModules(
compilation,
chunk,
stats,
chunkModule => {
this.innerModuleIterator.iterateModules(
chunkModule,
(module: WebpackChunkModule) => {
const identifiedModule =
this.extractIdentifiedModule(module) ||
this.fileHandler.getModule(module.resource);
if (identifiedModule) {
this.processModule(
compilation,
chunk,
moduleCache,
identifiedModule
);
}
}
);
}
);
}

private extractIdentifiedModule(
module: WebpackChunkModule
): LicenseIdentifiedModule | undefined {
const resolved = module.resourceResolveData;
if (!resolved) return undefined;
const {
descriptionFileRoot: directory,
descriptionFileData: packageJson
} = resolved;
if (
this.fileHandler.isInModuleDirectory(directory) &&
!this.fileHandler.isBuildRoot(directory)
) {
return {
directory,
packageJson,
name: packageJson.name
};
}
return undefined;
}

private getPackageJson(directory: string): PackageJson {
Expand All @@ -54,20 +90,17 @@ class PluginChunkReadHandler implements WebpackChunkHandler {
compilation: WebpackCompilation,
chunk: WebpackChunk,
moduleCache: ModuleCache,
module: Module | LicenseIdentifiedModule | null
module: LicenseIdentifiedModule
) {
if (module && !moduleCache.alreadySeenForChunk(chunk.name, module.name)) {
if (!moduleCache.alreadySeenForChunk(chunk.name, module.name)) {
const alreadyIncludedModule = moduleCache.getModule(module.name);
if (alreadyIncludedModule !== null) {
moduleCache.registerModule(chunk.name, alreadyIncludedModule);
} else {
// module not yet in cache
const packageJson: PackageJson =
(<LicenseIdentifiedModule>module).packageJson ??
this.getPackageJson(module.directory);
const licenseType:
| string
| null = this.licenseTypeIdentifier.findLicenseIdentifier(
const packageJson =
module.packageJson ?? this.getPackageJson(module.directory);
const licenseType = this.licenseTypeIdentifier.findLicenseIdentifier(
compilation,
module.name,
packageJson
Expand Down
42 changes: 22 additions & 20 deletions src/PluginFileHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,30 @@ class PluginFileHandler implements FileHandler {
: this.cache[filename];
}

isInModuleDirectory(filename: string) {
if (this.modulesDirectories === null) return true;
if (filename === null || filename === undefined) return false;
let foundInModuleDirectory = false;
const resolvedPath = this.fileSystem.resolvePath(filename);
for (const modulesDirectory of this.modulesDirectories) {
if (
resolvedPath.startsWith(this.fileSystem.resolvePath(modulesDirectory))
) {
foundInModuleDirectory = true;
}
}
return foundInModuleDirectory;
}

isBuildRoot(filename: string) {
return this.buildRoot === filename;
}

private getModuleInternal(
filename: string
): Partial<LicenseIdentifiedModule> | null {
if (filename === null || filename === undefined) {
return null;
}

if (this.modulesDirectories !== null) {
let foundInModuleDirectory = false;
for (const modulesDirectory of this.modulesDirectories) {
if (
this.fileSystem
.resolvePath(filename)
.startsWith(this.fileSystem.resolvePath(modulesDirectory))
) {
foundInModuleDirectory = true;
}
}
if (!foundInModuleDirectory) {
return null;
}
}
if (filename === null || filename === undefined) return null;
if (!this.isInModuleDirectory(filename)) return null;

const module = this.findModuleDir(filename);

Expand Down Expand Up @@ -78,7 +80,7 @@ class PluginFileHandler implements FileHandler {
}
}

if (this.buildRoot === dirOfModule) {
if (this.isBuildRoot(dirOfModule)) {
return null;
}

Expand Down
4 changes: 2 additions & 2 deletions src/WebpackChunkHandler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { WebpackChunk } from './WebpackChunk';
import { ModuleCache } from './ModuleCache';
import { Module } from './Module';
import { LicenseIdentifiedModule } from './LicenseIdentifiedModule';
import { WebpackCompilation } from './WebpackCompilation';
import { WebpackStats } from './WebpackStats';

Expand All @@ -15,7 +15,7 @@ interface WebpackChunkHandler {
compilation: WebpackCompilation,
chunk: WebpackChunk,
moduleCache: ModuleCache,
module: Module
module: LicenseIdentifiedModule
): void;
}

Expand Down
8 changes: 7 additions & 1 deletion src/WebpackChunkModule.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { PackageJson } from './PackageJson';

export interface WebpackChunkModule {
resource: string;
resource?: string;
rootModule?: {
resource?: string;
};
Expand All @@ -8,4 +10,8 @@ export interface WebpackChunkModule {
};
fileDependencies?: string[];
dependencies?: WebpackChunkModule[];
resourceResolveData?: {
descriptionFileRoot: string;
descriptionFileData: PackageJson;
};
}
6 changes: 3 additions & 3 deletions src/WebpackFileSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class WebpackFileSystem implements FileSystem {

pathExists(filename: string): boolean {
try {
this.fs.statSync(filename);
return true;
const stat = this.fs.statSync(filename, { throwIfNoEntry: false });
return !!stat;
} catch (e) {
return false;
}
Expand All @@ -44,7 +44,7 @@ class WebpackFileSystem implements FileSystem {
isDirectory(dir: string): boolean {
let isDir = false;
try {
isDir = this.fs.statSync(dir).isDirectory();
isDir = this.fs.statSync(dir, { throwIfNoEntry: false }).isDirectory();
} catch (e) {}
return isDir;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
import { WebpackChunkModule } from './WebpackChunkModule';

class WebpackModuleFileIterator {
class WebpackInnerModuleIterator {
constructor(private requireResolve: RequireResolve) {}

iterateFiles(
iterateModules(
chunkModule: WebpackChunkModule,
callback: (filename: string | null | undefined) => void
callback: (module: WebpackChunkModule) => void
) {
const internalCallback = this.internalCallback.bind(this, callback);
internalCallback(
chunkModule.resource ||
(chunkModule.rootModule && chunkModule.rootModule.resource)
chunkModule.resource ? chunkModule : chunkModule.rootModule
);
if (Array.isArray(chunkModule.fileDependencies)) {
const fileDependencies: string[] = chunkModule.fileDependencies;
fileDependencies.forEach(internalCallback);
fileDependencies.forEach(fileDependency =>
internalCallback({ resource: fileDependency })
);
}
if (Array.isArray(chunkModule.dependencies)) {
chunkModule.dependencies.forEach(module =>
internalCallback(module.originModule && module.originModule.resource)
internalCallback(module.originModule)
);
}
}

private internalCallback(
callback: (filename: string | null | undefined) => void,
filename: string | null | undefined
callback: (module: WebpackChunkModule) => void,
module: WebpackChunkModule | undefined
): void {
const actualFileName = this.getActualFilename(filename);
if (!module) return;
const actualFileName = this.getActualFilename(module.resource);
if (actualFileName) {
callback(actualFileName);
callback({ ...module, resource: actualFileName });
}
}

Expand Down Expand Up @@ -69,4 +71,4 @@ class WebpackModuleFileIterator {
}
}

export { WebpackModuleFileIterator };
export { WebpackInnerModuleIterator };
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { WebpackModuleFileIterator } from '../WebpackModuleFileIterator';
import { WebpackInnerModuleIterator } from '../WebpackInnerModuleIterator';
import {
fakeRequireResolve,
FAKE_REQUIRE_RESOLVE_OUTPUT
} from './FakeRequireResolve';

const iterator = new WebpackModuleFileIterator(fakeRequireResolve);
const iterator = new WebpackInnerModuleIterator(fakeRequireResolve);

describe('WebpackModuleFileIterator', () => {
describe('WebpackInnerModuleIterator', () => {
it('returns null for falsy filename', () => {
expect(iterator.getActualFilename('')).toBeNull();
expect(iterator.getActualFilename(null)).toBeNull();
Expand Down