update build scripts to latest esbuild & typescript

This commit is contained in:
Vendicated 2024-07-19 20:40:24 +02:00
parent d84943a6d7
commit 8fa7d006a4
No known key found for this signature in database
GPG key ID: D66986BAF75ECF18
8 changed files with 610 additions and 346 deletions

View file

@ -14,9 +14,9 @@
"license": "GPL-3.0-or-later", "license": "GPL-3.0-or-later",
"author": "Vendicated", "author": "Vendicated",
"scripts": { "scripts": {
"build": "node --require=./scripts/suppressExperimentalWarnings.js scripts/build/build.mjs", "build": "tsx scripts/build/build.mts",
"buildStandalone": "pnpm build --standalone", "buildStandalone": "pnpm build --standalone",
"buildWeb": "node --require=./scripts/suppressExperimentalWarnings.js scripts/build/buildWeb.mjs", "buildWeb": "tsx scripts/build/buildWeb.mts",
"buildWebStandalone": "pnpm buildWeb --standalone", "buildWebStandalone": "pnpm buildWeb --standalone",
"buildReporter": "pnpm buildWebStandalone --reporter --skip-extension", "buildReporter": "pnpm buildWebStandalone --reporter --skip-extension",
"buildReporterDesktop": "pnpm build --reporter", "buildReporterDesktop": "pnpm build --reporter",
@ -58,7 +58,7 @@
"@typescript-eslint/parser": "^5.59.1", "@typescript-eslint/parser": "^5.59.1",
"diff": "^5.1.0", "diff": "^5.1.0",
"discord-types": "^1.3.26", "discord-types": "^1.3.26",
"esbuild": "^0.15.18", "esbuild": "^0.23.0",
"eslint": "^8.46.0", "eslint": "^8.46.0",
"eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-path-alias": "^1.0.0", "eslint-plugin-path-alias": "^1.0.0",
@ -72,7 +72,7 @@
"stylelint": "^15.6.0", "stylelint": "^15.6.0",
"stylelint-config-standard": "^33.0.0", "stylelint-config-standard": "^33.0.0",
"ts-patch": "^3.1.2", "ts-patch": "^3.1.2",
"tsx": "^3.12.7", "tsx": "^4.16.2",
"type-fest": "^3.9.0", "type-fest": "^3.9.0",
"typescript": "^5.4.5", "typescript": "^5.4.5",
"typescript-transform-paths": "^3.4.7", "typescript-transform-paths": "^3.4.7",

File diff suppressed because it is too large Load diff

View file

@ -18,32 +18,29 @@
*/ */
import { createPackage } from "@electron/asar"; import { createPackage } from "@electron/asar";
import esbuild from "esbuild"; import { BuildOptions, Plugin } from "esbuild";
import { existsSync, readdirSync } from "fs"; import { existsSync, readdirSync } from "fs";
import { readdir, rm, writeFile } from "fs/promises"; import { readdir, rm, writeFile } from "fs/promises";
import { join } from "path"; import { join } from "path";
import { BUILD_TIMESTAMP, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, watch } from "./common.mjs"; import { addBuild, BUILD_TIMESTAMP, buildOrWatchAll, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, watch } from "./common.mjs";
const defines = { const defines = {
IS_STANDALONE, IS_STANDALONE: String(IS_STANDALONE),
IS_DEV, IS_DEV: String(IS_DEV),
IS_REPORTER, IS_REPORTER: String(IS_REPORTER),
IS_UPDATER_DISABLED, IS_UPDATER_DISABLED: String(IS_UPDATER_DISABLED),
IS_WEB: false, IS_WEB: "false",
IS_EXTENSION: false, IS_EXTENSION: "false",
VERSION: JSON.stringify(VERSION), VERSION: JSON.stringify(VERSION),
BUILD_TIMESTAMP BUILD_TIMESTAMP: String(BUILD_TIMESTAMP)
}; };
if (defines.IS_STANDALONE === false) if (defines.IS_STANDALONE === "false")
// If this is a local build (not standalone), optimize // If this is a local build (not standalone), optimize
// for the specific platform we're on // for the specific platform we're on
defines["process.platform"] = JSON.stringify(process.platform); defines["process.platform"] = JSON.stringify(process.platform);
/**
* @type {esbuild.BuildOptions}
*/
const nodeCommonOpts = { const nodeCommonOpts = {
...commonOpts, ...commonOpts,
format: "cjs", format: "cjs",
@ -51,15 +48,12 @@ const nodeCommonOpts = {
target: ["esnext"], target: ["esnext"],
external: ["electron", "original-fs", "~pluginNatives", ...commonOpts.external], external: ["electron", "original-fs", "~pluginNatives", ...commonOpts.external],
define: defines define: defines
}; } satisfies BuildOptions;
const sourceMapFooter = s => watch ? "" : `//# sourceMappingURL=vencord://${s}.js.map`; const sourceMapFooter = s => watch ? "" : `//# sourceMappingURL=vencord://${s}.js.map`;
const sourcemap = watch ? "inline" : "external"; const sourcemap = watch ? "inline" : "external";
/** const globNativesPlugin: Plugin = {
* @type {import("esbuild").Plugin}
*/
const globNativesPlugin = {
name: "glob-natives-plugin", name: "glob-natives-plugin",
setup: build => { setup: build => {
const filter = /^~pluginNatives$/; const filter = /^~pluginNatives$/;
@ -106,7 +100,7 @@ const globNativesPlugin = {
await Promise.all([ await Promise.all([
// Discord Desktop main & renderer & preload // Discord Desktop main & renderer & preload
esbuild.build({ addBuild({
...nodeCommonOpts, ...nodeCommonOpts,
entryPoints: ["src/main/index.ts"], entryPoints: ["src/main/index.ts"],
outfile: "dist/desktop/patcher.js", outfile: "dist/desktop/patcher.js",
@ -114,15 +108,15 @@ await Promise.all([
sourcemap, sourcemap,
define: { define: {
...defines, ...defines,
IS_DISCORD_DESKTOP: true, IS_DISCORD_DESKTOP: "true",
IS_VESKTOP: false IS_VESKTOP: "false"
}, },
plugins: [ plugins: [
...nodeCommonOpts.plugins, ...nodeCommonOpts.plugins,
globNativesPlugin globNativesPlugin
] ]
}), }),
esbuild.build({ addBuild({
...commonOpts, ...commonOpts,
entryPoints: ["src/Vencord.ts"], entryPoints: ["src/Vencord.ts"],
outfile: "dist/desktop/renderer.js", outfile: "dist/desktop/renderer.js",
@ -137,11 +131,11 @@ await Promise.all([
], ],
define: { define: {
...defines, ...defines,
IS_DISCORD_DESKTOP: true, IS_DISCORD_DESKTOP: "true",
IS_VESKTOP: false IS_VESKTOP: "false"
} }
}), }),
esbuild.build({ addBuild({
...nodeCommonOpts, ...nodeCommonOpts,
entryPoints: ["src/preload.ts"], entryPoints: ["src/preload.ts"],
outfile: "dist/desktop/preload.js", outfile: "dist/desktop/preload.js",
@ -149,13 +143,13 @@ await Promise.all([
sourcemap, sourcemap,
define: { define: {
...defines, ...defines,
IS_DISCORD_DESKTOP: true, IS_DISCORD_DESKTOP: "true",
IS_VESKTOP: false IS_VESKTOP: "false"
} }
}), }),
// Vencord Desktop main & renderer & preload // Vencord Desktop main & renderer & preload
esbuild.build({ addBuild({
...nodeCommonOpts, ...nodeCommonOpts,
entryPoints: ["src/main/index.ts"], entryPoints: ["src/main/index.ts"],
outfile: "dist/vesktop/main.js", outfile: "dist/vesktop/main.js",
@ -163,15 +157,15 @@ await Promise.all([
sourcemap, sourcemap,
define: { define: {
...defines, ...defines,
IS_DISCORD_DESKTOP: false, IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: true IS_VESKTOP: "true"
}, },
plugins: [ plugins: [
...nodeCommonOpts.plugins, ...nodeCommonOpts.plugins,
globNativesPlugin globNativesPlugin
] ]
}), }),
esbuild.build({ addBuild({
...commonOpts, ...commonOpts,
entryPoints: ["src/Vencord.ts"], entryPoints: ["src/Vencord.ts"],
outfile: "dist/vesktop/renderer.js", outfile: "dist/vesktop/renderer.js",
@ -186,11 +180,11 @@ await Promise.all([
], ],
define: { define: {
...defines, ...defines,
IS_DISCORD_DESKTOP: false, IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: true IS_VESKTOP: "true"
} }
}), }),
esbuild.build({ addBuild({
...nodeCommonOpts, ...nodeCommonOpts,
entryPoints: ["src/preload.ts"], entryPoints: ["src/preload.ts"],
outfile: "dist/vesktop/preload.js", outfile: "dist/vesktop/preload.js",
@ -198,17 +192,13 @@ await Promise.all([
sourcemap, sourcemap,
define: { define: {
...defines, ...defines,
IS_DISCORD_DESKTOP: false, IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: true IS_VESKTOP: "true"
} }
}), }),
]).catch(err => { ]);
console.error("Build failed");
console.error(err.message); await buildOrWatchAll();
// make ci fail
if (!commonOpts.watch)
process.exitCode = 1;
});
await Promise.all([ await Promise.all([
writeFile("dist/desktop/package.json", JSON.stringify({ writeFile("dist/desktop/package.json", JSON.stringify({
@ -226,6 +216,7 @@ await Promise.all([
createPackage("dist/vesktop", "dist/vesktop.asar") createPackage("dist/vesktop", "dist/vesktop.asar")
]); ]);
if (existsSync("dist/renderer.js")) { if (existsSync("dist/renderer.js")) {
console.warn("Legacy dist folder. Cleaning up and adding shims."); console.warn("Legacy dist folder. Cleaning up and adding shims.");

View file

@ -23,12 +23,12 @@ import { appendFile, mkdir, readdir, readFile, rm, writeFile } from "fs/promises
import { join } from "path"; import { join } from "path";
import Zip from "zip-local"; import Zip from "zip-local";
import { BUILD_TIMESTAMP, commonOpts, globPlugins, IS_DEV, IS_REPORTER, VERSION } from "./common.mjs"; import { BUILD_TIMESTAMP, buildOrWatchAll, commonOpts, addBuild, globPlugins, IS_DEV, IS_REPORTER, VERSION } from "./common.mjs";
/** /**
* @type {esbuild.BuildOptions} * @type {esbuild.BuildOptions}
*/ */
const commonOptions = { const commonOptions: esbuild.BuildOptions = {
...commonOpts, ...commonOpts,
entryPoints: ["browser/Vencord.ts"], entryPoints: ["browser/Vencord.ts"],
globalName: "Vencord", globalName: "Vencord",
@ -40,16 +40,16 @@ const commonOptions = {
], ],
target: ["esnext"], target: ["esnext"],
define: { define: {
IS_WEB: true, IS_WEB: "true",
IS_EXTENSION: false, IS_EXTENSION: "false",
IS_STANDALONE: true, IS_STANDALONE: "true",
IS_DEV, IS_DEV: String(IS_DEV),
IS_REPORTER, IS_REPORTER: String(IS_REPORTER),
IS_DISCORD_DESKTOP: false, IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: false, IS_VESKTOP: "false",
IS_UPDATER_DISABLED: true, IS_UPDATER_DISABLED: "true",
VERSION: JSON.stringify(VERSION), VERSION: JSON.stringify(VERSION),
BUILD_TIMESTAMP BUILD_TIMESTAMP: String(BUILD_TIMESTAMP)
} }
}; };
@ -67,7 +67,7 @@ const RnNoiseFiles = [
await Promise.all( await Promise.all(
[ [
esbuild.build({ addBuild({
entryPoints: MonacoWorkerEntryPoints.map(entry => `node_modules/monaco-editor/esm/${entry}`), entryPoints: MonacoWorkerEntryPoints.map(entry => `node_modules/monaco-editor/esm/${entry}`),
bundle: true, bundle: true,
minify: true, minify: true,
@ -75,7 +75,7 @@ await Promise.all(
outbase: "node_modules/monaco-editor/esm/", outbase: "node_modules/monaco-editor/esm/",
outdir: "dist/browser/monaco" outdir: "dist/browser/monaco"
}), }),
esbuild.build({ addBuild({
entryPoints: ["browser/monaco.ts"], entryPoints: ["browser/monaco.ts"],
bundle: true, bundle: true,
minify: true, minify: true,
@ -85,21 +85,21 @@ await Promise.all(
".ttf": "file" ".ttf": "file"
} }
}), }),
esbuild.build({ addBuild({
...commonOptions, ...commonOptions,
outfile: "dist/browser/browser.js", outfile: "dist/browser/browser.js",
footer: { js: "//# sourceURL=VencordWeb" } footer: { js: "//# sourceURL=VencordWeb" }
}), }),
esbuild.build({ addBuild({
...commonOptions, ...commonOptions,
outfile: "dist/browser/extension.js", outfile: "dist/browser/extension.js",
define: { define: {
...commonOptions?.define, ...commonOptions?.define,
IS_EXTENSION: true, IS_EXTENSION: "true",
}, },
footer: { js: "//# sourceURL=VencordWeb" } footer: { js: "//# sourceURL=VencordWeb" }
}), }),
esbuild.build({ addBuild({
...commonOptions, ...commonOptions,
inject: ["browser/GMPolyfill.js", ...(commonOptions?.inject || [])], inject: ["browser/GMPolyfill.js", ...(commonOptions?.inject || [])],
define: { define: {
@ -118,11 +118,10 @@ await Promise.all(
] ]
); );
/** await buildOrWatchAll();
* @type {(dir: string) => Promise<string[]>}
*/ async function globDir(dir: string): Promise<string[]> {
async function globDir(dir) { const files = [] as string[];
const files = [];
for (const child of await readdir(dir, { withFileTypes: true })) { for (const child of await readdir(dir, { withFileTypes: true })) {
const p = join(dir, child.name); const p = join(dir, child.name);
@ -135,27 +134,23 @@ async function globDir(dir) {
return files; return files;
} }
/** async function loadDir(dir: string, basePath = "") {
* @type {(dir: string, basePath?: string) => Promise<Record<string, string>>}
*/
async function loadDir(dir, basePath = "") {
const files = await globDir(dir); const files = await globDir(dir);
return Object.fromEntries(await Promise.all(files.map(async f => [f.slice(basePath.length), await readFile(f)]))); return Object.fromEntries(await Promise.all(files.map(async f =>
[f.slice(basePath.length), await readFile(f)] as const
)));
} }
/** async function buildExtension(target: string, files: string[]): Promise<void> {
* @type {(target: string, files: string[]) => Promise<void>} const entries: Record<string, Buffer> = {
*/
async function buildExtension(target, files) {
const entries = {
"dist/Vencord.js": await readFile("dist/browser/extension.js"), "dist/Vencord.js": await readFile("dist/browser/extension.js"),
"dist/Vencord.css": await readFile("dist/browser/extension.css"), "dist/Vencord.css": await readFile("dist/browser/extension.css"),
...await loadDir("dist/browser/monaco"), ...await loadDir("dist/browser/monaco"),
...Object.fromEntries(await Promise.all(RnNoiseFiles.map(async file => ...Object.fromEntries(await Promise.all(RnNoiseFiles.map(async file =>
[`third-party/rnnoise/${file.replace(/^dist\//, "")}`, await readFile(`node_modules/@sapphi-red/web-noise-suppressor/${file}`)] [`third-party/rnnoise/${file.replace(/^dist\//, "")}`, await readFile(`node_modules/@sapphi-red/web-noise-suppressor/${file}`)] as const
))), ))),
...Object.fromEntries(await Promise.all(files.map(async f => { ...Object.fromEntries(await Promise.all(files.map(async f => {
let content = await readFile(join("browser", f)); let content: Uint8Array | Buffer = await readFile(join("browser", f));
if (f.startsWith("manifest")) { if (f.startsWith("manifest")) {
const json = JSON.parse(content.toString("utf-8")); const json = JSON.parse(content.toString("utf-8"));
json.version = VERSION; json.version = VERSION;
@ -165,7 +160,7 @@ async function buildExtension(target, files) {
return [ return [
f.startsWith("manifest") ? "manifest.json" : f, f.startsWith("manifest") ? "manifest.json" : f,
content content
]; ] as const;
}))) })))
}; };

View file

@ -20,7 +20,7 @@ import "../suppressExperimentalWarnings.js";
import "../checkNodeVersion.js"; import "../checkNodeVersion.js";
import { exec, execSync } from "child_process"; import { exec, execSync } from "child_process";
import esbuild from "esbuild"; import esbuild, { build, BuildOptions, context, Plugin } from "esbuild";
import { constants as FsConstants, readFileSync } from "fs"; import { constants as FsConstants, readFileSync } from "fs";
import { access, readdir, readFile } from "fs/promises"; import { access, readdir, readFile } from "fs/promises";
import { minify as minifyHtml } from "html-minifier-terser"; import { minify as minifyHtml } from "html-minifier-terser";
@ -29,8 +29,7 @@ import { promisify } from "util";
import { getPluginTarget } from "../utils.mjs"; import { getPluginTarget } from "../utils.mjs";
/** @type {import("../../package.json")} */ const PackageJSON: typeof import("../../package.json") = JSON.parse(readFileSync("package.json", "utf-8"));
const PackageJSON = JSON.parse(readFileSync("package.json"));
export const VERSION = PackageJSON.version; export const VERSION = PackageJSON.version;
// https://reproducible-builds.org/docs/source-date-epoch/ // https://reproducible-builds.org/docs/source-date-epoch/
@ -54,11 +53,8 @@ export const banner = {
}; };
const PluginDefinitionNameMatcher = /definePlugin\(\{\s*(["'])?name\1:\s*(["'`])(.+?)\2/; const PluginDefinitionNameMatcher = /definePlugin\(\{\s*(["'])?name\1:\s*(["'`])(.+?)\2/;
/**
* @param {string} base export async function resolvePluginName(base: string, dirent: import("fs").Dirent) {
* @param {import("fs").Dirent} dirent
*/
export async function resolvePluginName(base, dirent) {
const fullPath = join(base, dirent.name); const fullPath = join(base, dirent.name);
const content = dirent.isFile() const content = dirent.isFile()
? await readFile(fullPath, "utf-8") ? await readFile(fullPath, "utf-8")
@ -79,17 +75,13 @@ export async function resolvePluginName(base, dirent) {
})(); })();
} }
export async function exists(path) { export async function exists(path: string) {
return await access(path, FsConstants.F_OK) return await access(path, FsConstants.F_OK)
.then(() => true) .then(() => true)
.catch(() => false); .catch(() => false);
} }
// https://github.com/evanw/esbuild/issues/619#issuecomment-751995294 export const makeAllPackagesExternalPlugin: Plugin = {
/**
* @type {import("esbuild").Plugin}
*/
export const makeAllPackagesExternalPlugin = {
name: "make-all-packages-external", name: "make-all-packages-external",
setup(build) { setup(build) {
const filter = /^[^./]|^\.[^./]|^\.\.[^/]/; // Must not start with "/" or "./" or "../" const filter = /^[^./]|^\.[^./]|^\.\.[^/]/; // Must not start with "/" or "./" or "../"
@ -97,10 +89,7 @@ export const makeAllPackagesExternalPlugin = {
} }
}; };
/** export const globPlugins: (kind: "web" | "discordDesktop" | "vencordDesktop") => Plugin = kind => ({
* @type {(kind: "web" | "discordDesktop" | "vencordDesktop") => import("esbuild").Plugin}
*/
export const globPlugins = kind => ({
name: "glob-plugins", name: "glob-plugins",
setup: build => { setup: build => {
const filter = /^~plugins$/; const filter = /^~plugins$/;
@ -164,10 +153,7 @@ export const globPlugins = kind => ({
} }
}); });
/** export const gitHashPlugin: Plugin = {
* @type {import("esbuild").Plugin}
*/
export const gitHashPlugin = {
name: "git-hash-plugin", name: "git-hash-plugin",
setup: build => { setup: build => {
const filter = /^~git-hash$/; const filter = /^~git-hash$/;
@ -180,10 +166,7 @@ export const gitHashPlugin = {
} }
}; };
/** export const gitRemotePlugin: Plugin = {
* @type {import("esbuild").Plugin}
*/
export const gitRemotePlugin = {
name: "git-remote-plugin", name: "git-remote-plugin",
setup: build => { setup: build => {
const filter = /^~git-remote$/; const filter = /^~git-remote$/;
@ -205,10 +188,7 @@ export const gitRemotePlugin = {
} }
}; };
/** export const fileUrlPlugin: Plugin = {
* @type {import("esbuild").Plugin}
*/
export const fileUrlPlugin = {
name: "file-uri-plugin", name: "file-uri-plugin",
setup: build => { setup: build => {
const filter = /^file:\/\/.+$/; const filter = /^file:\/\/.+$/;
@ -268,10 +248,7 @@ export const fileUrlPlugin = {
}; };
const styleModule = readFileSync("./scripts/build/module/style.js", "utf-8"); const styleModule = readFileSync("./scripts/build/module/style.js", "utf-8");
/** export const stylePlugin: Plugin = {
* @type {import("esbuild").Plugin}
*/
export const stylePlugin = {
name: "style-plugin", name: "style-plugin",
setup: ({ onResolve, onLoad }) => { setup: ({ onResolve, onLoad }) => {
onResolve({ filter: /\.css\?managed$/, namespace: "file" }, ({ path, resolveDir }) => ({ onResolve({ filter: /\.css\?managed$/, namespace: "file" }, ({ path, resolveDir }) => ({
@ -292,15 +269,11 @@ export const stylePlugin = {
} }
}; };
/**
* @type {import("esbuild").BuildOptions}
*/
export const commonOpts = { export const commonOpts = {
logLevel: "info", logLevel: "info",
bundle: true, bundle: true,
watch,
minify: !watch, minify: !watch,
sourcemap: watch ? "inline" : "", sourcemap: watch ? "inline" : "external",
legalComments: "linked", legalComments: "linked",
banner, banner,
plugins: [fileUrlPlugin, gitHashPlugin, gitRemotePlugin, stylePlugin], plugins: [fileUrlPlugin, gitHashPlugin, gitRemotePlugin, stylePlugin],
@ -310,4 +283,19 @@ export const commonOpts = {
jsxFragment: "VencordFragment", jsxFragment: "VencordFragment",
// Work around https://github.com/evanw/esbuild/issues/2460 // Work around https://github.com/evanw/esbuild/issues/2460
tsconfig: "./scripts/build/tsconfig.esbuild.json" tsconfig: "./scripts/build/tsconfig.esbuild.json"
}; } satisfies BuildOptions;
const builds = [] as BuildOptions[];
export function addBuild(options: BuildOptions) {
builds.push(options);
}
export async function buildOrWatchAll() {
if (watch) {
const contexts = await Promise.all(builds.map(context));
await Promise.all(contexts.map(ctx => ctx.watch()));
} else {
await Promise.all(builds.map(build));
}
}

View file

@ -117,7 +117,7 @@ export default definePlugin({
wrapSort(comparator: Function, row: any) { wrapSort(comparator: Function, row: any) {
return row.type === 5 return row.type === 5
? -UserAffinitiesStore.getUserAffinity(row.user.id)?.affinity ?? 0 ? -(UserAffinitiesStore.getUserAffinity(row.user.id)?.affinity ?? 0)
: comparator(row); : comparator(row);
}, },

View file

@ -299,7 +299,7 @@ export const lazyWebpackSearchHistory = [] as Array<["find" | "findByProps" | "f
* Note that the example below exists already as an api, see {@link findByPropsLazy} * Note that the example below exists already as an api, see {@link findByPropsLazy}
* @example const mod = proxyLazy(() => findByProps("blah")); console.log(mod.blah); * @example const mod = proxyLazy(() => findByProps("blah")); console.log(mod.blah);
*/ */
export function proxyLazyWebpack<T = any>(factory: () => any, attempts?: number) { export function proxyLazyWebpack<T = any>(factory: () => T, attempts?: number) {
if (IS_REPORTER) lazyWebpackSearchHistory.push(["proxyLazyWebpack", [factory]]); if (IS_REPORTER) lazyWebpackSearchHistory.push(["proxyLazyWebpack", [factory]]);
return proxyLazy<T>(factory, attempts); return proxyLazy<T>(factory, attempts);