mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-12-29 11:26:13 +08:00
refactor: use virtual module for env-config (@fehmer) (#7095)
This commit is contained in:
parent
556208efa2
commit
6adfcb092d
18 changed files with 99 additions and 78 deletions
61
frontend/scripts/env-config.ts
Normal file
61
frontend/scripts/env-config.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import { Plugin } from "vite";
|
||||
import { EnvConfig } from "virtual:env-config";
|
||||
|
||||
const virtualModuleId = "virtual:env-config";
|
||||
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
||||
|
||||
const developmentConfig: EnvConfig = {
|
||||
isDevelopment: true,
|
||||
backendUrl: fallbackEnv("BACKEND_URL", "http://localhost:5005"),
|
||||
clientVersion: "DEVELOPMENT_CLIENT",
|
||||
recaptchaSiteKey: "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI",
|
||||
quickLoginEmail: process.env["QUICK_LOGIN_EMAIL"],
|
||||
quickLoginPassword: process.env["QUICK_LOGIN_PASSWORD"],
|
||||
};
|
||||
const productionConfig: Omit<EnvConfig, "clientVersion"> = {
|
||||
isDevelopment: false,
|
||||
backendUrl: fallbackEnv("BACKEND_URL", "https://api.monkeytype.com"),
|
||||
recaptchaSiteKey: process.env["RECAPTCHA_SITE_KEY"] ?? "",
|
||||
quickLoginEmail: undefined,
|
||||
quickLoginPassword: undefined,
|
||||
};
|
||||
|
||||
export function envConfig(
|
||||
options:
|
||||
| {
|
||||
isDevelopment: true;
|
||||
}
|
||||
| {
|
||||
isDevelopment: false;
|
||||
clientVersion: string;
|
||||
}
|
||||
): Plugin {
|
||||
return {
|
||||
name: "virtual-env-config",
|
||||
resolveId(id) {
|
||||
if (id === virtualModuleId) return resolvedVirtualModuleId;
|
||||
return;
|
||||
},
|
||||
load(id) {
|
||||
if (id === resolvedVirtualModuleId) {
|
||||
const envConfig = options.isDevelopment
|
||||
? developmentConfig
|
||||
: {
|
||||
...productionConfig,
|
||||
clientVersion: options.clientVersion,
|
||||
};
|
||||
|
||||
return `
|
||||
export const envConfig = ${JSON.stringify(envConfig)};
|
||||
`;
|
||||
}
|
||||
return;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function fallbackEnv(envVariable: string, fallback: string): string {
|
||||
const value = process.env[envVariable];
|
||||
if (value === null || value === undefined || value === "") return fallback;
|
||||
return value;
|
||||
}
|
||||
|
|
@ -5,9 +5,8 @@ import { createHash } from "crypto";
|
|||
|
||||
const virtualModuleId = "virtual:language-hashes";
|
||||
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
||||
let skip = false;
|
||||
|
||||
export function languageHashes(): Plugin {
|
||||
export function languageHashes(options?: { skip: boolean }): Plugin {
|
||||
return {
|
||||
name: "virtual-language-hashes",
|
||||
resolveId(id) {
|
||||
|
|
@ -16,19 +15,17 @@ export function languageHashes(): Plugin {
|
|||
},
|
||||
load(id) {
|
||||
if (id === resolvedVirtualModuleId) {
|
||||
const hashes: Record<string, string> = skip ? {} : getHashes();
|
||||
if (options?.skip) {
|
||||
console.log("Skipping language hashing in dev environment.");
|
||||
}
|
||||
|
||||
const hashes: Record<string, string> = options?.skip ? {} : getHashes();
|
||||
return `
|
||||
export const languageHashes = ${JSON.stringify(hashes)};
|
||||
`;
|
||||
}
|
||||
return;
|
||||
},
|
||||
configResolved(resolvedConfig) {
|
||||
if (resolvedConfig?.define?.["IS_DEVELOPMENT"] === "true") {
|
||||
skip = true;
|
||||
console.log("Skipping language hashing in dev environment.");
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
tsRestFetchApi,
|
||||
type ApiFetcherArgs,
|
||||
} from "@ts-rest/core";
|
||||
import { envConfig } from "../../constants/env-config";
|
||||
import { envConfig } from "virtual:env-config";
|
||||
import { getIdToken } from "../../firebase";
|
||||
import {
|
||||
COMPATIBILITY_CHECK,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { envConfig } from "../constants/env-config";
|
||||
import { envConfig } from "virtual:env-config";
|
||||
import { buildClient } from "./adapters/ts-rest-adapter";
|
||||
import { contract } from "@monkeytype/contracts";
|
||||
import { devContract } from "@monkeytype/contracts/dev";
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
type Config = {
|
||||
backendUrl: string;
|
||||
isDevelopment: boolean;
|
||||
clientVersion: string;
|
||||
recaptchaSiteKey: string;
|
||||
quickLoginEmail: string | undefined;
|
||||
quickLoginPassword: string | undefined;
|
||||
};
|
||||
|
||||
//@ts-expect-error these get replaced by vite
|
||||
const backendUrl = BACKEND_URL;
|
||||
// @ts-expect-error ---
|
||||
const isDevelopment = IS_DEVELOPMENT;
|
||||
// @ts-expect-error ---
|
||||
const clientVersion = CLIENT_VERSION;
|
||||
// @ts-expect-error ---
|
||||
const recaptchaSiteKey = RECAPTCHA_SITE_KEY;
|
||||
// @ts-expect-error ---
|
||||
const quickLoginEmail = QUICK_LOGIN_EMAIL;
|
||||
// @ts-expect-error ---
|
||||
const quickLoginPassword = QUICK_LOGIN_PASSWORD;
|
||||
|
||||
export const envConfig: Config = {
|
||||
backendUrl,
|
||||
isDevelopment,
|
||||
clientVersion,
|
||||
recaptchaSiteKey,
|
||||
quickLoginEmail,
|
||||
quickLoginPassword,
|
||||
};
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
import { envConfig } from "../constants/env-config";
|
||||
import { envConfig } from "virtual:env-config";
|
||||
const siteKey = envConfig.recaptchaSiteKey;
|
||||
|
||||
const captchas: Record<string, number> = {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { envConfig } from "../constants/env-config";
|
||||
import { envConfig } from "virtual:env-config";
|
||||
|
||||
$("#nocss .requestedStylesheets").html(
|
||||
"Requested stylesheets:<br>" +
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import * as Commandline from "../commandline/commandline";
|
|||
import * as SupportPopup from "../modals/support";
|
||||
import * as ContactModal from "../modals/contact";
|
||||
import * as VersionHistoryModal from "../modals/version-history";
|
||||
import { envConfig } from "../constants/env-config";
|
||||
import { envConfig } from "virtual:env-config";
|
||||
import { COMPATIBILITY_CHECK } from "@monkeytype/contracts";
|
||||
import { lastSeenServerCompatibility } from "../ape/adapters/ts-rest-adapter";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { envConfig } from "../constants/env-config";
|
||||
import { envConfig } from "virtual:env-config";
|
||||
import AnimatedModal from "../utils/animated-modal";
|
||||
import { showPopup } from "./simple-modals";
|
||||
import * as Notifications from "../elements/notifications";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { envConfig } from "./constants/env-config";
|
||||
import { envConfig } from "virtual:env-config";
|
||||
|
||||
async function getSentry(): Promise<typeof import("@sentry/browser")> {
|
||||
return await import("@sentry/browser");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import * as Loader from "../elements/loader";
|
||||
import { envConfig } from "../constants/env-config";
|
||||
import { envConfig } from "virtual:env-config";
|
||||
import { lastElementFromArray } from "./arrays";
|
||||
import { Config } from "@monkeytype/schemas/configs";
|
||||
import { Mode, Mode2, PersonalBests } from "@monkeytype/schemas/shared";
|
||||
|
|
|
|||
12
frontend/src/ts/virtual-env-config.d.ts
vendored
Normal file
12
frontend/src/ts/virtual-env-config.d.ts
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
export type EnvConfig = {
|
||||
backendUrl: string;
|
||||
isDevelopment: boolean;
|
||||
clientVersion: string;
|
||||
recaptchaSiteKey: string;
|
||||
quickLoginEmail: string | undefined;
|
||||
quickLoginPassword: string | undefined;
|
||||
};
|
||||
|
||||
declare module "virtual:env-config" {
|
||||
export const envConfig: EnvConfig;
|
||||
}
|
||||
|
|
@ -9,7 +9,8 @@
|
|||
"target": "ES6",
|
||||
"noEmit": true,
|
||||
"paths": {
|
||||
"virtual:language-hashes": ["./src/ts/module.d.ts"]
|
||||
"virtual:language-hashes": ["./src/ts/virtual-language-hashes.d.ts"],
|
||||
"virtual:env-config": ["./src/ts/virtual-env-config.d.ts"]
|
||||
}
|
||||
},
|
||||
"include": ["./src/**/*.ts", "./scripts/**/*.ts"],
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@ import { checker } from "vite-plugin-checker";
|
|||
import Inspect from "vite-plugin-inspect";
|
||||
import path from "node:path";
|
||||
import { getFontsConig } from "./vite.config";
|
||||
import { envConfig } from "./scripts/env-config";
|
||||
import { languageHashes } from "./scripts/language-hashes";
|
||||
|
||||
/** @type {import("vite").UserConfig} */
|
||||
export default {
|
||||
plugins: [
|
||||
envConfig({ isDevelopment: true }),
|
||||
languageHashes({ skip: true }),
|
||||
checker({
|
||||
typescript: {
|
||||
tsconfigPath: path.resolve(__dirname, "./tsconfig.json"),
|
||||
|
|
@ -32,18 +36,6 @@ export default {
|
|||
},
|
||||
},
|
||||
},
|
||||
define: {
|
||||
BACKEND_URL: JSON.stringify(
|
||||
process.env.BACKEND_URL || "http://localhost:5005"
|
||||
),
|
||||
IS_DEVELOPMENT: JSON.stringify(true),
|
||||
CLIENT_VERSION: JSON.stringify("DEVELOPMENT_CLIENT"),
|
||||
RECAPTCHA_SITE_KEY: JSON.stringify(
|
||||
"6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
|
||||
),
|
||||
QUICK_LOGIN_EMAIL: JSON.stringify(process.env.QUICK_LOGIN_EMAIL),
|
||||
QUICK_LOGIN_PASSWORD: JSON.stringify(process.env.QUICK_LOGIN_PASSWORD),
|
||||
},
|
||||
build: {
|
||||
outDir: "../dist",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,12 +6,10 @@ import PROD_CONFIG from "./vite.config.prod";
|
|||
import DEV_CONFIG from "./vite.config.dev";
|
||||
import MagicString from "magic-string";
|
||||
import { Fonts } from "./src/ts/constants/fonts";
|
||||
import { languageHashes } from "./scripts/language-hashes";
|
||||
|
||||
/** @type {import("vite").UserConfig} */
|
||||
const BASE_CONFIG = {
|
||||
plugins: [
|
||||
languageHashes(),
|
||||
{
|
||||
name: "simple-jquery-inject",
|
||||
async transform(src, id) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ import {
|
|||
import { ViteMinifyPlugin } from "vite-plugin-minify";
|
||||
import { sentryVitePlugin } from "@sentry/vite-plugin";
|
||||
import { getFontsConig } from "./vite.config";
|
||||
import { envConfig } from "./scripts/env-config";
|
||||
import { languageHashes } from "./scripts/language-hashes";
|
||||
|
||||
function pad(numbers, maxLength, fillString) {
|
||||
return numbers.map((number) =>
|
||||
|
|
@ -59,6 +61,8 @@ function sassList(values) {
|
|||
/** @type {import("vite").UserConfig} */
|
||||
export default {
|
||||
plugins: [
|
||||
envConfig({ isDevelopment: false, clientVersion: CLIENT_VERSION }),
|
||||
languageHashes(),
|
||||
{
|
||||
name: "vite-plugin-fontawesome-subset",
|
||||
apply: "build",
|
||||
|
|
@ -311,17 +315,6 @@ export default {
|
|||
},
|
||||
},
|
||||
},
|
||||
define: {
|
||||
BACKEND_URL: JSON.stringify(
|
||||
process.env.BACKEND_URL || "https://api.monkeytype.com"
|
||||
),
|
||||
IS_DEVELOPMENT: JSON.stringify(false),
|
||||
CLIENT_VERSION: JSON.stringify(CLIENT_VERSION),
|
||||
RECAPTCHA_SITE_KEY: JSON.stringify(process.env.RECAPTCHA_SITE_KEY),
|
||||
QUICK_LOGIN_EMAIL: undefined,
|
||||
QUICK_LOGIN_PASSWORD: undefined,
|
||||
},
|
||||
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { defineConfig } from "vitest/config";
|
||||
import { languageHashes } from "./scripts/language-hashes";
|
||||
import { envConfig } from "./scripts/env-config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
|
|
@ -19,5 +20,5 @@ export default defineConfig({
|
|||
},
|
||||
},
|
||||
|
||||
plugins: [languageHashes()],
|
||||
plugins: [languageHashes({ skip: true }), envConfig({ isDevelopment: true })],
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue