mirror of
				https://github.com/monkeytypegame/monkeytype.git
				synced 2025-10-31 03:08:29 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			206 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			206 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;
 | |
|         }
 | |
|       },
 | |
|     },
 | |
|   },*/
 | |
| };
 |