Skip to content

Commit 55dd3f8

Browse files
authored
When available, use resolve data already present in most modules (#114)
* When available, use resolve data already present in most modules * remove one check * Use throwIfNoEntry in backward compatible way
1 parent 81ee591 commit 55dd3f8

9 files changed

+109
-64
lines changed

src/FileHandler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ interface FileHandler {
44
getModule(
55
filename: string | null | undefined
66
): LicenseIdentifiedModule | null;
7+
isBuildRoot(filename: string): boolean;
8+
isInModuleDirectory(filename: string): boolean;
79
}
810

911
export { FileHandler };

src/LicenseIdentifiedModule.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { Module } from './Module';
22
import { PackageJson } from './PackageJson';
33

44
interface LicenseIdentifiedModule extends Module {
5-
packageJson: PackageJson;
6-
licenseId: string | null;
7-
licenseText: string | null;
5+
packageJson?: PackageJson;
6+
licenseId?: string | null;
7+
licenseText?: string | null;
88
}
99

1010
export { LicenseIdentifiedModule };

src/PluginChunkReadHandler.ts

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import { WebpackChunkHandler } from './WebpackChunkHandler';
22
import { WebpackChunk } from './WebpackChunk';
3+
import { WebpackChunkModule } from './WebpackChunkModule';
34
import { WebpackChunkModuleIterator } from './WebpackChunkModuleIterator';
4-
import { WebpackModuleFileIterator } from './WebpackModuleFileIterator';
5+
import { WebpackInnerModuleIterator } from './WebpackInnerModuleIterator';
56
import { FileHandler } from './FileHandler';
67
import { LicenseTypeIdentifier } from './LicenseTypeIdentifier';
78
import { FileSystem } from './FileSystem';
89
import { PackageJson } from './PackageJson';
910
import { LicenseTextReader } from './LicenseTextReader';
1011
import { ModuleCache } from './ModuleCache';
1112
import { LicensePolicy } from './LicensePolicy';
12-
import { Module } from './Module';
1313
import { LicenseIdentifiedModule } from './LicenseIdentifiedModule';
1414
import { WebpackCompilation } from './WebpackCompilation';
1515
import { Logger } from './Logger';
1616
import { WebpackStats } from './WebpackStats';
1717

1818
class PluginChunkReadHandler implements WebpackChunkHandler {
1919
private moduleIterator = new WebpackChunkModuleIterator();
20-
private fileIterator = new WebpackModuleFileIterator(require.resolve);
20+
private innerModuleIterator = new WebpackInnerModuleIterator(require.resolve);
2121

2222
constructor(
2323
private logger: Logger,
@@ -34,15 +34,51 @@ class PluginChunkReadHandler implements WebpackChunkHandler {
3434
moduleCache: ModuleCache,
3535
stats: WebpackStats | undefined
3636
) {
37-
this.moduleIterator.iterateModules(compilation, chunk, stats, module => {
38-
this.fileIterator.iterateFiles(
39-
module,
40-
(filename: string | null | undefined) => {
41-
const module = this.fileHandler.getModule(filename);
42-
this.processModule(compilation, chunk, moduleCache, module);
43-
}
44-
);
45-
});
37+
this.moduleIterator.iterateModules(
38+
compilation,
39+
chunk,
40+
stats,
41+
chunkModule => {
42+
this.innerModuleIterator.iterateModules(
43+
chunkModule,
44+
(module: WebpackChunkModule) => {
45+
const identifiedModule =
46+
this.extractIdentifiedModule(module) ||
47+
this.fileHandler.getModule(module.resource);
48+
if (identifiedModule) {
49+
this.processModule(
50+
compilation,
51+
chunk,
52+
moduleCache,
53+
identifiedModule
54+
);
55+
}
56+
}
57+
);
58+
}
59+
);
60+
}
61+
62+
private extractIdentifiedModule(
63+
module: WebpackChunkModule
64+
): LicenseIdentifiedModule | undefined {
65+
const resolved = module.resourceResolveData;
66+
if (!resolved) return undefined;
67+
const {
68+
descriptionFileRoot: directory,
69+
descriptionFileData: packageJson
70+
} = resolved;
71+
if (
72+
this.fileHandler.isInModuleDirectory(directory) &&
73+
!this.fileHandler.isBuildRoot(directory)
74+
) {
75+
return {
76+
directory,
77+
packageJson,
78+
name: packageJson.name
79+
};
80+
}
81+
return undefined;
4682
}
4783

4884
private getPackageJson(directory: string): PackageJson {
@@ -54,20 +90,17 @@ class PluginChunkReadHandler implements WebpackChunkHandler {
5490
compilation: WebpackCompilation,
5591
chunk: WebpackChunk,
5692
moduleCache: ModuleCache,
57-
module: Module | LicenseIdentifiedModule | null
93+
module: LicenseIdentifiedModule
5894
) {
59-
if (module && !moduleCache.alreadySeenForChunk(chunk.name, module.name)) {
95+
if (!moduleCache.alreadySeenForChunk(chunk.name, module.name)) {
6096
const alreadyIncludedModule = moduleCache.getModule(module.name);
6197
if (alreadyIncludedModule !== null) {
6298
moduleCache.registerModule(chunk.name, alreadyIncludedModule);
6399
} else {
64100
// module not yet in cache
65-
const packageJson: PackageJson =
66-
(<LicenseIdentifiedModule>module).packageJson ??
67-
this.getPackageJson(module.directory);
68-
const licenseType:
69-
| string
70-
| null = this.licenseTypeIdentifier.findLicenseIdentifier(
101+
const packageJson =
102+
module.packageJson ?? this.getPackageJson(module.directory);
103+
const licenseType = this.licenseTypeIdentifier.findLicenseIdentifier(
71104
compilation,
72105
module.name,
73106
packageJson

src/PluginFileHandler.ts

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,30 @@ class PluginFileHandler implements FileHandler {
2020
: this.cache[filename];
2121
}
2222

23+
isInModuleDirectory(filename: string) {
24+
if (this.modulesDirectories === null) return true;
25+
if (filename === null || filename === undefined) return false;
26+
let foundInModuleDirectory = false;
27+
const resolvedPath = this.fileSystem.resolvePath(filename);
28+
for (const modulesDirectory of this.modulesDirectories) {
29+
if (
30+
resolvedPath.startsWith(this.fileSystem.resolvePath(modulesDirectory))
31+
) {
32+
foundInModuleDirectory = true;
33+
}
34+
}
35+
return foundInModuleDirectory;
36+
}
37+
38+
isBuildRoot(filename: string) {
39+
return this.buildRoot === filename;
40+
}
41+
2342
private getModuleInternal(
2443
filename: string
2544
): Partial<LicenseIdentifiedModule> | null {
26-
if (filename === null || filename === undefined) {
27-
return null;
28-
}
29-
30-
if (this.modulesDirectories !== null) {
31-
let foundInModuleDirectory = false;
32-
for (const modulesDirectory of this.modulesDirectories) {
33-
if (
34-
this.fileSystem
35-
.resolvePath(filename)
36-
.startsWith(this.fileSystem.resolvePath(modulesDirectory))
37-
) {
38-
foundInModuleDirectory = true;
39-
}
40-
}
41-
if (!foundInModuleDirectory) {
42-
return null;
43-
}
44-
}
45+
if (filename === null || filename === undefined) return null;
46+
if (!this.isInModuleDirectory(filename)) return null;
4547

4648
const module = this.findModuleDir(filename);
4749

@@ -78,7 +80,7 @@ class PluginFileHandler implements FileHandler {
7880
}
7981
}
8082

81-
if (this.buildRoot === dirOfModule) {
83+
if (this.isBuildRoot(dirOfModule)) {
8284
return null;
8385
}
8486

src/WebpackChunkHandler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { WebpackChunk } from './WebpackChunk';
22
import { ModuleCache } from './ModuleCache';
3-
import { Module } from './Module';
3+
import { LicenseIdentifiedModule } from './LicenseIdentifiedModule';
44
import { WebpackCompilation } from './WebpackCompilation';
55
import { WebpackStats } from './WebpackStats';
66

@@ -15,7 +15,7 @@ interface WebpackChunkHandler {
1515
compilation: WebpackCompilation,
1616
chunk: WebpackChunk,
1717
moduleCache: ModuleCache,
18-
module: Module
18+
module: LicenseIdentifiedModule
1919
): void;
2020
}
2121

src/WebpackChunkModule.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { PackageJson } from './PackageJson';
2+
13
export interface WebpackChunkModule {
2-
resource: string;
4+
resource?: string;
35
rootModule?: {
46
resource?: string;
57
};
@@ -8,4 +10,8 @@ export interface WebpackChunkModule {
810
};
911
fileDependencies?: string[];
1012
dependencies?: WebpackChunkModule[];
13+
resourceResolveData?: {
14+
descriptionFileRoot: string;
15+
descriptionFileData: PackageJson;
16+
};
1117
}

src/WebpackFileSystem.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ class WebpackFileSystem implements FileSystem {
1818

1919
pathExists(filename: string): boolean {
2020
try {
21-
this.fs.statSync(filename);
22-
return true;
21+
const stat = this.fs.statSync(filename, { throwIfNoEntry: false });
22+
return !!stat;
2323
} catch (e) {
2424
return false;
2525
}
@@ -44,7 +44,7 @@ class WebpackFileSystem implements FileSystem {
4444
isDirectory(dir: string): boolean {
4545
let isDir = false;
4646
try {
47-
isDir = this.fs.statSync(dir).isDirectory();
47+
isDir = this.fs.statSync(dir, { throwIfNoEntry: false }).isDirectory();
4848
} catch (e) {}
4949
return isDir;
5050
}

src/WebpackModuleFileIterator.ts renamed to src/WebpackInnerModuleIterator.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,37 @@
11
import { WebpackChunkModule } from './WebpackChunkModule';
22

3-
class WebpackModuleFileIterator {
3+
class WebpackInnerModuleIterator {
44
constructor(private requireResolve: RequireResolve) {}
55

6-
iterateFiles(
6+
iterateModules(
77
chunkModule: WebpackChunkModule,
8-
callback: (filename: string | null | undefined) => void
8+
callback: (module: WebpackChunkModule) => void
99
) {
1010
const internalCallback = this.internalCallback.bind(this, callback);
1111
internalCallback(
12-
chunkModule.resource ||
13-
(chunkModule.rootModule && chunkModule.rootModule.resource)
12+
chunkModule.resource ? chunkModule : chunkModule.rootModule
1413
);
1514
if (Array.isArray(chunkModule.fileDependencies)) {
1615
const fileDependencies: string[] = chunkModule.fileDependencies;
17-
fileDependencies.forEach(internalCallback);
16+
fileDependencies.forEach(fileDependency =>
17+
internalCallback({ resource: fileDependency })
18+
);
1819
}
1920
if (Array.isArray(chunkModule.dependencies)) {
2021
chunkModule.dependencies.forEach(module =>
21-
internalCallback(module.originModule && module.originModule.resource)
22+
internalCallback(module.originModule)
2223
);
2324
}
2425
}
2526

2627
private internalCallback(
27-
callback: (filename: string | null | undefined) => void,
28-
filename: string | null | undefined
28+
callback: (module: WebpackChunkModule) => void,
29+
module: WebpackChunkModule | undefined
2930
): void {
30-
const actualFileName = this.getActualFilename(filename);
31+
if (!module) return;
32+
const actualFileName = this.getActualFilename(module.resource);
3133
if (actualFileName) {
32-
callback(actualFileName);
34+
callback({ ...module, resource: actualFileName });
3335
}
3436
}
3537

@@ -69,4 +71,4 @@ class WebpackModuleFileIterator {
6971
}
7072
}
7173

72-
export { WebpackModuleFileIterator };
74+
export { WebpackInnerModuleIterator };

src/__tests__/WebpackModuleFileIterator.test.ts renamed to src/__tests__/WebpackInnerModuleIterator.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { WebpackModuleFileIterator } from '../WebpackModuleFileIterator';
1+
import { WebpackInnerModuleIterator } from '../WebpackInnerModuleIterator';
22
import {
33
fakeRequireResolve,
44
FAKE_REQUIRE_RESOLVE_OUTPUT
55
} from './FakeRequireResolve';
66

7-
const iterator = new WebpackModuleFileIterator(fakeRequireResolve);
7+
const iterator = new WebpackInnerModuleIterator(fakeRequireResolve);
88

9-
describe('WebpackModuleFileIterator', () => {
9+
describe('WebpackInnerModuleIterator', () => {
1010
it('returns null for falsy filename', () => {
1111
expect(iterator.getActualFilename('')).toBeNull();
1212
expect(iterator.getActualFilename(null)).toBeNull();

0 commit comments

Comments
 (0)