Revalidate Docs / Revalidate Docs (push) Failing after 2s
E2E CI / Check Duplicate Run (push) Failing after 5s
Test CI / Check Duplicate Run (push) Failing after 6s
E2E CI / Test Web App (push) Has been skipped
Test CI / Test Packages (push) Has been skipped
Test CI / Test App (shard 1/3) (push) Has been skipped
Test CI / Test App (shard 2/3) (push) Has been skipped
Test CI / Test App (shard 3/3) (push) Has been skipped
Test CI / Test Desktop App (push) Has been skipped
🔄 Branch Synchronization / sync-branches (push) Failing after 11s
Test CI / Test Database (push) Has been skipped
Test CI / Merge and Upload App Coverage (push) Has been skipped
Database Schema Visualization CI / build (push) Failing after 4m14s
57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
import { access } from 'node:fs/promises';
|
|
|
|
import type { Plugin } from 'vite';
|
|
|
|
type Platform = 'web' | 'mobile' | 'desktop';
|
|
|
|
/**
|
|
* Resolves platform-specific file variants by suffix priority:
|
|
* 1. `.vite` — Vite-specific override (highest)
|
|
* 2. `.mobile` — mobile build only
|
|
* ∞. fallback — original file
|
|
*
|
|
* Example: importing `./locale.ts` on a mobile build tries
|
|
* locale.vite.ts → locale.mobile.ts → locale.ts
|
|
*/
|
|
export function vitePlatformResolve(platform?: Platform): Plugin {
|
|
const suffixes: string[] = [];
|
|
if (platform) suffixes.push(`.${platform}`);
|
|
suffixes.push('.vite');
|
|
const EXT_RE = /\.(ts|tsx|js|jsx)$/;
|
|
const PLATFORM_RE = /\.(?:vite|web|mobile|desktop)\.(?:ts|tsx|js|jsx)$/;
|
|
|
|
return {
|
|
enforce: 'pre',
|
|
name: 'vite-platform-resolve',
|
|
async resolveId(source, importer, options) {
|
|
if (!importer || importer.includes('node_modules')) return null;
|
|
|
|
const resolved = await this.resolve(source, importer, { ...options, skipSelf: true });
|
|
if (!resolved) return null;
|
|
|
|
const id = resolved.id.split('?')[0];
|
|
|
|
const extMatch = id.match(EXT_RE);
|
|
if (!extMatch) return null;
|
|
|
|
// Already a platform-specific file — skip to avoid infinite loop
|
|
if (PLATFORM_RE.test(id)) return null;
|
|
|
|
const basePath = id.slice(0, -extMatch[0].length);
|
|
const ext = extMatch[0];
|
|
|
|
for (const suffix of suffixes) {
|
|
const candidate = `${basePath}${suffix}${ext}`;
|
|
try {
|
|
await access(candidate);
|
|
return candidate;
|
|
} catch {
|
|
// Not found, try next
|
|
}
|
|
}
|
|
|
|
return null;
|
|
},
|
|
};
|
|
}
|