UNPKG

velund

Version:

Модульная UI-система на Vite для полиглотных бэкендов

98 lines (95 loc) 3.34 kB
import path from 'path'; import { pathToFileURL } from 'url'; import * as fs from 'fs'; import fg from 'fast-glob'; const buildPlugin = (opts, generator, extensions) => { const assetSet = /* @__PURE__ */ new Set(); let rollupInput; let outDir; return { configResolved(config) { rollupInput = path.resolve( config?.build?.rollupOptions?.input === "index.html" ? "./src/main.ts" : config?.build?.rollupOptions?.input?.toString() || "./src/main.ts" ).toString().replace(/\\/g, "/"); outDir = path.resolve(config.build?.outDir); path.resolve(config.build?.assetsDir); }, // Сбор ассетов async buildStart() { if (this.meta?.watchMode) return; const templatesGlob = [ "./**/*.vel.ts", "./**/*.vel.js", ...extensions.map((ext) => `./**/*${ext}`) ]; const files = await fg(templatesGlob, { absolute: true }); const assetsToEmit = /* @__PURE__ */ new Set(); for (const file of files) { const content = fs.readFileSync(file, "utf-8"); const regex = /@\/([^\s"'<>]+)/g; let match; while ((match = regex.exec(content)) !== null) { assetsToEmit.add(match[1]); } } assetsToEmit.forEach((_, relPath) => { const absPath = path.join("./src", relPath); if (!fs.existsSync(absPath)) { console.warn(`[vite-plugin-twig] Asset not found: ${relPath}`); return; } const ext = path.extname(relPath); this.emitFile({ type: "chunk", id: path.resolve(absPath), name: path.basename(relPath, ext) }); assetSet.add("src/" + relPath); }); }, // Генерация PHP библиотеки async writeBundle(options, bundle) { const mainFile = Object.values(bundle).find( (f) => f.type === "chunk" && f.isEntry && f.facadeModuleId == rollupInput ); if (!mainFile) { console.warn("Main entry not found in bundle"); return; } const mainPath = path.resolve( options.dir || process.cwd(), mainFile.fileName ); await import(pathToFileURL(mainPath).href); const components = globalThis.__APP__.components || []; const finalAssetMap = {}; for (const fileName in bundle) { const b = bundle[fileName]; if ((b.type === "asset" || b.type === "chunk") && (b.originalFileName || b.facadeModuleId)) { const originalFileName = b.originalFileName || b.facadeModuleId.replace( path.resolve("./").replace(/\\/g, "/") + "/", "" ); if (assetSet.has(originalFileName)) { finalAssetMap[originalFileName.replace("src/", "@/")] = b.fileName; } } } components.forEach((tpl) => { let updated = tpl.template; Object.entries(finalAssetMap).forEach(([origPath, finalPath]) => { updated = updated.split(origPath).join( path.join(opts.assetsUrl, finalPath.replace("assets/", "./")).replace(/\\/g, "/") ); }); tpl.template = updated; }); await generator.generate( opts.renderer, components, path.join(outDir, "/lib") ); } }; }; export { buildPlugin as default };