Giter Site home page Giter Site logo

menci / vite-plugin-public-path Goto Github PK

View Code? Open in Web Editor NEW
13.0 2.0 4.0 112 KB

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

License: MIT License

TypeScript 94.89% HTML 2.75% CSS 0.56% JavaScript 1.79%

vite-plugin-public-path's Introduction

vite-plugin-public-path

Test Status npm Commitizen friendly code style: prettier License

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

You may need it if you want to load your resources from a CDN / multiple CDNs.

Installation

yarn add -D vite-plugin-public-path

Basic Usage

Put 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.

import react from "@nestjs/plugin-react";
import legacy from "@nestjs/plugin-legacy";
import publicPath from "vite-plugin-public-path";
import minifyHtml from "vite-plugin-html-minifier-terser";

export default defineConfig({
  plugins: [
    react(),
    legacy(),
    publicPath({
      // A JS expression evaluates on client side each time when loading a new file
      // Should evaluate to a string ending with "/"
      publicPathExpression: "window.publicPath",
      // See below for explanation of `options.html`
      html: true,
      // (Optional) The plugin will not rewrite any <script> tags whose src matches the provided filters
      // Useful for your external dependencies
      // Can be string, string[], RegExp or RegExp[]
      excludeScripts: /^https:.*systemjs/
    }),
    // You may need `vite-plugin-html-minifier-terser` since this plugin outputs non-minified inline JS code
    minifyHtml({ minifyJS: true })
  ]
});

Use 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.:

export default defineConfig({
  base: process.env.NODE_ENV === "production" ? "/__vite_base__/" : "/",
  plugins: [
    // ...
  ]
});

HTML Substitution

To make sure the initial scripts and assets in the HTML file load from your dynamic public path, we transform <link> and <script> tags in index.html to a piece of inline JS code, which creates and appends that tags dynamically.

You 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 <script> tag in <head>. We will start creating <link> tags after the last <script> tag in your <head>.

Skip HTML Substitution

You can skip this plugin's processing of your index.html (and, most likely, handle it yourself after this plugin) by:

  • 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.
  • 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.
    • 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.

Advanced Options

There'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.

You 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). All <link> and <script> tags will be transformed to calls to those two functions.

If you are confused, just refer to the dist/index.html generated with simple html: true.

functionNameAddLinkTag

The function name to add <link> tag, e.g. "addLinkTag". The function would be like:

function addLinkTag(rel, href) {
  var link = document.createElement("link");
  link.rel = rel;
  link.href = href;
  document.head.appendChild(link);
}

addLinkTagsPlaceholder

This string in your HTML file (should be in a <script> in <head>) 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__":

(function () {
  function addLinkTag(rel, href) {
    // code above
  }

  // __add_link_tags__
})();

functionNameAddScriptTag

The function name to add <script> tag, e.g. "addScriptTag". The function would be like:

function addScriptTag(attributes, inlineScriptCode) {
  var script = document.createElement("script");
  if (attributes) for (var key in attributes) script.setAttribute(key, attributes[key]);
  // This is required to make them execute in-order
  script.async = false;
  if (inlineScriptCode) script.src = "data:text/javascript," + inlineScriptCode;
  document.body.appendChild(script);
}

addScriptTagsPlaceholder

This string in your HTML file (should be in a <script> in <body>) 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__":

(function () {
  function addScriptTag(attributes, inlineScriptCode) {
    // code above
  }

  // __add_script_tags__
})();

vite-plugin-public-path's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vite-plugin-public-path's Issues

Example of how to create "header" tag in index.html

Can you give an example of how to create "header" tag in index.html refer to this description?
You 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 <script> tag in <head>. We will start creating <link> tags after the last <script> tag in your <head>.'

I have tried a lot of ways, but none of them worked.

Thank you.

Support vite 3.2.4

Will you upate this plugin to support latest version 3.2.4?
Currently the peerDependencies is still '^2.8':

  "peerDependencies": {
    "vite": "^2.8"
  },

memory allocation of bytes failed

On my project build was working fine
But as soon as I added this plugin the build is failing for me with error memory allocation of 268435456 bytes failed and now I need to add NODE_OPTIONS=--max_old_space_size=8192 on my local.

publicPath({
            // A JS expression evaluates on client side each time when loading a new file
            // Should evaluate to a string ending with "/"
            publicPathExpression: "window.publicPath",
            html: true,
            // uncomment if needed
            // excludeScripts: /^https:.*systemjs/
        }),

As the app is build via Github actions running which have memory of 7GB, its always failing. Even setting the max-old-space-size does not work there for windows env.

Why rewrite external script tags?

Hey!

I've got a use case where I'm dependent on certain external scripts being included in the initial DOM, in <head>. This plugin removes those script tags from the DOM and dynamically adds them back to the document body, which unfortunately breaks the page.

What is the purpose of rewriting external script tags? They will never be impacted by the public path, so why rewrite them?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.