mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-12-11 13:57:28 +08:00
build: combine vite config into a single file (@fehmer) (#7190)
- **build: replace dotenv with vite env variables (@fehmer)** - **build: combine vite config into a single file (@fehmer)** --------- Co-authored-by: Miodec <jack@monkeytype.com>
This commit is contained in:
parent
b746ef844e
commit
8cce5bfc7e
11 changed files with 280 additions and 268 deletions
2
.github/labeler.yml
vendored
2
.github/labeler.yml
vendored
|
|
@ -18,4 +18,4 @@ packages:
|
|||
- any: ["packages/**/*"]
|
||||
|
||||
local dev:
|
||||
- any: ["**/turbo.json", "**/tsconfig.json", "**/knip.json", "**/.prettierrc", "**/.oxlintrc.json", "**/.eslintrc.cjs", "**/vite.config.dev.js"]
|
||||
- any: ["**/turbo.json", "**/tsconfig.json", "**/knip.json", "**/.prettierrc", "**/.oxlintrc.json", "**/.eslintrc.cjs"]
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@
|
|||
"@vitest/coverage-v8": "4.0.8",
|
||||
"autoprefixer": "10.4.20",
|
||||
"concurrently": "8.2.2",
|
||||
"dotenv": "16.4.5",
|
||||
"eslint": "8.57.1",
|
||||
"eslint-plugin-compat": "6.0.2",
|
||||
"firebase-tools": "13.15.1",
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@
|
|||
"virtual:env-config": ["./src/ts/types/virtual-env-config.d.ts"]
|
||||
}
|
||||
},
|
||||
"include": ["./src/**/*.ts", "./scripts/**/*.ts", "vite-plugins/**/*.ts"],
|
||||
"include": [
|
||||
"./src/**/*.ts",
|
||||
"./scripts/**/*.ts",
|
||||
"vite-plugins/**/*.ts",
|
||||
"vite.config.ts"
|
||||
],
|
||||
"exclude": ["node_modules", "build", "setup-tests.ts", "**/*.spec.ts"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +1,14 @@
|
|||
import { Plugin } from "vite";
|
||||
import { EnvConfig } from "virtual:env-config";
|
||||
import { config as dotenvConfig } from "dotenv";
|
||||
|
||||
const envFile =
|
||||
process.env["NODE_ENV"] === "production" ? ".env.production" : ".env";
|
||||
dotenvConfig({ path: envFile });
|
||||
|
||||
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 {
|
||||
export function envConfig(options: {
|
||||
isDevelopment: boolean;
|
||||
clientVersion: string;
|
||||
env: Record<string, string>;
|
||||
}): Plugin {
|
||||
return {
|
||||
name: "virtual-env-config",
|
||||
resolveId(id) {
|
||||
|
|
@ -43,13 +17,31 @@ export function envConfig(
|
|||
},
|
||||
load(id) {
|
||||
if (id === resolvedVirtualModuleId) {
|
||||
const envConfig = options.isDevelopment
|
||||
? developmentConfig
|
||||
: {
|
||||
...productionConfig,
|
||||
clientVersion: options.clientVersion,
|
||||
};
|
||||
const devConfig: EnvConfig = {
|
||||
isDevelopment: true,
|
||||
backendUrl: fallback(
|
||||
options.env["BACKEND_URL"],
|
||||
"http://localhost:5005",
|
||||
),
|
||||
clientVersion: options.clientVersion,
|
||||
recaptchaSiteKey: "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI",
|
||||
quickLoginEmail: options.env["QUICK_LOGIN_EMAIL"],
|
||||
quickLoginPassword: options.env["QUICK_LOGIN_PASSWORD"],
|
||||
};
|
||||
|
||||
const prodConfig: EnvConfig = {
|
||||
isDevelopment: false,
|
||||
backendUrl: fallback(
|
||||
options.env["BACKEND_URL"],
|
||||
"https://api.monkeytype.com",
|
||||
),
|
||||
recaptchaSiteKey: options.env["RECAPTCHA_SITE_KEY"] ?? "",
|
||||
quickLoginEmail: undefined,
|
||||
quickLoginPassword: undefined,
|
||||
clientVersion: options.clientVersion,
|
||||
};
|
||||
|
||||
const envConfig = options.isDevelopment ? devConfig : prodConfig;
|
||||
return `
|
||||
export const envConfig = ${JSON.stringify(envConfig)};
|
||||
`;
|
||||
|
|
@ -59,8 +51,7 @@ export function envConfig(
|
|||
};
|
||||
}
|
||||
|
||||
function fallbackEnv(envVariable: string, fallback: string): string {
|
||||
const value = process.env[envVariable];
|
||||
function fallback(value: string | undefined | null, fallback: string): string {
|
||||
if (value === null || value === undefined || value === "") return fallback;
|
||||
return value;
|
||||
}
|
||||
|
|
|
|||
29
frontend/vite-plugins/jquery-inject.ts
Normal file
29
frontend/vite-plugins/jquery-inject.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { Plugin } from "vite";
|
||||
import MagicString from "magic-string";
|
||||
|
||||
export function jqueryInject(): Plugin {
|
||||
return {
|
||||
name: "simple-jquery-inject",
|
||||
async transform(src: string, id: string) {
|
||||
if (id.endsWith(".ts")) {
|
||||
//check if file has a jQuery or $() call
|
||||
if (/(?:jQuery|\$)\([^)]*\)/.test(src)) {
|
||||
const s = new MagicString(src);
|
||||
|
||||
//if file has "use strict"; at the top, add it below that line, if not, add it at the very top
|
||||
if (src.startsWith(`"use strict";`)) {
|
||||
s.appendRight(12, `\nimport $ from "jquery";`);
|
||||
} else {
|
||||
s.prepend(`import $ from "jquery";`);
|
||||
}
|
||||
|
||||
return {
|
||||
code: s.toString(),
|
||||
map: s.generateMap({ hires: true, source: id }),
|
||||
};
|
||||
}
|
||||
}
|
||||
return;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ export function languageHashes(options?: { skip: boolean }): Plugin {
|
|||
load(id) {
|
||||
if (id === resolvedVirtualModuleId) {
|
||||
if (options?.skip) {
|
||||
console.log("Skipping language hashing in dev environment.");
|
||||
console.log("Skipping language hashing.");
|
||||
}
|
||||
|
||||
const hashes: Record<string, string> = options?.skip ? {} : getHashes();
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
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 "./vite-plugins/env-config";
|
||||
import { languageHashes } from "./vite-plugins/language-hashes";
|
||||
|
||||
/** @type {import("vite").UserConfig} */
|
||||
export default {
|
||||
plugins: [
|
||||
envConfig({ isDevelopment: true }),
|
||||
languageHashes({ skip: true }),
|
||||
checker({
|
||||
typescript: {
|
||||
tsconfigPath: path.resolve(__dirname, "./tsconfig.json"),
|
||||
},
|
||||
oxlint: true,
|
||||
eslint: {
|
||||
lintCommand: `eslint "${path.resolve(__dirname, "./src/ts/**/*.ts")}"`,
|
||||
watchPath: path.resolve(__dirname, "./src/"),
|
||||
},
|
||||
overlay: {
|
||||
initialIsOpen: false,
|
||||
},
|
||||
}),
|
||||
Inspect(),
|
||||
],
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: `
|
||||
$fontAwesomeOverride:"@fortawesome/fontawesome-free/webfonts";
|
||||
$previewFontsPath:"webfonts";
|
||||
$fonts: (${getFontsConig()});
|
||||
`,
|
||||
},
|
||||
},
|
||||
},
|
||||
build: {
|
||||
outDir: "../dist",
|
||||
},
|
||||
};
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
import { defineConfig, mergeConfig } from "vite";
|
||||
import injectHTML from "vite-plugin-html-inject";
|
||||
import autoprefixer from "autoprefixer";
|
||||
import { config as dotenvConfig } from "dotenv";
|
||||
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";
|
||||
|
||||
// Load environment variables based on NODE_ENV
|
||||
const envFile =
|
||||
process.env.NODE_ENV === "production" ? ".env.production" : ".env";
|
||||
dotenvConfig({ path: envFile });
|
||||
|
||||
/** @type {import("vite").UserConfig} */
|
||||
const BASE_CONFIG = {
|
||||
plugins: [
|
||||
{
|
||||
name: "simple-jquery-inject",
|
||||
async transform(src, id) {
|
||||
if (id.endsWith(".ts")) {
|
||||
//check if file has a jQuery or $() call
|
||||
if (/(?:jQuery|\$)\([^)]*\)/.test(src)) {
|
||||
const s = new MagicString(src);
|
||||
|
||||
//if file has "use strict"; at the top, add it below that line, if not, add it at the very top
|
||||
if (src.startsWith(`"use strict";`)) {
|
||||
s.appendRight(12, `\nimport $ from "jquery";`);
|
||||
} else {
|
||||
s.prepend(`import $ from "jquery";`);
|
||||
}
|
||||
|
||||
return {
|
||||
code: s.toString(),
|
||||
map: s.generateMap({ hires: true, source: id }),
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
injectHTML(),
|
||||
],
|
||||
server: {
|
||||
open: process.env.SERVER_OPEN !== "false",
|
||||
port: 3000,
|
||||
host: process.env.BACKEND_URL !== undefined,
|
||||
watch: {
|
||||
//we rebuild the whole contracts package when a file changes
|
||||
//so we only want to watch one file
|
||||
ignored: [/.*\/packages\/contracts\/dist\/(?!configs).*/],
|
||||
},
|
||||
},
|
||||
clearScreen: false,
|
||||
root: "src",
|
||||
publicDir: "../static",
|
||||
css: {
|
||||
devSourcemap: true,
|
||||
postcss: {
|
||||
plugins: [autoprefixer({})],
|
||||
},
|
||||
},
|
||||
envDir: "../",
|
||||
optimizeDeps: {
|
||||
include: ["jquery"],
|
||||
exclude: ["@fortawesome/fontawesome-free"],
|
||||
},
|
||||
};
|
||||
|
||||
export default defineConfig(({ command }) => {
|
||||
if (command === "build") {
|
||||
const envFileName =
|
||||
process.env.NODE_ENV === "production" ? ".env.production" : ".env";
|
||||
if (process.env.RECAPTCHA_SITE_KEY === undefined) {
|
||||
throw new Error(`${envFileName}: RECAPTCHA_SITE_KEY is not defined`);
|
||||
}
|
||||
if (process.env.SENTRY && process.env.SENTRY_AUTH_TOKEN === undefined) {
|
||||
throw new Error(`${envFileName}: SENTRY_AUTH_TOKEN is not defined`);
|
||||
}
|
||||
return mergeConfig(BASE_CONFIG, PROD_CONFIG);
|
||||
} else {
|
||||
return mergeConfig(BASE_CONFIG, DEV_CONFIG);
|
||||
}
|
||||
});
|
||||
|
||||
/** Enable for font awesome v6 */
|
||||
/*
|
||||
function sassList(values) {
|
||||
return values.map((it) => `"${it}"`).join(",");
|
||||
}
|
||||
*/
|
||||
|
||||
export function getFontsConig() {
|
||||
return (
|
||||
"\n" +
|
||||
Object.keys(Fonts)
|
||||
.sort()
|
||||
.map((name) => {
|
||||
const config = Fonts[name];
|
||||
if (config.systemFont === true) return "";
|
||||
return `"${name.replaceAll("_", " ")}": (
|
||||
"src": "${config.fileName}",
|
||||
"weight": ${config.weight ?? 400},
|
||||
),`;
|
||||
})
|
||||
.join("\n") +
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
|
@ -1,70 +1,112 @@
|
|||
import { VitePWA } from "vite-plugin-pwa";
|
||||
import replace from "vite-plugin-filter-replace";
|
||||
import {
|
||||
defineConfig,
|
||||
loadEnv,
|
||||
UserConfig,
|
||||
BuildEnvironmentOptions,
|
||||
PluginOption,
|
||||
Plugin,
|
||||
CSSOptions,
|
||||
} from "vite";
|
||||
import path from "node:path";
|
||||
import injectHTML from "vite-plugin-html-inject";
|
||||
import childProcess from "child_process";
|
||||
import { checker } from "vite-plugin-checker";
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import UnpluginInjectPreload from "unplugin-inject-preload/vite";
|
||||
import { ViteMinifyPlugin } from "vite-plugin-minify";
|
||||
import { sentryVitePlugin } from "@sentry/vite-plugin";
|
||||
import { getFontsConig } from "./vite.config";
|
||||
import autoprefixer from "autoprefixer";
|
||||
import { Fonts } from "./src/ts/constants/fonts";
|
||||
import { fontawesomeSubset } from "./vite-plugins/fontawesome-subset";
|
||||
import { fontPreview } from "./vite-plugins/font-preview";
|
||||
import { envConfig } from "./vite-plugins/env-config";
|
||||
import { languageHashes } from "./vite-plugins/language-hashes";
|
||||
import { minifyJson } from "./vite-plugins/minify-json";
|
||||
import { versionFile } from "./vite-plugins/version-file";
|
||||
import { jqueryInject } from "./vite-plugins/jquery-inject";
|
||||
import { checker } from "vite-plugin-checker";
|
||||
import Inspect from "vite-plugin-inspect";
|
||||
import { ViteMinifyPlugin } from "vite-plugin-minify";
|
||||
import { VitePWA } from "vite-plugin-pwa";
|
||||
import { sentryVitePlugin } from "@sentry/vite-plugin";
|
||||
import replace from "vite-plugin-filter-replace";
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import UnpluginInjectPreload from "unplugin-inject-preload/vite";
|
||||
import { KnownFontName } from "@monkeytype/schemas/fonts";
|
||||
|
||||
function pad(numbers, maxLength, fillString) {
|
||||
return numbers.map((number) =>
|
||||
number.toString().padStart(maxLength, fillString),
|
||||
);
|
||||
}
|
||||
export default defineConfig(({ mode }): UserConfig => {
|
||||
const env = loadEnv(mode, process.cwd(), "");
|
||||
const useSentry = env["SENTRY"] !== undefined;
|
||||
const isDevelopment = mode !== "production";
|
||||
|
||||
const CLIENT_VERSION = (() => {
|
||||
const date = new Date();
|
||||
const versionPrefix = pad(
|
||||
[date.getFullYear(), date.getMonth() + 1, date.getDate()],
|
||||
2,
|
||||
"0",
|
||||
).join(".");
|
||||
const versionSuffix = pad([date.getHours(), date.getMinutes()], 2, "0").join(
|
||||
".",
|
||||
);
|
||||
const version = [versionPrefix, versionSuffix].join("_");
|
||||
|
||||
try {
|
||||
const commitHash = childProcess
|
||||
.execSync("git rev-parse --short HEAD")
|
||||
.toString();
|
||||
|
||||
return `${version}_${commitHash}`.replace(/\n/g, "");
|
||||
} catch (e) {
|
||||
return `${version}_unknown-hash`;
|
||||
if (!isDevelopment) {
|
||||
if (env["RECAPTCHA_SITE_KEY"] === undefined) {
|
||||
throw new Error(`${mode}: RECAPTCHA_SITE_KEY is not defined`);
|
||||
}
|
||||
if (useSentry && env["SENTRY_AUTH_TOKEN"] === undefined) {
|
||||
throw new Error(`${mode}: SENTRY_AUTH_TOKEN is not defined`);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
/** Enable for font awesome v6 */
|
||||
/*
|
||||
function sassList(values) {
|
||||
return values.map((it) => `"${it}"`).join(",");
|
||||
}
|
||||
*/
|
||||
return {
|
||||
plugins: getPlugins({ isDevelopment, useSentry: useSentry, env }),
|
||||
build: getBuildOptions({ enableSourceMaps: useSentry }),
|
||||
css: getCssOptions({ isDevelopment }),
|
||||
server: {
|
||||
open: env["SERVER_OPEN"] !== "false",
|
||||
port: 3000,
|
||||
host: env["BACKEND_URL"] !== undefined,
|
||||
watch: {
|
||||
//we rebuild the whole contracts package when a file changes
|
||||
//so we only want to watch one file
|
||||
ignored: [/.*\/packages\/contracts\/dist\/(?!configs).*/],
|
||||
},
|
||||
},
|
||||
clearScreen: false,
|
||||
root: "src",
|
||||
publicDir: "../static",
|
||||
optimizeDeps: {
|
||||
include: ["jquery"],
|
||||
exclude: ["@fortawesome/fontawesome-free"],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
/** @type {import("vite").UserConfig} */
|
||||
export default {
|
||||
plugins: [
|
||||
envConfig({ isDevelopment: false, clientVersion: CLIENT_VERSION }),
|
||||
languageHashes(),
|
||||
fontawesomeSubset(),
|
||||
versionFile({ clientVersion: CLIENT_VERSION }),
|
||||
fontPreview(),
|
||||
function getPlugins({
|
||||
isDevelopment,
|
||||
env,
|
||||
useSentry,
|
||||
}: {
|
||||
isDevelopment: boolean;
|
||||
env: Record<string, string>;
|
||||
useSentry: boolean;
|
||||
}): PluginOption[] {
|
||||
const clientVersion = getClientVersion(isDevelopment);
|
||||
|
||||
const plugins: PluginOption[] = [
|
||||
envConfig({ isDevelopment, clientVersion, env }),
|
||||
languageHashes({ skip: isDevelopment }),
|
||||
checker({
|
||||
typescript: {
|
||||
tsconfigPath: path.resolve(__dirname, "./tsconfig.json"),
|
||||
},
|
||||
oxlint: isDevelopment,
|
||||
eslint: isDevelopment
|
||||
? {
|
||||
lintCommand: `eslint "${path.resolve(__dirname, "./src/ts/**/*.ts")}"`,
|
||||
watchPath: path.resolve(__dirname, "./src/"),
|
||||
}
|
||||
: false,
|
||||
overlay: {
|
||||
initialIsOpen: false,
|
||||
},
|
||||
}),
|
||||
ViteMinifyPlugin({}),
|
||||
jqueryInject(),
|
||||
injectHTML(),
|
||||
];
|
||||
|
||||
const devPlugins: PluginOption[] = [Inspect()];
|
||||
|
||||
const prodPlugins: PluginOption[] = [
|
||||
fontPreview(),
|
||||
fontawesomeSubset(),
|
||||
versionFile({ clientVersion }),
|
||||
ViteMinifyPlugin(),
|
||||
VitePWA({
|
||||
// injectRegister: "networkfirst",
|
||||
injectRegister: null,
|
||||
|
|
@ -118,16 +160,16 @@ export default {
|
|||
],
|
||||
},
|
||||
}),
|
||||
process.env.SENTRY
|
||||
? sentryVitePlugin({
|
||||
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||
useSentry
|
||||
? (sentryVitePlugin({
|
||||
authToken: env["SENTRY_AUTH_TOKEN"],
|
||||
org: "monkeytype",
|
||||
project: "frontend",
|
||||
release: {
|
||||
name: CLIENT_VERSION,
|
||||
name: clientVersion,
|
||||
},
|
||||
applicationKey: "monkeytype-frontend",
|
||||
})
|
||||
}) as Plugin)
|
||||
: null,
|
||||
replace([
|
||||
{
|
||||
|
|
@ -169,9 +211,20 @@ export default {
|
|||
injectTo: "head-prepend",
|
||||
}),
|
||||
minifyJson(),
|
||||
],
|
||||
build: {
|
||||
sourcemap: process.env.SENTRY,
|
||||
];
|
||||
|
||||
return [...plugins, ...(isDevelopment ? devPlugins : prodPlugins)].filter(
|
||||
(it) => it !== null,
|
||||
);
|
||||
}
|
||||
|
||||
function getBuildOptions({
|
||||
enableSourceMaps,
|
||||
}: {
|
||||
enableSourceMaps: boolean;
|
||||
}): BuildEnvironmentOptions {
|
||||
return {
|
||||
sourcemap: enableSourceMaps,
|
||||
emptyOutDir: true,
|
||||
outDir: "../dist",
|
||||
assetsInlineLimit: 0, //dont inline small files as data
|
||||
|
|
@ -185,8 +238,8 @@ export default {
|
|||
404: path.resolve(__dirname, "src/404.html"),
|
||||
},
|
||||
output: {
|
||||
assetFileNames: (assetInfo) => {
|
||||
let extType = assetInfo.name.split(".").at(1);
|
||||
assetFileNames: (assetInfo: { name: string }) => {
|
||||
let extType = assetInfo.name.split(".").at(1) as string;
|
||||
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
|
||||
extType = "images";
|
||||
}
|
||||
|
|
@ -213,26 +266,50 @@ export default {
|
|||
if (id.includes("node_modules")) {
|
||||
return "vendor";
|
||||
}
|
||||
return;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
css: {
|
||||
} as BuildEnvironmentOptions;
|
||||
}
|
||||
|
||||
function getCssOptions({
|
||||
isDevelopment,
|
||||
}: {
|
||||
isDevelopment: boolean;
|
||||
}): CSSOptions {
|
||||
return {
|
||||
devSourcemap: true,
|
||||
postcss: {
|
||||
plugins: [
|
||||
// @ts-expect-error this is fine
|
||||
autoprefixer({}),
|
||||
],
|
||||
},
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData(source, fp) {
|
||||
if (fp.endsWith("index.scss")) {
|
||||
/** Enable for font awesome v6 */
|
||||
/*
|
||||
const fontawesomeClasses = getFontawesomeConfig();
|
||||
const fontawesomeClasses = getFontawesomeConfig();
|
||||
|
||||
//inject variables into sass context
|
||||
$fontawesomeBrands: ${sassList(
|
||||
fontawesomeClasses.brands
|
||||
)};
|
||||
$fontawesomeSolid: ${sassList(fontawesomeClasses.solid)};
|
||||
*/
|
||||
const fonts = `$fonts: (${getFontsConig()});`;
|
||||
//inject variables into sass context
|
||||
$fontawesomeBrands: ${sassList(
|
||||
fontawesomeClasses.brands
|
||||
)};
|
||||
$fontawesomeSolid: ${sassList(fontawesomeClasses.solid)};
|
||||
*/
|
||||
|
||||
const bypassFonts = isDevelopment
|
||||
? `
|
||||
$fontAwesomeOverride:"@fortawesome/fontawesome-free/webfonts";
|
||||
$previewFontsPath:"webfonts";`
|
||||
: "";
|
||||
const fonts = `
|
||||
${bypassFonts}
|
||||
$fonts: (${getFontsConfig()});
|
||||
`;
|
||||
return `
|
||||
//inject variables into sass context
|
||||
${fonts}
|
||||
|
|
@ -244,5 +321,66 @@ export default {
|
|||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function getFontsConfig(): string {
|
||||
return (
|
||||
"\n" +
|
||||
Object.keys(Fonts)
|
||||
.sort()
|
||||
.map((name: string) => {
|
||||
const config = Fonts[name as KnownFontName];
|
||||
if (config.systemFont === true) return "";
|
||||
return `"${name.replaceAll("_", " ")}": (
|
||||
"src": "${config.fileName}",
|
||||
"weight": ${config.weight ?? 400},
|
||||
),`;
|
||||
})
|
||||
.join("\n") +
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
function pad(
|
||||
numbers: number[],
|
||||
maxLength: number,
|
||||
fillString: string,
|
||||
): string[] {
|
||||
return numbers.map((number) =>
|
||||
number.toString().padStart(maxLength, fillString),
|
||||
);
|
||||
}
|
||||
|
||||
/** Enable for font awesome v6 */
|
||||
/*
|
||||
function sassList(values) {
|
||||
return values.map((it) => `"${it}"`).join(",");
|
||||
}
|
||||
*/
|
||||
|
||||
function getClientVersion(isDevelopment: boolean): string {
|
||||
if (isDevelopment) {
|
||||
return "DEVELOPMENT_CLIENT";
|
||||
}
|
||||
const date = new Date();
|
||||
const versionPrefix = pad(
|
||||
[date.getFullYear(), date.getMonth() + 1, date.getDate()],
|
||||
2,
|
||||
"0",
|
||||
).join(".");
|
||||
const versionSuffix = pad([date.getHours(), date.getMinutes()], 2, "0").join(
|
||||
".",
|
||||
);
|
||||
const version = [versionPrefix, versionSuffix].join("_");
|
||||
|
||||
try {
|
||||
const commitHash = childProcess
|
||||
.execSync("git rev-parse --short HEAD")
|
||||
.toString();
|
||||
|
||||
return `${version}_${commitHash}`.replace(/\n/g, "");
|
||||
} catch (e) {
|
||||
return `${version}_unknown-hash`;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,5 +20,8 @@ export default defineConfig({
|
|||
},
|
||||
},
|
||||
|
||||
plugins: [languageHashes({ skip: true }), envConfig({ isDevelopment: true })],
|
||||
plugins: [
|
||||
languageHashes({ skip: true }),
|
||||
envConfig({ isDevelopment: true, clientVersion: "TESTING", env: {} }),
|
||||
],
|
||||
});
|
||||
|
|
|
|||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
|
|
@ -409,9 +409,6 @@ importers:
|
|||
concurrently:
|
||||
specifier: 8.2.2
|
||||
version: 8.2.2
|
||||
dotenv:
|
||||
specifier: 16.4.5
|
||||
version: 16.4.5
|
||||
eslint:
|
||||
specifier: 8.57.1
|
||||
version: 8.57.1
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue