this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 243 lines 7.3 kB view raw
1import { execSync } from 'child_process'; 2import fs from 'fs'; 3import { resolve } from 'path'; 4 5import { lingui } from '@lingui/vite-plugin'; 6import preact from '@preact/preset-vite'; 7import Sonda from 'sonda/vite'; 8import { uid } from 'uid/single'; 9import { defineConfig, loadEnv } from 'vite'; 10import generateFile from 'vite-plugin-generate-file'; 11import htmlPlugin from 'vite-plugin-html-config'; 12import { VitePWA } from 'vite-plugin-pwa'; 13import removeConsole from 'vite-plugin-remove-console'; 14import { run } from 'vite-plugin-run'; 15 16import { ALL_LOCALES } from './src/locales'; 17 18const allowedEnvPrefixes = ['VITE_', 'PHANPY_']; 19const { NODE_ENV } = process.env; 20const { 21 PHANPY_WEBSITE: WEBSITE, 22 PHANPY_CLIENT_NAME: CLIENT_NAME, 23 PHANPY_APP_ERROR_LOGGING: ERROR_LOGGING, 24 PHANPY_REFERRER_POLICY: REFERRER_POLICY, 25 PHANPY_DISALLOW_ROBOTS: DISALLOW_ROBOTS, 26 PHANPY_DEV, 27} = loadEnv('production', process.cwd(), allowedEnvPrefixes); 28 29const now = new Date(); 30let commitHash; 31let fakeCommitHash = false; 32try { 33 commitHash = execSync('git rev-parse --short HEAD').toString().trim(); 34} catch (error) { 35 // If error, means git is not installed or not a git repo (could be downloaded instead of git cloned) 36 // Fallback to random hash which should be different on every build run 🤞 37 commitHash = uid(); 38 fakeCommitHash = true; 39} 40 41const rollbarCode = fs.readFileSync( 42 resolve(__dirname, './rollbar.js'), 43 'utf-8', 44); 45 46// https://vitejs.dev/config/ 47export default defineConfig({ 48 base: './', 49 envPrefix: allowedEnvPrefixes, 50 appType: 'mpa', 51 mode: NODE_ENV, 52 define: { 53 __BUILD_TIME__: JSON.stringify(now), 54 __COMMIT_HASH__: JSON.stringify(commitHash), 55 __FAKE_COMMIT_HASH__: fakeCommitHash, 56 }, 57 server: { 58 host: true, 59 }, 60 css: { 61 preprocessorMaxWorkers: 1, 62 }, 63 plugins: [ 64 preact({ 65 // Force use Babel instead of ESBuild due to this change: https://github.com/preactjs/preset-vite/pull/114 66 // Else, a bug will happen with importing variables from import.meta.env 67 babel: { 68 plugins: ['@lingui/babel-plugin-lingui-macro'], 69 }, 70 }), 71 lingui(), 72 run({ 73 silent: false, 74 input: [ 75 { 76 name: 'messages:extract:clean', 77 run: ['npm', 'run', 'messages:extract:clean'], 78 pattern: 'src/**/*.{js,jsx,ts,tsx}', 79 }, 80 // { 81 // name: 'update-catalogs', 82 // run: ['node', 'scripts/catalogs.js'], 83 // pattern: 'src/locales/*.po', 84 // }, 85 ], 86 }), 87 removeConsole({ 88 includes: ['log', 'debug', 'info', 'warn', 'error'], 89 }), 90 htmlPlugin({ 91 metas: [ 92 // Learn more: https://web.dev/articles/referrer-best-practices 93 { 94 name: 'referrer', 95 content: REFERRER_POLICY || 'origin', 96 }, 97 ], 98 headScripts: ERROR_LOGGING ? [rollbarCode] : [], 99 links: [ 100 ...ALL_LOCALES.map((lang) => ({ 101 rel: 'alternate', 102 hreflang: lang, 103 // *Fully-qualified* URLs 104 href: `${WEBSITE}/?lang=${lang}`, 105 })), 106 // https://developers.google.com/search/docs/specialty/international/localized-versions#xdefault 107 { 108 rel: 'alternate', 109 hreflang: 'x-default', 110 href: `${WEBSITE}`, 111 }, 112 ], 113 }), 114 generateFile([ 115 { 116 type: 'json', 117 output: './version.json', 118 data: { 119 buildTime: now, 120 commitHash, 121 }, 122 }, 123 ...(DISALLOW_ROBOTS 124 ? [ 125 { 126 type: 'raw', 127 output: './robots.txt', 128 data: 'User-agent: *\nDisallow: /', 129 }, 130 ] 131 : []), 132 ]), 133 VitePWA({ 134 manifest: { 135 name: CLIENT_NAME, 136 short_name: CLIENT_NAME, 137 description: 'Minimalistic opinionated Mastodon web client', 138 // https://github.com/cheeaun/phanpy/issues/231 139 theme_color: undefined, 140 icons: [ 141 { 142 src: 'logo-192.png', 143 sizes: '192x192', 144 type: 'image/png', 145 }, 146 { 147 src: 'logo-512.png', 148 sizes: '512x512', 149 type: 'image/png', 150 }, 151 { 152 src: 'logo-maskable-512.png', 153 sizes: '512x512', 154 type: 'image/png', 155 purpose: 'maskable', 156 }, 157 ], 158 categories: ['social', 'news'], 159 }, 160 strategies: 'injectManifest', 161 injectRegister: 'inline', 162 injectManifest: { 163 // Prevent "Unable to find a place to inject the manifest" error 164 injectionPoint: undefined, 165 }, 166 devOptions: { 167 enabled: NODE_ENV === 'development', 168 type: 'module', 169 }, 170 }), 171 Sonda({ 172 deep: true, 173 brotli: true, 174 open: false, 175 }), 176 ], 177 build: { 178 sourcemap: true, 179 // Note: In Vite 6, if cssCodeSplit = false, it will show error "Cannot read properties of undefined (reading 'includes')" 180 // TODO: Revisit this when this issue is fixed 181 // cssCodeSplit: false, 182 rollupOptions: { 183 treeshake: false, 184 input: { 185 main: resolve(__dirname, 'index.html'), 186 compose: resolve(__dirname, 'compose/index.html'), 187 }, 188 output: { 189 // NOTE: Comment this for now. This messes up async imports. 190 // Without SplitVendorChunkPlugin, pushing everything to vendor is not "smart" enough 191 // manualChunks: (id, { getModuleInfo }) => { 192 // // if (id.includes('@formatjs/intl-segmenter/polyfill')) return 'intl-segmenter-polyfill'; 193 // if (/tiny.*light/.test(id)) return 'tinyld-light'; 194 195 // // Implement logic similar to splitVendorChunkPlugin 196 // if (id.includes('node_modules')) { 197 // // Check if this module is dynamically imported 198 // const moduleInfo = getModuleInfo(id); 199 // if (moduleInfo) { 200 // // If it's imported dynamically, don't put in vendor 201 // const isDynamicOnly = 202 // moduleInfo.importers.length === 0 && 203 // moduleInfo.dynamicImporters.length > 0; 204 // if (isDynamicOnly) return null; 205 // } 206 // return 'vendor'; 207 // } 208 // }, 209 chunkFileNames: (chunkInfo) => { 210 const { facadeModuleId } = chunkInfo; 211 if (facadeModuleId && facadeModuleId.includes('icon')) { 212 return 'assets/icons/[name]-[hash].js'; 213 } 214 if (facadeModuleId && facadeModuleId.includes('locales')) { 215 return 'assets/locales/[name]-[hash].js'; 216 } 217 return 'assets/[name]-[hash].js'; 218 }, 219 assetFileNames: (assetInfo) => { 220 const { originalFileNames } = assetInfo; 221 if (originalFileNames?.[0]?.includes('assets/sandbox')) { 222 return 'assets/sandbox/[name]-[hash].[ext]'; 223 } 224 return 'assets/[name]-[hash].[ext]'; 225 }, 226 }, 227 plugins: [ 228 { 229 name: 'exclude-sandbox', 230 generateBundle(_, bundle) { 231 if (!PHANPY_DEV) { 232 Object.entries(bundle).forEach(([name, chunk]) => { 233 if (name.includes('sandbox')) { 234 delete bundle[name]; 235 } 236 }); 237 } 238 }, 239 }, 240 ], 241 }, 242 }, 243});