'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const ejs = require('ejs'); const dotenvExpand = require('dotenv-expand'); const dotenv = require('dotenv'); const path = require('pathe'); const fse = require('fs-extra'); const vite = require('vite'); const nodeHtmlParser = require('node-html-parser'); const fg = require('fast-glob'); const consola = require('consola'); const colorette = require('colorette'); const history = require('connect-history-api-fallback'); const htmlMinifierTerser = require('html-minifier-terser'); const pluginutils = require('@rollup/pluginutils'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; } const dotenv__default = /*#__PURE__*/_interopDefaultLegacy(dotenv); const path__default = /*#__PURE__*/_interopDefaultLegacy(path); const fse__default = /*#__PURE__*/_interopDefaultLegacy(fse); const fg__default = /*#__PURE__*/_interopDefaultLegacy(fg); const consola__default = /*#__PURE__*/_interopDefaultLegacy(consola); const history__default = /*#__PURE__*/_interopDefaultLegacy(history); function loadEnv(mode, envDir, prefix = "") { if (mode === "local") { throw new Error(`"local" cannot be used as a mode name because it conflicts with the .local postfix for .env files.`); } const env = {}; const envFiles = [ `.env.${mode}.local`, `.env.${mode}`, `.env.local`, `.env` ]; for (const file of envFiles) { const path = lookupFile(envDir, [file], true); if (path) { const parsed = dotenv__default.parse(fse__default.readFileSync(path)); dotenvExpand.expand({ parsed, ignoreProcessEnv: true }); for (const [key, value] of Object.entries(parsed)) { if (key.startsWith(prefix) && env[key] === void 0) { env[key] = value; } else if (key === "NODE_ENV") { process.env.VITE_USER_NODE_ENV = value; } } } } return env; } function lookupFile(dir, formats, pathOnly = false) { for (const format of formats) { const fullPath = path.join(dir, format); if (fse__default.pathExistsSync(fullPath) && fse__default.statSync(fullPath).isFile()) { return pathOnly ? fullPath : fse__default.readFileSync(fullPath, "utf-8"); } } const parentDir = path.dirname(dir); if (parentDir !== dir) { return lookupFile(parentDir, formats, pathOnly); } } async function isDirEmpty(dir) { return fse__default.readdir(dir).then((files) => { return files.length === 0; }); } const DEFAULT_TEMPLATE = "index.html"; const ignoreDirs = [".", "", "/"]; const bodyInjectRE = /<\/body>/; function createPlugin(userOptions = {}) { const { entry, template = DEFAULT_TEMPLATE, pages = [], verbose = false } = userOptions; let viteConfig; let env = {}; return { name: "vite:html", enforce: "pre", configResolved(resolvedConfig) { viteConfig = resolvedConfig; env = loadEnv(viteConfig.mode, viteConfig.root, ""); }, config(conf) { const input = createInput(userOptions, conf); if (input) { return { build: { rollupOptions: { input } } }; } }, configureServer(server) { let _pages = []; const rewrites = []; if (!isMpa(viteConfig)) { const template2 = userOptions.template || DEFAULT_TEMPLATE; const filename = DEFAULT_TEMPLATE; _pages.push({ filename, template: template2 }); } else { _pages = pages.map((page) => { return { filename: page.filename || DEFAULT_TEMPLATE, template: page.template || DEFAULT_TEMPLATE }; }); } const proxy = viteConfig.server?.proxy ?? {}; const baseUrl = viteConfig.base ?? "/"; const keys = Object.keys(proxy); let indexPage = null; for (const page of _pages) { if (page.filename !== "index.html") { rewrites.push(createRewire(page.template, page, baseUrl, keys)); } else { indexPage = page; } } if (indexPage) { rewrites.push(createRewire("", indexPage, baseUrl, keys)); } server.middlewares.use(history__default({ disableDotRule: void 0, htmlAcceptHeaders: ["text/html", "application/xhtml+xml"], rewrites })); }, transformIndexHtml: { enforce: "pre", async transform(html, ctx) { const url = ctx.filename; const base = viteConfig.base; const excludeBaseUrl = url.replace(base, "/"); const htmlName = path__default.relative(process.cwd(), excludeBaseUrl); const page = getPage(userOptions, htmlName, viteConfig); const { injectOptions = {} } = page; const _html = await renderHtml(html, { injectOptions, viteConfig, env, entry: page.entry || entry, verbose }); const { tags = [] } = injectOptions; return { html: _html, tags }; } }, async closeBundle() { const outputDirs = []; if (isMpa(viteConfig) || pages.length) { for (const page of pages) { const dir = path__default.dirname(page.template); if (!ignoreDirs.includes(dir)) { outputDirs.push(dir); } } } else { const dir = path__default.dirname(template); if (!ignoreDirs.includes(dir)) { outputDirs.push(dir); } } const cwd = path__default.resolve(viteConfig.root, viteConfig.build.outDir); const htmlFiles = await fg__default(outputDirs.map((dir) => `${dir}/*.html`), { cwd: path__default.resolve(cwd), absolute: true }); await Promise.all(htmlFiles.map((file) => fse__default.move(file, path__default.resolve(cwd, path__default.basename(file)), { overwrite: true }))); const htmlDirs = await fg__default(outputDirs.map((dir) => dir), { cwd: path__default.resolve(cwd), onlyDirectories: true, absolute: true }); await Promise.all(htmlDirs.map(async (item) => { const isEmpty = await isDirEmpty(item); if (isEmpty) { return fse__default.remove(item); } })); } }; } function createInput({ pages = [], template = DEFAULT_TEMPLATE }, viteConfig) { const input = {}; if (isMpa(viteConfig) || pages?.length) { const templates = pages.map((page) => page.template); templates.forEach((temp) => { let dirName = path__default.dirname(temp); const file = path__default.basename(temp); dirName = dirName.replace(/\s+/g, "").replace(/\//g, "-"); const key = dirName === "." || dirName === "public" || !dirName ? file.replace(/\.html/, "") : dirName; input[key] = path__default.resolve(viteConfig.root, temp); }); return input; } else { const dir = path__default.dirname(template); if (ignoreDirs.includes(dir)) { return void 0; } else { const file = path__default.basename(template); const key = file.replace(/\.html/, ""); return { [key]: path__default.resolve(viteConfig.root, template) }; } } } async function renderHtml(html, config) { const { injectOptions, viteConfig, env, entry, verbose } = config; const { data, ejsOptions } = injectOptions; const ejsData = { ...viteConfig?.env ?? {}, ...viteConfig?.define ?? {}, ...env || {}, ...data }; let result = await ejs.render(html, ejsData, ejsOptions); if (entry) { result = removeEntryScript(result, verbose); result = result.replace(bodyInjectRE, `