{"id":19065484,"url":"https://github.com/menci/vite-plugin-public-path","last_synced_at":"2025-04-28T11:40:56.938Z","repository":{"id":42391943,"uuid":"462842153","full_name":"Menci/vite-plugin-public-path","owner":"Menci","description":"Vite's equivalent of `__webpack_public_path__` in Webpack. Works for `index.html` and modern/legacy build.","archived":false,"fork":false,"pushed_at":"2022-12-01T17:51:08.000Z","size":112,"stargazers_count":16,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-18T15:17:27.957Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Menci.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-23T17:39:31.000Z","updated_at":"2024-08-01T06:37:52.000Z","dependencies_parsed_at":"2023-01-22T10:45:28.875Z","dependency_job_id":null,"html_url":"https://github.com/Menci/vite-plugin-public-path","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2Fvite-plugin-public-path","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2Fvite-plugin-public-path/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2Fvite-plugin-public-path/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Menci%2Fvite-plugin-public-path/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Menci","download_url":"https://codeload.github.com/Menci/vite-plugin-public-path/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251306576,"owners_count":21568293,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T00:50:25.960Z","updated_at":"2025-04-28T11:40:56.921Z","avatar_url":"https://github.com/Menci.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vite-plugin-public-path\n\n[![Test Status](https://img.shields.io/github/workflow/status/Menci/vite-plugin-public-path/Test?style=flat-square)](https://github.com/Menci/vite-plugin-public-path/actions?query=workflow%3ATest)\n[![npm](https://img.shields.io/npm/v/vite-plugin-public-path?style=flat-square)](https://www.npmjs.com/package/vite-plugin-public-path)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square)](http://commitizen.github.io/cz-cli/)\n[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)\n[![License](https://img.shields.io/github/license/Menci/vite-plugin-public-path?style=flat-square)](LICENSE)\n\nVite's equivalent of [`__webpack_public_path__` in Webpack](https://webpack.js.org/guides/public-path/#on-the-fly). Works for `index.html` and modern/[legacy](https://www.npmjs.com/package/@vitejs/plugin-legacy) build.\n\nYou may need it if you want to load your resources from a CDN / multiple CDNs.\n\n## Installation\n\n```bash\nyarn add -D vite-plugin-public-path\n```\n\n## Basic Usage\n\nPut this plugin in your plugin list. It should be put ***after*** almost all plugins, ***expect for*** resource minimizers, e.g. you may need [vite-plugin-html-minifier-terser](https://www.npmjs.com/package/vite-plugin-html-minifier-terser).\n\n```typescript\nimport react from \"@nestjs/plugin-react\";\nimport legacy from \"@nestjs/plugin-legacy\";\nimport publicPath from \"vite-plugin-public-path\";\nimport minifyHtml from \"vite-plugin-html-minifier-terser\";\n\nexport default defineConfig({\n  plugins: [\n    react(),\n    legacy(),\n    publicPath({\n      // A JS expression evaluates on client side each time when loading a new file\n      // Should evaluate to a string ending with \"/\"\n      publicPathExpression: \"window.publicPath\",\n      // See below for explanation of `options.html`\n      html: true,\n      // (Optional) The plugin will not rewrite any \u003cscript\u003e tags whose src matches the provided filters\n      // Useful for your external dependencies\n      // Can be string, string[], RegExp or RegExp[]\n      excludeScripts: /^https:.*systemjs/\n    }),\n    // You may need `vite-plugin-html-minifier-terser` since this plugin outputs non-minified inline JS code\n    minifyHtml({ minifyJS: true })\n  ]\n});\n```\n\nUse a ***unique placeholder*** for `config.base` when building but NOT previewing. The placeholder value will be replaced to dynamic public path expression, so make sure it doesn't occur in your application code or assets' contents. e.g.:\n\n```typescript\nexport default defineConfig({\n  base: process.env.NODE_ENV === \"production\" ? \"/__vite_base__/\" : \"/\",\n  plugins: [\n    // ...\n  ]\n});\n```\n\n## HTML Substitution\n\nTo make sure the initial scripts and assets in the HTML file load from your dynamic public path, we transform `\u003clink\u003e` and `\u003cscript\u003e` tags in `index.html` to a piece of inline JS code, which creates and appends that tags dynamically.\n\nYou should initialize this expression's value (i.e. assign to it if it's a global variable or declare the function if it's calling one) in a `\u003cscript\u003e` tag in `\u003chead\u003e`. We will start creating `\u003clink\u003e` tags ***after*** the last `\u003cscript\u003e` tag in your `\u003chead\u003e`.\n\n### Skip HTML Substitution\n\nYou can skip this plugin's processing of your `index.html` (and, most likely, handle it yourself after this plugin) by:\n\n* `false`: Disable `index.html` processing. This will cause the output `index.html` contains the base placeholder, which lead to unusable HTML, which may help you process `index.html` yourself.\n* A `string`: if you pass a string, the `config.base` placeholder will be replaced to this string in generated `index.html`. This just removes the impact of placeholder.\n  * **NOTE:** If you (unlikely) just use this option and do no more processing, for modern build, this doesn't match Webpack's behavior \"load initial JS/CSS files from original host but imported from dynamic public path\", because ES module imports generated by Vite use ALL *relative* URLs. For legacy build it matches that behavior.\n\n### Advanced Options\n\nThere're some advanced options for HTML substitution. For some reason, if you want to customize the method of dynamically creating and appending tags, you can pass a `HtmlAdvancedOptions` to `options.html`.\n\nYou will need to implement two functions `addLinkTag` and `addScriptTag`. And two placeholders in contexts with access to those two functions (to allow minifier shortening the names, put them in a [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE)). All `\u003clink\u003e` and `\u003cscript\u003e` tags will be transformed to calls to those two functions.\n\nIf you are confused, just refer to the `dist/index.html` generated with simple `html: true`.\n\n#### `functionNameAddLinkTag`\n\nThe function name to add `\u003clink\u003e` tag, e.g. `\"addLinkTag\"`. The function would be like:\n\n```javascript\nfunction addLinkTag(rel, href) {\n  var link = document.createElement(\"link\");\n  link.rel = rel;\n  link.href = href;\n  document.head.appendChild(link);\n}\n```\n\n#### `addLinkTagsPlaceholder`\n\nThis string in your HTML file (should be in a `\u003cscript\u003e` in `\u003chead\u003e`) will be replaced to `functionNameAddLinkTag` expressions. Use a comment to prevent syntax errors on previewing (this plugin does only apply to building, not previewing). For example `\"// __add_link_tags__\"`:\n\n```javascript\n(function () {\n  function addLinkTag(rel, href) {\n    // code above\n  }\n\n  // __add_link_tags__\n})();\n```\n\n#### `functionNameAddScriptTag`\n\nThe function name to add `\u003cscript\u003e` tag, e.g. `\"addScriptTag\"`. The function would be like:\n\n```javascript\nfunction addScriptTag(attributes, inlineScriptCode) {\n  var script = document.createElement(\"script\");\n  if (attributes) for (var key in attributes) script.setAttribute(key, attributes[key]);\n  // This is required to make them execute in-order\n  script.async = false;\n  if (inlineScriptCode) script.src = \"data:text/javascript,\" + inlineScriptCode;\n  document.body.appendChild(script);\n}\n```\n\n#### `addScriptTagsPlaceholder`\n\nThis string in your HTML file (should be in a `\u003cscript\u003e` in `\u003cbody\u003e`) will be replaced to `functionNameAddScriptTag` expressions. Use a comment to prevent syntax errors on previewing (this plugin does only apply to building, not previewing). For example `\"// __add_script_tags__\"`:\n\n```javascript\n(function () {\n  function addScriptTag(attributes, inlineScriptCode) {\n    // code above\n  }\n\n  // __add_script_tags__\n})();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmenci%2Fvite-plugin-public-path","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmenci%2Fvite-plugin-public-path","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmenci%2Fvite-plugin-public-path/lists"}