personal web client for Bluesky
typescript solidjs bluesky atcute
at trunk 3.2 kB view raw
1import * as path from 'node:path'; 2 3import { cloudflare } from '@cloudflare/vite-plugin'; 4import { defineConfig } from 'vite'; 5import { VitePWA } from 'vite-plugin-pwa'; 6import solid from 'vite-plugin-solid'; 7 8const SERVER_HOST = '127.0.0.1'; 9const SERVER_PORT = 52222; 10 11const OAUTH_SCOPE = 'atproto transition:generic transition:chat.bsky'; 12 13export default defineConfig({ 14 build: { 15 target: 'esnext', 16 modulePreload: false, 17 sourcemap: true, 18 assetsInlineLimit: 0, 19 minify: 'terser', 20 rollupOptions: { 21 output: { 22 chunkFileNames: 'assets/[hash].js', 23 manualChunks: { 24 common: [ 25 'solid-js', 26 'solid-js/store', 27 'solid-js/web', 28 29 '@atcute/client', 30 '@atcute/oauth-browser-client', 31 '@mary/events', 32 '@mary/solid-query', 33 34 'src/service-worker.tsx', 35 36 'src/globals/events.ts', 37 'src/globals/locales.ts', 38 'src/globals/modals.tsx', 39 'src/globals/navigation.ts', 40 'src/globals/preferences.ts', 41 42 'src/lib/states/agent.tsx', 43 'src/lib/states/session.tsx', 44 'src/lib/states/theme.tsx', 45 ], 46 shell: ['src/shell.tsx'], 47 }, 48 }, 49 }, 50 terserOptions: { 51 compress: { 52 passes: 3, 53 }, 54 }, 55 }, 56 resolve: { 57 alias: { 58 '~': path.join(__dirname, './src'), 59 }, 60 }, 61 server: { 62 host: SERVER_HOST, 63 port: SERVER_PORT, 64 }, 65 optimizeDeps: { 66 esbuildOptions: { 67 target: 'esnext', 68 }, 69 }, 70 plugins: [ 71 solid({ 72 babel: { 73 plugins: [['babel-plugin-transform-typescript-const-enums']], 74 }, 75 }), 76 77 cloudflare(), 78 79 VitePWA({ 80 registerType: 'prompt', 81 injectRegister: null, 82 workbox: { 83 globPatterns: ['**/*.{js,css,html,svg,jpg,png}'], 84 cleanupOutdatedCaches: true, 85 }, 86 manifest: { 87 id: '/', 88 start_url: '/', 89 scope: '/', 90 name: 'Aglais', 91 short_name: 'Aglais', 92 description: 'Alternative web client for Bluesky', 93 display: 'standalone', 94 background_color: '#000000', 95 icons: [ 96 { 97 src: 'favicon.png', 98 type: 'image/png', 99 sizes: '150x150', 100 }, 101 ], 102 }, 103 }), 104 105 // Transform the icon components to remove the `() => _tmpl$()` wrapper 106 { 107 name: 'aglais-icon-transform', 108 transform(code, id) { 109 if (!id.includes('/icons-central/')) { 110 return; 111 } 112 113 const transformed = code.replace( 114 /(?<=createIcon\()\(\)\s*=>*.([\w$]+)\(\)(?=\))/g, 115 (_match, id) => id, 116 ); 117 118 return { code: transformed, map: null }; 119 }, 120 }, 121 122 // Injects OAuth-related variables for development mode 123 { 124 name: 'aglais-oauth-inject', 125 config(_conf, { command }) { 126 if (command === 'build') { 127 // Production uses confidential client 128 process.env.VITE_OAUTH_CLIENT_ID = ''; 129 process.env.VITE_OAUTH_REDIRECT_URL = ''; 130 } else { 131 // Development uses public client with http://localhost format 132 const redirectUri = `http://${SERVER_HOST}:${SERVER_PORT}/oauth/callback`; 133 134 const clientId = 135 `http://localhost` + 136 `?redirect_uri=${encodeURIComponent(redirectUri)}` + 137 `&scope=${encodeURIComponent(OAUTH_SCOPE)}`; 138 139 process.env.VITE_OAUTH_CLIENT_ID = clientId; 140 process.env.VITE_OAUTH_REDIRECT_URL = redirectUri; 141 } 142 143 process.env.VITE_OAUTH_SCOPE = OAUTH_SCOPE; 144 }, 145 }, 146 ], 147});