From e4e70acef2ca9f9327704b5d843fac74e5b60d13 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Sat, 1 Mar 2025 17:38:43 +0800 Subject: [PATCH] feat: add desktop specific resolver --- packages/shared/src/env.desktop.ts | 67 +++++++++++++++++++++++++ packages/shared/src/env.mobile.ts | 19 +++++--- packages/shared/src/env.ts | 78 +++++++----------------------- plugins/vite/specific-import.ts | 55 ++++++--------------- 4 files changed, 110 insertions(+), 109 deletions(-) create mode 100644 packages/shared/src/env.desktop.ts diff --git a/packages/shared/src/env.desktop.ts b/packages/shared/src/env.desktop.ts new file mode 100644 index 000000000..9029ce303 --- /dev/null +++ b/packages/shared/src/env.desktop.ts @@ -0,0 +1,67 @@ +import { createEnv } from "@t3-oss/env-core" +import { z } from "zod" + +export const isDev = + "process" in globalThis ? process.env.NODE_ENV === "development" : import.meta.env.DEV +export const env = createEnv({ + clientPrefix: "VITE_", + client: { + VITE_WEB_URL: z.string().url().default("https://app.follow.is"), + VITE_API_URL: z.string(), + VITE_DEV_PROXY: z.string().optional(), + VITE_SENTRY_DSN: z.string().optional(), + VITE_INBOXES_EMAIL: z.string().default("@follow.re"), + VITE_FIREBASE_CONFIG: z.string().optional(), + + VITE_OPENPANEL_CLIENT_ID: z.string().optional(), + VITE_OPENPANEL_API_URL: z.string().url().optional(), + + // For external, use api_url if you don't want to fill it in. + VITE_EXTERNAL_PROD_API_URL: z.string().optional(), + VITE_EXTERNAL_DEV_API_URL: z.string().optional(), + VITE_EXTERNAL_API_URL: z.string().optional(), + VITE_WEB_PROD_URL: z.string().optional(), + VITE_WEB_DEV_URL: z.string().optional(), + }, + + emptyStringAsUndefined: true, + runtimeEnv: getRuntimeEnv() as any, + + skipValidation: "process" in globalThis ? process.env.VITEST === "true" : false, +}) + +function metaEnvIsEmpty() { + try { + return Object.keys(import.meta.env || {}).length === 0 + } catch { + return true + } +} + +function getRuntimeEnv() { + try { + if (metaEnvIsEmpty()) { + return process.env + } + return injectExternalEnv(import.meta.env) + } catch { + return process.env + } +} + +declare const globalThis: any +function injectExternalEnv(originEnv: T): T { + if (!("document" in globalThis)) { + return originEnv + } + const prefix = "__followEnv" + const env = globalThis[prefix] + if (!env) { + return originEnv + } + + for (const key in env) { + originEnv[key as keyof T] = env[key] + } + return originEnv +} diff --git a/packages/shared/src/env.mobile.ts b/packages/shared/src/env.mobile.ts index 377071a28..23fea443e 100644 --- a/packages/shared/src/env.mobile.ts +++ b/packages/shared/src/env.mobile.ts @@ -2,20 +2,23 @@ const profile = "prod" const appEndpointMap = { prod: { - api: "https://api.follow.is", - web: "https://app.follow.is", + VITE_API_URL: "https://api.follow.is", + VITE_WEB_URL: "https://app.follow.is", + VITE_INBOXES_EMAIL: "@follow.re", }, dev: { - api: "https://api.dev.follow.is", - web: "https://dev.follow.is", + VITE_API_URL: "https://api.dev.follow.is", + VITE_WEB_URL: "https://dev.follow.is", + VITE_INBOXES_EMAIL: "__devdev@follow.re", }, staging: { - api: "https://api.follow.is", - web: "https://staging.follow.is", + VITE_API_URL: "https://api.follow.is", + VITE_WEB_URL: "https://staging.follow.is", + VITE_INBOXES_EMAIL: "@follow.re", }, } export const env = { - VITE_WEB_URL: appEndpointMap[profile].web, - VITE_API_URL: appEndpointMap[profile].api, + VITE_WEB_URL: appEndpointMap[profile].VITE_WEB_URL, + VITE_API_URL: appEndpointMap[profile].VITE_API_URL, } diff --git a/packages/shared/src/env.ts b/packages/shared/src/env.ts index 9029ce303..7904410a3 100644 --- a/packages/shared/src/env.ts +++ b/packages/shared/src/env.ts @@ -1,67 +1,23 @@ -import { createEnv } from "@t3-oss/env-core" import { z } from "zod" -export const isDev = - "process" in globalThis ? process.env.NODE_ENV === "development" : import.meta.env.DEV -export const env = createEnv({ - clientPrefix: "VITE_", - client: { - VITE_WEB_URL: z.string().url().default("https://app.follow.is"), - VITE_API_URL: z.string(), - VITE_DEV_PROXY: z.string().optional(), - VITE_SENTRY_DSN: z.string().optional(), - VITE_INBOXES_EMAIL: z.string().default("@follow.re"), - VITE_FIREBASE_CONFIG: z.string().optional(), +export const envSchema = { + VITE_WEB_URL: z.string().url().default("https://app.follow.is"), + VITE_API_URL: z.string().default("https://api.follow.is"), + VITE_DEV_PROXY: z.string().optional(), + VITE_SENTRY_DSN: z.string().optional(), + VITE_INBOXES_EMAIL: z.string().default("@follow.re"), + VITE_FIREBASE_CONFIG: z.string().optional(), - VITE_OPENPANEL_CLIENT_ID: z.string().optional(), - VITE_OPENPANEL_API_URL: z.string().url().optional(), + VITE_OPENPANEL_CLIENT_ID: z.string().optional(), + VITE_OPENPANEL_API_URL: z.string().url().optional(), - // For external, use api_url if you don't want to fill it in. - VITE_EXTERNAL_PROD_API_URL: z.string().optional(), - VITE_EXTERNAL_DEV_API_URL: z.string().optional(), - VITE_EXTERNAL_API_URL: z.string().optional(), - VITE_WEB_PROD_URL: z.string().optional(), - VITE_WEB_DEV_URL: z.string().optional(), - }, - - emptyStringAsUndefined: true, - runtimeEnv: getRuntimeEnv() as any, - - skipValidation: "process" in globalThis ? process.env.VITEST === "true" : false, -}) - -function metaEnvIsEmpty() { - try { - return Object.keys(import.meta.env || {}).length === 0 - } catch { - return true - } + // For external, use api_url if you don't want to fill it in. + VITE_EXTERNAL_PROD_API_URL: z.string().optional(), + VITE_EXTERNAL_DEV_API_URL: z.string().optional(), + VITE_EXTERNAL_API_URL: z.string().optional(), + VITE_WEB_PROD_URL: z.string().optional(), + VITE_WEB_DEV_URL: z.string().optional(), } -function getRuntimeEnv() { - try { - if (metaEnvIsEmpty()) { - return process.env - } - return injectExternalEnv(import.meta.env) - } catch { - return process.env - } -} - -declare const globalThis: any -function injectExternalEnv(originEnv: T): T { - if (!("document" in globalThis)) { - return originEnv - } - const prefix = "__followEnv" - const env = globalThis[prefix] - if (!env) { - return originEnv - } - - for (const key in env) { - originEnv[key as keyof T] = env[key] - } - return originEnv -} +export const isDev = false +export const env = z.object(envSchema).parse({}) diff --git a/plugins/vite/specific-import.ts b/plugins/vite/specific-import.ts index 251431135..1a87758d2 100644 --- a/plugins/vite/specific-import.ts +++ b/plugins/vite/specific-import.ts @@ -6,49 +6,24 @@ export function createPlatformSpecificImportPlugin(platform: Platform): Plugin { name: "platform-specific-import", enforce: "pre", async resolveId(source, importer) { - if (!importer) { - return null - } + const resolvedPath = await this.resolve(source, importer, { + skipSelf: true, + }) - const allowExts = [".js", ".jsx", ".ts", ".tsx"] + if (resolvedPath && !resolvedPath.id.includes("node_modules")) { + const lastDotIndex = resolvedPath.id.lastIndexOf(".") - if (!allowExts.some((ext) => importer.endsWith(ext))) return null + const paths = [ + `${resolvedPath.id.slice(0, lastDotIndex)}.${platform}${resolvedPath.id.slice(lastDotIndex)}`, + `${resolvedPath.id.slice(0, lastDotIndex)}.desktop${resolvedPath.id.slice(lastDotIndex)}`, + ] - if (importer.includes("node_modules")) return null - const [path, query] = source.split("?") - - if (path.startsWith(".") || path.startsWith("/")) { - let priorities: string[] = [] - switch (platform) { - case "electron": { - priorities = [".electron.ts", ".electron.tsx", ".electron.js", ".electron.jsx"] - - break - } - case "web": { - priorities = [".web.ts", ".web.tsx", ".web.js", ".web.jsx"] - - break - } - case "rn": { - priorities = [".rn.ts", ".rn.tsx", ".rn.js", ".rn.jsx"] - - break - } - // No default - } - - for (const ext of priorities) { - const resolvedPath = await this.resolve( - `${path}${ext}${query ? `?${query}` : ""}`, - importer, - { - skipSelf: true, - }, - ) - - if (resolvedPath) { - return resolvedPath.id + for (const path of paths) { + const resolvedPlatform = await this.resolve(path, importer, { + skipSelf: true, + }) + if (resolvedPlatform) { + return resolvedPlatform.id } } }