monkeytype/frontend/vite.config.prod.js
2024-07-27 18:10:08 +02:00

207 lines
5.8 KiB
JavaScript

import { fontawesomeSubset } from "fontawesome-subset";
import { getFontawesomeConfig } from "./scripts/fontawesome";
import { generatePreviewFonts } from "./scripts/font-preview";
import { VitePWA } from "vite-plugin-pwa";
import replace from "vite-plugin-filter-replace";
import path from "node:path";
import { splitVendorChunkPlugin } from "vite";
import childProcess from "child_process";
import { checker } from "vite-plugin-checker";
import { writeFileSync } from "fs";
function pad(numbers, maxLength, fillString) {
return numbers.map((number) =>
number.toString().padStart(maxLength, fillString)
);
}
function buildClientVersion() {
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`;
}
}
/** Enable for font awesome v6 */
/*
function sassList(values) {
return values.map((it) => `"${it}"`).join(",");
}
*/
/** @type {import("vite").UserConfig} */
export default {
plugins: [
{
name: "vite-plugin-fontawesome-subset",
apply: "build",
buildStart() {
const fontawesomeClasses = getFontawesomeConfig();
fontawesomeSubset(fontawesomeClasses, "src/webfonts-generated", {
targetFormats: ["woff2"],
});
},
},
{
name: "generate-version-json",
apply: "build",
closeBundle() {
const version = buildClientVersion();
const versionJson = JSON.stringify({ version });
const versionPath = path.resolve(__dirname, "dist/version.json");
writeFileSync(versionPath, versionJson);
},
},
{
name: "vite-plugin-webfonts-preview",
apply: "build",
buildStart() {
generatePreviewFonts();
},
},
checker({
typescript: {
tsconfigPath: path.resolve(__dirname, "./tsconfig.json"),
},
}),
splitVendorChunkPlugin(),
VitePWA({
injectRegister: "networkfirst",
registerType: "autoUpdate",
manifest: {
short_name: "Monkeytype",
name: "Monkeytype",
start_url: "/",
icons: [
{
src: "/images/icons/maskable_icon_x512.png",
sizes: "512x512",
type: "image/png",
purpose: "maskable",
},
{
src: "/images/icons/general_icon_x512.png",
sizes: "512x512",
type: "image/png",
purpose: "any",
},
],
background_color: "#323437",
display: "standalone",
theme_color: "#323437",
},
manifestFilename: "manifest.json",
workbox: {
clientsClaim: true,
cleanupOutdatedCaches: true,
globIgnores: ["**/.*"],
globPatterns: [],
navigateFallback: "",
runtimeCaching: [
{
urlPattern: (options) => {
const isApi = options.url.hostname === "api.monkeytype.com";
return options.sameOrigin && !isApi;
},
handler: "NetworkFirst",
options: {},
},
{
urlPattern: (options) => {
//disable caching for version.json
return options.url.pathname === "/version.json";
},
handler: "NetworkOnly",
options: {},
},
],
},
}),
replace([
{
filter: /firebase\.ts$/,
replace: {
from: /\.\/constants\/firebase-config/gi,
to: "./constants/firebase-config-live",
},
},
]),
],
build: {
emptyOutDir: true,
outDir: "../dist",
assetsInlineLimit: 0, //dont inline small files as data
rollupOptions: {
input: {
monkeytype: path.resolve(__dirname, "src/index.html"),
email: path.resolve(__dirname, "src/email-handler.html"),
privacy: path.resolve(__dirname, "src/privacy-policy.html"),
security: path.resolve(__dirname, "src/security-policy.html"),
terms: path.resolve(__dirname, "src/terms-of-service.html"),
404: path.resolve(__dirname, "src/404.html"),
},
output: {
assetFileNames: (assetInfo) => {
let extType = assetInfo.name.split(".").at(1);
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
extType = "images";
}
if (/\.(woff|woff2|eot|ttf|otf)$/.test(assetInfo.name)) {
return `webfonts/[name]-[hash].${extType}`;
}
return `${extType}/[name].[hash][extname]`;
},
chunkFileNames: "js/[name].[hash].js",
entryFileNames: "js/[name].[hash].js",
},
},
},
define: {
BACKEND_URL: JSON.stringify(
process.env.BACKEND_URL || "https://api.monkeytype.com"
),
IS_DEVELOPMENT: JSON.stringify(false),
CLIENT_VERSION: JSON.stringify(buildClientVersion()),
RECAPTCHA_SITE_KEY: JSON.stringify(process.env.RECAPTCHA_SITE_KEY),
QUICK_LOGIN_EMAIL: undefined,
QUICK_LOGIN_PASSWORD: undefined,
},
/** Enable for font awesome v6 */
/*preprocessorOptions: {
scss: {
additionalData(source, fp) {
if (fp.endsWith("index.scss")) {
const fontawesomeClasses = getFontawesomeConfig();
return `
//inject variables into sass context
$fontawesomeBrands: ${sassList(
fontawesomeClasses.brands
)};
$fontawesomeSolid: ${sassList(fontawesomeClasses.solid)};
${source}`;
} else {
return source;
}
},
},
},*/
};