| 94 | `; |
| 95 | |
| 96 | export async function buildUI() { |
| 97 | const start = Date.now(); |
| 98 | let totalSize = 0; |
| 99 | const entryPoints: string[] = []; |
| 100 | const lazyModules: string[] = []; |
| 101 | const newFiles = ['entry.js']; |
| 102 | for (const addon of Object.values(global.addons) as string[]) { |
| 103 | let publicPath = resolve(addon, 'frontend'); |
| 104 | if (!fs.existsSync(publicPath)) publicPath = resolve(addon, 'public'); |
| 105 | if (!fs.existsSync(publicPath)) continue; |
| 106 | const targets = fs.readdirSync(publicPath); |
| 107 | for (const target of targets) { |
| 108 | if (/\.page\.[jt]sx?$/.test(target)) entryPoints.push(join(publicPath, target)); |
| 109 | if (/\.lazy\.[jt]sx?$/.test(target)) lazyModules.push(join(publicPath, target)); |
| 110 | } |
| 111 | } |
| 112 | function addFile(name: string, content: string) { |
| 113 | vfs[name] = content; |
| 114 | hashes[name] = sha1(content).substring(0, 8); |
| 115 | logger.info('+ %s-%s: %s', name, hashes[name].substring(0, 6), size(content.length)); |
| 116 | newFiles.push(name); |
| 117 | totalSize += content.length; |
| 118 | } |
| 119 | for (const m of lazyModules) { |
| 120 | const name = basename(m).split('.')[0]; |
| 121 | const { outputFiles } = await build(`window.lazyModuleResolver['${name}'](require('${relative(tmp, m).replace(/\\/g, '\\\\')}'))`); |
| 122 | const css = outputFiles.filter((i) => i.path.endsWith('.css')).map((i) => i.text).join('\n'); |
| 123 | for (const file of outputFiles) { |
| 124 | if (file.path.endsWith('.css')) continue; |
| 125 | addFile(basename(m).replace(/\.[tj]sx?$/, '.js'), (css ? applyCss(css) : '') + file.text); |
| 126 | } |
| 127 | } |
| 128 | for (const lang in global.Hydro.locales) { |
| 129 | if (!/^[a-zA-Z_]+$/.test(lang)) continue; |
| 130 | if (!global.Hydro.locales[lang].__interface) continue; |
| 131 | const str = `window.LOCALES=${JSON.stringify(global.Hydro.locales[lang][Symbol.for('iterate')])};`; |
| 132 | addFile(`lang-${lang}.js`, str); |
| 133 | } |
| 134 | const entry = await build([ |
| 135 | `window.lazyloadMetadata = ${JSON.stringify(hashes)};`, |
| 136 | `window.LANGS=${JSON.stringify(SettingModel.langs)};`, |
| 137 | ...entryPoints.map((i) => `import '${relative(tmp, i).replace(/\\/g, '\\\\')}';`), |
| 138 | ].join('\n')); |
| 139 | const pages = entry.outputFiles.filter((i) => i.path.endsWith('.js')).map((i) => i.text); |
| 140 | const css = entry.outputFiles.filter((i) => i.path.endsWith('.css')).map((i) => i.text); |
| 141 | addFile('entry.js', `window._hydroLoad=()=>{ |
| 142 | ${css.length ? applyCss(css.join('\n')) : ''} |
| 143 | ${pages.join('\n')} |
| 144 | };`); |
| 145 | UiContextBase.constantVersion = hashes['entry.js']; |
| 146 | for (const key in vfs) { |
| 147 | if (newFiles.includes(key)) continue; |
| 148 | delete vfs[key]; |
| 149 | delete hashes[key]; |
| 150 | } |
| 151 | logger.success('UI addons built in %d ms (%s)', Date.now() - start, size(totalSize)); |
| 152 | } |
| 153 | |