-
-
Notifications
You must be signed in to change notification settings - Fork 615
Expand file tree
/
Copy pathAssetRelocatorPatch.ts
More file actions
83 lines (72 loc) · 2.91 KB
/
AssetRelocatorPatch.ts
File metadata and controls
83 lines (72 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import type { Chunk, Compiler } from 'webpack';
export default class AssetRelocatorPatch {
private readonly isProd: boolean;
private readonly nodeIntegration: boolean;
constructor(isProd: boolean, nodeIntegration: boolean) {
this.isProd = isProd;
this.nodeIntegration = nodeIntegration;
}
private injectedProductionDirnameCode(): string {
if (this.nodeIntegration) {
// In production the assets are found one directory up from
// __dirname
return 'require("path").resolve(__dirname, "..")';
}
// If nodeIntegration is disabled, we replace __dirname
// with an empty string so no error is thrown at runtime
return '""';
}
public apply(compiler: Compiler): void {
compiler.hooks.compilation.tap(
'asset-relocator-forge-patch',
(compilation) => {
// We intercept the Vercel loader code injection and replace __dirname with
// code that works with Electron Forge
//
// Here is where the injection occurs:
// https://github.com/vercel/webpack-asset-relocator-loader/blob/4710a018fc8fb64ad51efb368759616fb273618f/src/asset-relocator.js#L331-L339
compilation.mainTemplate.hooks.requireExtensions.intercept({
register: (tapInfo) => {
if (tapInfo.name === 'asset-relocator-loader') {
const originalFn = tapInfo.fn as (
source: string,
chunk: Chunk,
) => string;
tapInfo.fn = (source: string, chunk: Chunk) => {
const originalInjectCode = originalFn(source, chunk);
// Since this is not a public API of the Vercel loader, it could
// change on patch versions and break things.
//
// If the injected code changes substantially, we throw an error
if (
!originalInjectCode.includes(
'__webpack_require__.ab = __dirname + ',
)
) {
throw new Error(
'The installed version of @vercel/webpack-asset-relocator-loader does not appear to be compatible with Forge',
);
}
if (this.isProd) {
return originalInjectCode.replace(
'__dirname',
this.injectedProductionDirnameCode(),
);
}
return originalInjectCode.replace(
'__dirname',
// In development, the app is loaded via webpack-dev-server
// so __dirname is useless because it points to Electron
// internal code. Instead we hard-code the absolute path to
// the webpack output.
JSON.stringify(compiler.options.output.path),
);
};
}
return tapInfo;
},
});
},
);
}
}