2024-02-22 09:24:20 +08:00
|
|
|
import { defineConfig, splitVendorChunkPlugin, mergeConfig } 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";
|
|
|
|
import { VitePWA } from "vite-plugin-pwa";
|
|
|
|
import replace from "vite-plugin-filter-replace";
|
|
|
|
import Inspect from "vite-plugin-inspect";
|
|
|
|
import autoprefixer from "autoprefixer";
|
|
|
|
import "dotenv/config";
|
|
|
|
|
|
|
|
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("_");
|
|
|
|
|
2024-02-28 21:17:09 +08:00
|
|
|
try {
|
|
|
|
const commitHash = childProcess
|
|
|
|
.execSync("git rev-parse --short HEAD")
|
|
|
|
.toString();
|
2024-02-22 09:24:20 +08:00
|
|
|
|
2024-02-28 21:17:09 +08:00
|
|
|
return `${version}.${commitHash}`;
|
|
|
|
} catch (e) {
|
|
|
|
return `${version}.unknown-hash`;
|
|
|
|
}
|
2024-02-22 09:24:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/** @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)) {
|
|
|
|
//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";`)) {
|
|
|
|
return src.replace(
|
|
|
|
/("use strict";)/,
|
2024-03-04 07:07:33 +08:00
|
|
|
`$1import $ from "jquery";`
|
2024-02-22 09:24:20 +08:00
|
|
|
);
|
|
|
|
} else {
|
2024-03-04 07:07:33 +08:00
|
|
|
return `import $ from "jquery";${src}`;
|
2024-02-22 09:24:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
checker({
|
|
|
|
typescript: {
|
|
|
|
root: path.resolve(__dirname, "./"),
|
|
|
|
},
|
|
|
|
eslint: {
|
|
|
|
lintCommand: `eslint "${path.resolve(__dirname, "./src/ts/**/*.ts")}"`,
|
|
|
|
},
|
|
|
|
overlay: {
|
|
|
|
initialIsOpen: false,
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
injectHTML(),
|
|
|
|
Inspect(),
|
|
|
|
],
|
|
|
|
server: {
|
2024-02-28 21:17:09 +08:00
|
|
|
open: process.env.SERVER_OPEN !== "false",
|
2024-02-22 09:24:20 +08:00
|
|
|
port: 3000,
|
|
|
|
host: process.env.BACKEND_URL !== undefined,
|
|
|
|
},
|
|
|
|
root: "src",
|
|
|
|
publicDir: "../static",
|
|
|
|
css: {
|
|
|
|
devSourcemap: true,
|
|
|
|
postcss: {
|
|
|
|
plugins: [autoprefixer({})],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
envDir: "../",
|
|
|
|
build: {
|
|
|
|
emptyOutDir: true,
|
|
|
|
outDir: "../dist",
|
|
|
|
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"),
|
2024-02-24 03:43:12 +08:00
|
|
|
404: path.resolve(__dirname, "src/404.html"),
|
2024-02-22 09:24:20 +08:00
|
|
|
},
|
|
|
|
output: {
|
|
|
|
assetFileNames: (assetInfo) => {
|
|
|
|
let extType = assetInfo.name.split(".").at(1);
|
|
|
|
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
|
|
|
|
extType = "images";
|
|
|
|
}
|
|
|
|
return `${extType}/[name].[hash][extname]`;
|
|
|
|
},
|
|
|
|
chunkFileNames: "js/[name].[hash].js",
|
|
|
|
entryFileNames: "js/[name].[hash].js",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// resolve: {
|
|
|
|
// alias: {
|
|
|
|
// "/src": path.resolve(process.cwd(), "src"),
|
|
|
|
// $: "jquery",
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
define: {
|
|
|
|
BACKEND_URL: JSON.stringify(
|
|
|
|
process.env.BACKEND_URL || "http://localhost:5005"
|
|
|
|
),
|
|
|
|
IS_DEVELOPMENT: JSON.stringify(true),
|
|
|
|
CLIENT_VERSION: JSON.stringify("DEVELOPMENT_CLIENT"),
|
2024-02-27 07:49:51 +08:00
|
|
|
RECAPTCHA_SITE_KEY: JSON.stringify(
|
|
|
|
"6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
|
|
|
|
),
|
2024-02-22 09:24:20 +08:00
|
|
|
},
|
|
|
|
optimizeDeps: {
|
|
|
|
include: ["jquery"],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
/** @type {import("vite").UserConfig} */
|
|
|
|
const BUILD_CONFIG = {
|
|
|
|
plugins: [
|
|
|
|
splitVendorChunkPlugin(),
|
|
|
|
VitePWA({
|
|
|
|
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: ["**/.*"],
|
2024-02-25 20:38:15 +08:00
|
|
|
globPatterns: [],
|
|
|
|
navigateFallback: "",
|
2024-02-22 09:24:20 +08:00
|
|
|
runtimeCaching: [
|
|
|
|
{
|
2024-03-08 05:08:29 +08:00
|
|
|
urlPattern: (options) => {
|
|
|
|
const isApi = options.url.hostname === "api.monkeytype.com";
|
|
|
|
return options.sameOrigin && !isApi;
|
2024-02-22 09:24:20 +08:00
|
|
|
},
|
|
|
|
handler: "NetworkFirst",
|
|
|
|
options: {},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
replace([
|
|
|
|
{
|
|
|
|
filter: /firebase\.ts$/,
|
|
|
|
replace: {
|
|
|
|
from: /\.\/constants\/firebase-config/gi,
|
|
|
|
to: "./constants/firebase-config-live",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]),
|
|
|
|
],
|
|
|
|
define: {
|
2024-03-12 19:02:13 +08:00
|
|
|
BACKEND_URL: JSON.stringify(
|
|
|
|
process.env.BACKEND_URL || "https://api.monkeytype.com"
|
|
|
|
),
|
2024-02-22 09:24:20 +08:00
|
|
|
IS_DEVELOPMENT: JSON.stringify(false),
|
|
|
|
CLIENT_VERSION: JSON.stringify(buildClientVersion()),
|
2024-02-27 07:49:51 +08:00
|
|
|
RECAPTCHA_SITE_KEY: JSON.stringify(process.env.RECAPTCHA_SITE_KEY),
|
2024-02-22 09:24:20 +08:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
export default defineConfig(({ command }) => {
|
|
|
|
if (command === "build") {
|
2024-02-27 07:49:51 +08:00
|
|
|
if (process.env.RECAPTCHA_SITE_KEY === undefined) {
|
|
|
|
throw new Error(".env: RECAPTCHA_SITE_KEY is not defined");
|
|
|
|
}
|
2024-02-22 09:24:20 +08:00
|
|
|
return mergeConfig(BASE_CONFIG, BUILD_CONFIG);
|
|
|
|
} else {
|
|
|
|
return BASE_CONFIG;
|
|
|
|
}
|
|
|
|
});
|