Skip to content

Commit ca69c8c

Browse files
alan-agius4clydin
authored andcommitted
fix(@angular-devkit/build-angular): update ScriptsWebpackPlugin to work with Webpack 5
Closes: #19550
1 parent 30b8e00 commit ca69c8c

File tree

1 file changed

+60
-56
lines changed

1 file changed

+60
-56
lines changed

packages/angular_devkit/build_angular/src/webpack/plugins/scripts-webpack-plugin.ts

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -35,30 +35,33 @@ function addDependencies(compilation: any, scripts: string[]): void {
3535
compilation.fileDependencies.add(script);
3636
}
3737
}
38-
39-
function hook(compiler: any, action: (compilation: any, callback: (err?: Error) => void) => void) {
40-
compiler.hooks.thisCompilation.tap('scripts-webpack-plugin', (compilation: any) => {
41-
compilation.hooks.additionalAssets.tapAsync(
42-
'scripts-webpack-plugin',
43-
(callback: (err?: Error) => void) => action(compilation, callback),
44-
);
45-
});
46-
}
47-
4838
export class ScriptsWebpackPlugin {
4939
private _lastBuildTime?: number;
5040
private _cachedOutput?: ScriptOutput;
5141

5242
constructor(private options: Partial<ScriptsWebpackPluginOptions> = {}) { }
5343

54-
shouldSkip(compilation: any, scripts: string[]): boolean {
44+
async shouldSkip(compilation: any, scripts: string[]): Promise<boolean> {
5545
if (this._lastBuildTime == undefined) {
5646
this._lastBuildTime = Date.now();
5747
return false;
5848
}
5949

60-
for (let i = 0; i < scripts.length; i++) {
61-
const scriptTime = compilation.fileTimestamps.get(scripts[i]);
50+
for (const script of scripts) {
51+
const scriptTime = isWebpackFiveOrHigher()
52+
? await new Promise<number | undefined>((resolve, reject) => {
53+
compilation.fileSystemInfo.getFileTimestamp(script, (error: unknown, entry: any) => {
54+
if (error) {
55+
reject(error);
56+
57+
return;
58+
}
59+
60+
resolve(typeof entry !== 'string' ? entry.safeTime : undefined)
61+
})
62+
})
63+
: compilation.fileTimestamps.get(script);
64+
6265
if (!scriptTime || scriptTime > this._lastBuildTime) {
6366
this._lastBuildTime = Date.now();
6467
return false;
@@ -83,7 +86,12 @@ export class ScriptsWebpackPlugin {
8386
entrypoint.pushChunk(chunk);
8487
chunk.addGroup(entrypoint);
8588
compilation.entrypoints.set(this.options.name, entrypoint);
86-
compilation.chunks.push(chunk);
89+
if (isWebpackFiveOrHigher()) {
90+
compilation.chunks.add(chunk);
91+
} else {
92+
compilation.chunks.push(chunk);
93+
}
94+
8795
compilation.assets[filename] = source;
8896
}
8997

@@ -96,48 +104,47 @@ export class ScriptsWebpackPlugin {
96104
.filter(script => !!script)
97105
.map(script => path.resolve(this.options.basePath || '', script));
98106

99-
hook(compiler, (compilation, callback) => {
100-
if (this.shouldSkip(compilation, scripts)) {
101-
if (this._cachedOutput) {
102-
this._insertOutput(compilation, this._cachedOutput, true);
103-
}
104-
105-
addDependencies(compilation, scripts);
106-
callback();
107-
108-
return;
109-
}
110-
111-
const sourceGetters = scripts.map(fullPath => {
112-
return new Promise<Source>((resolve, reject) => {
113-
compilation.inputFileSystem.readFile(fullPath, (err: Error, data: Buffer) => {
114-
if (err) {
115-
reject(err);
116-
return;
107+
compiler.hooks.thisCompilation.tap('scripts-webpack-plugin', compilation => {
108+
compilation.hooks.additionalAssets.tapPromise('scripts-webpack-plugin', async () => {
109+
if (await this.shouldSkip(compilation, scripts)) {
110+
if (this._cachedOutput) {
111+
this._insertOutput(compilation, this._cachedOutput, true);
117112
}
118113

119-
const content = data.toString();
120-
121-
let source;
122-
if (this.options.sourceMap) {
123-
// TODO: Look for source map file (for '.min' scripts, etc.)
124-
125-
let adjustedPath = fullPath;
126-
if (this.options.basePath) {
127-
adjustedPath = path.relative(this.options.basePath, fullPath);
128-
}
129-
source = new OriginalSource(content, adjustedPath);
130-
} else {
131-
source = new RawSource(content);
132-
}
133-
134-
resolve(source);
114+
addDependencies(compilation, scripts);
115+
116+
return;
117+
}
118+
119+
const sourceGetters = scripts.map(fullPath => {
120+
return new Promise<Source>((resolve, reject) => {
121+
compilation.inputFileSystem.readFile(fullPath, (err: Error, data: Buffer) => {
122+
if (err) {
123+
reject(err);
124+
return;
125+
}
126+
127+
const content = data.toString();
128+
129+
let source;
130+
if (this.options.sourceMap) {
131+
// TODO: Look for source map file (for '.min' scripts, etc.)
132+
133+
let adjustedPath = fullPath;
134+
if (this.options.basePath) {
135+
adjustedPath = path.relative(this.options.basePath, fullPath);
136+
}
137+
source = new OriginalSource(content, adjustedPath);
138+
} else {
139+
source = new RawSource(content);
140+
}
141+
142+
resolve(source);
143+
});
144+
});
135145
});
136-
});
137-
});
138146

139-
Promise.all(sourceGetters)
140-
.then(sources => {
147+
const sources = await Promise.all(sourceGetters);
141148
const concatSource = new ConcatSource();
142149
sources.forEach(source => {
143150
concatSource.add(source);
@@ -155,10 +162,7 @@ export class ScriptsWebpackPlugin {
155162
this._insertOutput(compilation, output);
156163
this._cachedOutput = output;
157164
addDependencies(compilation, scripts);
158-
159-
callback();
160-
})
161-
.catch((err: Error) => callback(err));
165+
});
162166
});
163167
}
164168
}

0 commit comments

Comments
 (0)