UNPKG

vite-plugin-public-path

Version:

Vite's equivalent of `__webpack_public_path__` in Webpack. Works for `index.html` and modern/legacy build.

120 lines (119 loc) 5.92 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.processHtml = void 0; const pluginutils_1 = require("@rollup/pluginutils"); const node_html_parser_1 = require("node-html-parser"); const serialize_javascript_1 = __importDefault(require("serialize-javascript")); function processHtml(config, options, _fileName, html) { // Just load from a static base if (typeof options.html === "string") { return html.split(config.base).join(options.html); } // Disable HTML processing and pass-through the HTML with base placeholder for manual processing if (!options.html) { return html; } const document = (0, node_html_parser_1.parse)(html, { comment: true }); // For simple substitution, firstly inject placeholders and required code const htmlOptions = typeof options.html === "object" ? options.html : { functionNameAddLinkTag: "__vitePluginPublicPath_addLinkTag", addLinkTagsPlaceholder: `__add_link_tags_${Math.random()}__`, functionNameAddScriptTag: "__vitePluginPublicPath_addScriptTag", addScriptTagsPlaceholder: `__add_script_tags_${Math.random()}__` }; if (typeof options.html !== "object") { // Ignore const lastScriptInHead = document.querySelectorAll("head > script:not([type=module])").pop(); /* istanbul ignore next */ if (!lastScriptInHead) { throw new Error(`Couldn't find any <script> tags in your <head>. Please initialize your public path expression (${options.publicPathExpression}) in a <script> in your <head>.`); } lastScriptInHead.insertAdjacentHTML("afterend", "\n" + "<script>\n" + " (function () {\n" + ` function ${htmlOptions.functionNameAddLinkTag}(rel, href, integrity) {\n` + ' var link = document.createElement("link");\n' + " link.rel = rel;\n" + " link.href = href;\n" + " if (integrity) { link.integrity = integrity; };\n" + " document.head.appendChild(link);\n" + " }\n" + ` ${htmlOptions.addLinkTagsPlaceholder}\n` + " })();\n" + "</script>\n"); document .querySelector("body") .insertAdjacentHTML("beforeend", "\n" + "<script>\n" + " (function () {\n" + ` function ${htmlOptions.functionNameAddScriptTag}(attributes, inlineScriptCode) {\n` + ' var script = document.createElement("script");\n' + " if (attributes) for (var key in attributes) script.setAttribute(key, attributes[key]);\n" + " script.async = false;\n" + ' if (inlineScriptCode) script.src = "data:text/javascript," + inlineScriptCode;\n' + " document.body.appendChild(script);\n" + " }\n" + ` ${htmlOptions.addScriptTagsPlaceholder}\n` + " })();\n" + "</script>\n"); } const urlPrefix = config.base; const normalizeUrl = (url) => { if (url.startsWith(urlPrefix)) url = url.slice(urlPrefix.length); return url; }; const urlToExpression = (url) => { url = normalizeUrl(url); // Check absolute URLs if (["//", "http://", "https://", "data:"].some(prefix => url.toLowerCase().startsWith(prefix))) { return (0, serialize_javascript_1.default)(url); } return `${options.publicPathExpression} + ${(0, serialize_javascript_1.default)(url)}`; }; const linkTags = document .querySelectorAll("link[rel]") .filter(link => link.getAttribute("href").startsWith(urlPrefix)); const addLinkTagsCode = linkTags .map(tag => { const href = tag.getAttribute("href"); const rel = tag.getAttribute("rel"); const integrity = tag.getAttribute("integrity"); return `${htmlOptions.functionNameAddLinkTag}(${(0, serialize_javascript_1.default)(rel)}, ${urlToExpression(href)}, ${(0, serialize_javascript_1.default)(integrity)})`; }) .join(";"); const patchAttributes = ["src", "data-src"]; const excludeScriptsFilter = options.excludeScripts ? (0, pluginutils_1.createFilter)(options.excludeScripts) : () => false; const scriptTags = document.querySelectorAll("script[src], script[nomodule]").filter(tag => { var _a; if (!patchAttributes.some(attr => tag.hasAttribute(attr))) { // script tag has no src or data-src, keep tag for rewrite. return true; } const src = (_a = tag.getAttribute("src")) !== null && _a !== void 0 ? _a : tag.getAttribute("data-src"); return !excludeScriptsFilter(src); }); const addScriptTagsCode = scriptTags .map(tag => { const args = [ "{ " + Object.entries(tag.attributes) .map(([key, value]) => (0, serialize_javascript_1.default)(key) + ": " + (patchAttributes.includes(key) ? urlToExpression(value) : (0, serialize_javascript_1.default)(value))) .join(", ") + " }", tag.innerHTML.trim() ? (0, serialize_javascript_1.default)(tag.innerHTML.trim()) : null ]; return `${htmlOptions.functionNameAddScriptTag}(${args.filter(arg => arg != null).join(", ")})`; }) .join(";"); [...linkTags, ...scriptTags].map(tag => tag.parentNode.removeChild(tag)); return document.outerHTML .replace(htmlOptions.addLinkTagsPlaceholder, addLinkTagsCode) .replace(htmlOptions.addScriptTagsPlaceholder, addScriptTagsCode); } exports.processHtml = processHtml;