Skip to content

Commit 7199203

Browse files
committed
Add missing files
1 parent 732b4ba commit 7199203

15 files changed

+3583
-9
lines changed

.gitignore

+8-9
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
*.pyc
33
*.sublime-project
44
*.sublime-workspace
5-
node_modules
6-
test_case.html
7-
npm-debug.log
8-
build
9-
local.log
10-
stats-*.html
11-
.idea/
12-
foo
13-
.vscode
5+
/node_modules
6+
/npm-debug.log
7+
/build
8+
/local.log
9+
/stats-*.html
10+
/.idea/
11+
/foo
12+
/.vscode

tools/build/build.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import fs from "node:fs/promises";
2+
import { buildCss } from "./buildCss.ts";
3+
import { buildJs } from "./buildJs.ts";
4+
import { buildSw } from "./buildSw.ts";
5+
import { copyFiles } from "./copyFiles.ts";
6+
import { generateJsonSchema } from "./generateJsonSchema.ts";
7+
import { getSport } from "../lib/getSport.ts";
8+
import { minifyIndexHtml } from "./minifyIndexHtml.ts";
9+
import { reset } from "./reset.ts";
10+
11+
export const build = async () => {
12+
const sport = getSport();
13+
14+
console.log(`Building ${sport}...`);
15+
16+
await reset();
17+
await copyFiles();
18+
19+
const jsonSchema = generateJsonSchema(sport);
20+
await fs.mkdir("build/files", { recursive: true });
21+
await fs.writeFile(
22+
"build/files/league-schema.json",
23+
JSON.stringify(jsonSchema, null, 2),
24+
);
25+
26+
console.log("Bundling JavaScript files...");
27+
await buildJs();
28+
29+
console.log("Processing CSS/HTML files...");
30+
await buildCss();
31+
await minifyIndexHtml();
32+
33+
console.log("Generating sw.js...");
34+
await buildSw();
35+
};

tools/build/buildCss.ts

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { Buffer } from "node:buffer";
2+
import fs from "node:fs";
3+
import browserslist from "browserslist";
4+
import * as lightningCSS from "lightningcss";
5+
import { PurgeCSS } from "purgecss";
6+
import * as sass from "sass";
7+
import { fileHash } from "./fileHash.ts";
8+
import { replace } from "./replace.ts";
9+
10+
export const buildCss = async (watch: boolean = false) => {
11+
const filenames = ["light", "dark"];
12+
const rawCSS = filenames.map((filename) => {
13+
const sassFilePath = `public/css/${filename}.scss`;
14+
const sassResult = sass.renderSync({
15+
file: sassFilePath,
16+
});
17+
return sassResult.css.toString();
18+
});
19+
20+
const purgeCSSResults = watch
21+
? []
22+
: await new PurgeCSS().purge({
23+
content: ["build/gen/*.js"],
24+
css: rawCSS.map((raw) => ({ raw })),
25+
safelist: {
26+
standard: [/^qc-cmp2-persistent-link$/],
27+
greedy: [
28+
// react-bootstrap stuff
29+
/^modal/,
30+
/^navbar/,
31+
/^popover/,
32+
/^tooltip/,
33+
/^bs-tooltip/,
34+
35+
// For align="end" in react-bootstrap
36+
/^dropdown-menu-end$/,
37+
38+
// flag-icons
39+
/^fi$/,
40+
/^fi-/,
41+
42+
/^dark-select/,
43+
/^bar-graph/,
44+
/^watch-active/,
45+
/^dashboard-top-link-other/,
46+
],
47+
},
48+
});
49+
50+
for (let i = 0; i < filenames.length; i++) {
51+
const filename = filenames[i];
52+
53+
let output;
54+
if (!watch) {
55+
// https://zengm.com/blog/2022/07/investigating-a-tricky-performance-bug/
56+
const DANGER_CSS = ".input-group.has-validation";
57+
if (!rawCSS[i].includes(DANGER_CSS)) {
58+
throw new Error(
59+
`rawCSS no longer contains ${DANGER_CSS} - same problem might exist with another name?`,
60+
);
61+
}
62+
63+
const purgeCSSResult = purgeCSSResults[i].css;
64+
65+
const { code } = lightningCSS.transform({
66+
filename: `${filename}.css`,
67+
code: Buffer.from(purgeCSSResult),
68+
minify: true,
69+
sourceMap: false,
70+
targets: lightningCSS.browserslistToTargets(
71+
browserslist("Chrome >= 75, Firefox >= 78, Safari >= 12.1"),
72+
),
73+
});
74+
75+
output = code.toString();
76+
77+
if (output.includes(DANGER_CSS)) {
78+
throw new Error(`CSS output contains ${DANGER_CSS}`);
79+
}
80+
} else {
81+
output = rawCSS[i];
82+
}
83+
84+
let outFilename;
85+
if (watch) {
86+
outFilename = `build/gen/${filename}.css`;
87+
} else {
88+
const hash = fileHash(output);
89+
outFilename = `build/gen/${filename}-${hash}.css`;
90+
91+
replace({
92+
paths: ["build/index.html"],
93+
replaces: [
94+
{
95+
searchValue: `CSS_HASH_${filename.toUpperCase()}`,
96+
replaceValue: hash,
97+
},
98+
],
99+
});
100+
}
101+
102+
fs.writeFileSync(outFilename, output);
103+
}
104+
};

tools/build/buildJs.ts

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import fs from "node:fs";
2+
import { Worker } from "node:worker_threads";
3+
import { fileHash } from "./fileHash.ts";
4+
import { generateVersionNumber } from "./generateVersionNumber.ts";
5+
import { replace } from "./replace.ts";
6+
import { setTimestamps } from "./setTimestamps.ts";
7+
8+
const versionNumber = generateVersionNumber();
9+
console.log(versionNumber);
10+
11+
export const buildJs = async () => {
12+
const promises = [];
13+
for (const name of ["ui", "worker"]) {
14+
for (const legacy of [false, true]) {
15+
promises.push(
16+
new Promise<void>((resolve) => {
17+
const worker = new Worker(
18+
new URL("buildJsWorker.ts", import.meta.url),
19+
{
20+
workerData: {
21+
legacy,
22+
name,
23+
rev: versionNumber,
24+
},
25+
},
26+
);
27+
28+
worker.on("message", () => {
29+
resolve();
30+
});
31+
}),
32+
);
33+
}
34+
}
35+
await Promise.all(promises);
36+
37+
// Hack because otherwise I'm somehow left with no newline before the souce map URL, which confuses Bugsnag
38+
const replacePaths = fs
39+
.readdirSync("build/gen")
40+
.filter((filename) => filename.endsWith(".js"))
41+
.map((filename) => `build/gen/${filename}`);
42+
replace({
43+
paths: replacePaths,
44+
replaces: [
45+
{
46+
searchValue: ";//# sourceMappingURL",
47+
replaceValue: ";\n//# sourceMappingURL",
48+
},
49+
],
50+
});
51+
52+
setTimestamps(versionNumber);
53+
54+
const jsonFiles = [
55+
"names",
56+
"names-female",
57+
"real-player-data",
58+
"real-player-stats",
59+
];
60+
const replaces = [];
61+
for (const filename of jsonFiles) {
62+
const filePath = `build/gen/${filename}.json`;
63+
if (fs.existsSync(filePath)) {
64+
const string = fs.readFileSync(filePath, "utf8");
65+
const compressed = JSON.stringify(JSON.parse(string));
66+
67+
const hash = fileHash(compressed);
68+
const newFilename = filePath.replace(".json", `-${hash}.json`);
69+
fs.rmSync(filePath);
70+
fs.writeFileSync(newFilename, compressed);
71+
72+
replaces.push({
73+
searchValue: `/gen/${filename}.json`,
74+
replaceValue: `/gen/${filename}-${hash}.json`,
75+
});
76+
}
77+
}
78+
replace({
79+
paths: [
80+
`build/gen/worker-legacy-${versionNumber}.js`,
81+
`build/gen/worker-${versionNumber}.js`,
82+
],
83+
replaces,
84+
});
85+
};

tools/build/buildJsWorker.ts

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { rollup, type ModuleFormat } from "rollup";
2+
import rollupConfig from "../lib/rollupConfig.ts";
3+
import { parentPort, workerData } from "node:worker_threads";
4+
5+
const LODASH_BLACKLIST = [
6+
/^lodash$/,
7+
/^lodash-es/,
8+
9+
// lodash/debounce and lodash/memoize are used by visx
10+
/^lodash\/(?!debounce|memoize)/,
11+
];
12+
13+
const BLACKLIST = {
14+
ui: [...LODASH_BLACKLIST, /\/worker/],
15+
worker: [...LODASH_BLACKLIST, /\/ui/, /^react/],
16+
};
17+
18+
const buildFile = async (
19+
name: "ui" | "worker",
20+
legacy: boolean,
21+
rev: string,
22+
) => {
23+
const bundle = await rollup({
24+
...rollupConfig("production", {
25+
blacklistOptions: BLACKLIST[name],
26+
statsFilename: `stats-${name}${legacy ? "-legacy" : ""}.html`,
27+
legacy,
28+
}),
29+
input: {
30+
[name]: `src/${name}/index.${name === "ui" ? "tsx" : "ts"}`,
31+
},
32+
preserveEntrySignatures: false,
33+
});
34+
35+
let format: ModuleFormat;
36+
if (legacy) {
37+
// ES modules don't work in workers in all the browsers currently supported
38+
// Chrome 80, Firefox 114, Safari 15.5/16.4
39+
format = name === "ui" ? "es" : "iife";
40+
} else {
41+
format = "es";
42+
}
43+
44+
await bundle.write({
45+
compact: true,
46+
format,
47+
indent: false,
48+
sourcemap: true,
49+
entryFileNames: `[name]-${legacy ? "legacy-" : ""}${rev}.js`,
50+
chunkFileNames: `chunk-${legacy ? "legacy-" : ""}[hash].js`,
51+
dir: "build/gen",
52+
});
53+
54+
parentPort!.postMessage("done");
55+
};
56+
57+
const { legacy, name, rev } = workerData;
58+
59+
await buildFile(name, legacy, rev);

0 commit comments

Comments
 (0)