UNPKG

vite-plugin-prerelease

Version:
130 lines (125 loc) 3.8 kB
import fsp from 'node:fs/promises'; import path from 'node:path'; import { build, normalizePath } from 'vite'; import * as cheerio from 'cheerio'; // src/node/buildtime-env/index.ts function transformHtml(originHtml, prereleaseHtml) { if (!originHtml || !prereleaseHtml) return; const $ = cheerio.load(originHtml); const pre$ = cheerio.load(prereleaseHtml); const generateDynamicTags = ($2) => { return [ ...$2("script").filter((_, el) => Boolean($2(el).attr("src"))), ...$2("link").filter((_, el) => Boolean($2(el).attr("href"))), // legacy ...$2("script").filter((_, el) => Boolean($2(el).data("src") && $2(el).attr("id") === "vite-legacy-entry")), // log-time ...$2("script").filter((_, el) => typeof $2(el).data("log-time") !== "undefined") ]; }; const dynamicTags = generateDynamicTags($); const dynamicTagsOfPre = generateDynamicTags(pre$); dynamicTags.forEach((el) => { $(el).remove(); }); const createInsertScript = (dynamicTags2) => { return dynamicTags2.map((e) => { return { attribs: e.attribs, tag: e.tagName, children: $(e).html() }; }); }; const code = ( /* js */ ` !(function() { function insertTags(tags) { tags.forEach(({ attribs, tag, children }) => { const element = document.createElement(tag) for (const key in attribs) { element.setAttribute(key, attribs[key]) } if(children) { element.innerHTML = children } document.head.appendChild(element) }) } const isPrerelease = window.Cookies.get('prerelease') === 'true' const attrs = isPrerelease ? ${JSON.stringify(createInsertScript(dynamicTagsOfPre))} : ${JSON.stringify(createInsertScript(dynamicTags))} insertTags(attrs) })() ` ); $("body").after(`<script>${code}</script>`); return $.html().replace(/^\s*$(?:\r\n?|\n)/gm, ""); } // src/node/buildtime-env/index.ts function buildtimeEnv(options) { const { prereleaseEnv, __debug } = options || {}; const definePlugin = { name: "vite:plugin-prerelease-define", apply(_, env) { return env.mode === prereleaseEnv && env.command === "build" || __debug; }, config() { return { define: { "import.meta.env.PRERELEASE": "true" } }; } }; let config; let originalHtml; let prereleaseHtml; const buildPlugin = { name: "vite:plugin-prerelease-build", enforce: "post", apply(_, env) { if (env.mode === prereleaseEnv) return false; return env.command === "build"; }, configResolved(resolvedConfig) { config = resolvedConfig; }, transformIndexHtml: { order: "post", handler(html) { originalHtml = html; } }, async closeBundle() { config.logger.info("Building prerelease..."); await build({ configFile: config.configFile, mode: prereleaseEnv, base: normalizePath(`${config.base}/prerelease`), build: { outDir: normalizePath(`${config.build.outDir}/prerelease`) }, plugins: [ { name: "vite:plugin-prerelease-html", enforce: "post", transformIndexHtml: { order: "post", handler(html) { prereleaseHtml = html; } } } ] }); const transformedHtml = transformHtml(originalHtml, prereleaseHtml); if (transformedHtml) { await fsp.writeFile(path.join(config.build.outDir, "index.html"), transformedHtml); } config.logger.info("Prerelease build complete"); } }; return [definePlugin, buildPlugin]; } export { buildtimeEnv };