Giter Site home page Giter Site logo

applelo / unplugin-inject-preload Goto Github PK

View Code? Open in Web Editor NEW
15.0 2.0 3.0 562 KB

A plugin for injecting <link rel='preload'> for ViteJS and HTMLWebpackPlugin

License: MIT License

HTML 2.89% TypeScript 85.09% CSS 1.60% JavaScript 10.42%
html-webpack-plugin inject preload vite-plugin vitejs webpack

unplugin-inject-preload's Introduction

unplugin-inject-preload

NPM version node-current jsr Coverage Status

This plugin adds preload links by getting output assets from the build tools you are using.

Supporting:

Note

This plugin combines vite-plugin-inject-preload and html-webpack-inject-preload into one package.

See the migration guide for vite-plugin-inject-preload and html-webpack-inject-preload .

Install

#npm
npm i -D unplugin-inject-preload
#yarn
yarn add -D unplugin-inject-preload
#pnpm
pnpm i -D unplugin-inject-preload
Vite
// vite.config.ts
import UnpluginInjectPreload from 'unplugin-inject-preload/vite'

export default defineConfig({
  plugins: [
    UnpluginInjectPreload({ /* options */ }),
  ],
})

Example: playground/vitejs

The Vite plugin only works on build because of the way Vite behave.


Webpack (with HtmlWebpackPlugin)
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UnpluginInjectPreload = require('unplugin-inject-preload/webpack')

module.exports = {
  plugins: [
    HtmlWebpackPlugin({ /*  HtmlWebpackPlugin options */ }),
    UnpluginInjectPreload({ /* options */ }),
  ]
}

Example: playground/webpack


Rspack (with HtmlWebpackPlugin)
// rspack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UnpluginInjectPreload = require('unplugin-inject-preload/rspack')

module.exports = {
  plugins: [
    HtmlWebpackPlugin({ /*  HtmlWebpackPlugin options */ }),
    UnpluginInjectPreload({ /* options */ }),
  ]
}

Example: playground/rspack


Rspack (with HtmlRspackPlugin)
// rspack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UnpluginInjectPreload = require('unplugin-inject-preload/rspack')

module.exports = {
  plugins: [
    new rspack.HtmlRspackPlugin({ /* HtmlRspackPlugin options */ }),
    UnpluginInjectPreload({ /* options */ }),
  ]
}

Example: playground/rspack


๐Ÿ‘จโ€๐Ÿ’ป Usage

All example are presented for ViteJS but this is the same behavior for Webpack and RsPack

All the files needs to be process by the bundler to be find by the plugin. For example, if I load this CSS file :

@font-face {
  font-family: 'Roboto';
  src: url('./../fonts/Roboto-Italic.woff2');
  font-weight: 400;
  font-style: italic;
}

@font-face {
  font-family: 'Roboto';
  src: url('./../fonts/Roboto-Regular.woff2');
  font-weight: 400;
  font-style: normal;
}

I can make the following configuration for UnpluginInjectPreload :

// vite.config.js / vite.config.ts
import UnpluginInjectPreload from 'unplugin-inject-preload/vite'

export default {
  plugins: [
    UnpluginInjectPreload({
      files: [
        {
          entryMatch: /Roboto-[a-zA-Z]*\.woff2$/,
        },
        {
          outputMatch: /lazy.[a-z-0-9]*.(css|js)$/,
        }
      ]
    })
  ]
}

Options

  • files: An array of files object

    • entryMatch: A regular expression to target entry files you want to preload
    • outputMatch: A regular expression to target output build files you want to preload

    You need to set at least entryMatch or/and outputMatch. Be aware that entry file is not always present for webpack and entryMatch will do nothing.

    • attributes (optional): If this option is ommited, it will determine the mime and the as attributes automatically. You can also add/override any attributes you want.
  • injectTo (optional): By default, the preload links are injected with the 'head-prepend' options. But you can pass 'head' to inject preload links at bottom of the head tag if you need it.
    You can pass the 'custom' option and put <!--__unplugin-inject-preload__--> in your .html file where you want to inject the preload links.

With the full options usage, you can do something like this :

// vite.config.js / vite.config.ts
import UnpluginInjectPreload from 'unplugin-inject-preload/vite'

export default {
  plugins: [
    UnpluginInjectPreload({
      files: [
        {
          entryMatch: /Roboto-[a-zA-Z]*\.woff2$/,
          outputMatch: /Roboto-[a-zA-Z]*-[a-z-0-9]*\.woff2$/,
          attributes: {
            'type': 'font/woff2',
            'as': 'font',
            'crossorigin': 'anonymous',
            'data-font': 'Roboto'
          }
        },
        {
          outputMatch: /lazy.[a-z-0-9]*.(js)$/,
          attributes: {
            rel: 'modulepreload',
            type: undefined,
          }
        }
      ],
      injectTo: 'head-prepend'
    })
  ]
}

Migration

From vite-plugin-inject-preload

package.json

{
  "devDependencies": {
-   "vite-plugin-inject-preload": "*",
+   "unplugin-inject-preload": "^2.0.0",
  }
}

vite.config.js

- import VitePluginInjectPreload from 'vite-plugin-inject-preload'
+ import UnpluginInjectPreload from 'unplugin-inject-preload/vite'

export default {
  plugins: [
    VitePluginInjectPreload({
      files: [
        {
-         match: /Roboto-[a-zA-Z]*-[a-z-0-9]*\.woff2$/,
+         outputMatch: /Roboto-[a-zA-Z]*-[a-z-0-9]*\.woff2$/,
          attributes: {
            'type': 'font/woff2',
            'as': 'font',
            'crossorigin': 'anonymous',
            'data-font': 'Roboto'
          }
        },
      ],
      injectTo: 'head-prepend'
    })
  ]
}

From html-webpack-inject-preload

package.json

{
  "devDependencies": {
-   "@principalstudio/html-webpack-inject-preload": "*",
+   "unplugin-inject-preload": "^2.0.0",
  }
}
const HtmlWebpackPlugin = require('html-webpack-plugin');
- const HtmlWebpackInjectPreload = require('@principalstudio/html-webpack-inject-preload');
+ const UnpluginInjectPreload = require('unplugin-inject-preload/webpack');

module.exports = {
  entry: 'index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'index_bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin(),
-   new HtmlWebpackInjectPreload({
+   UnpluginInjectPreload({
      files: [
        {
-         match: /.*\.woff2$/,
+         outputMatch: /.*\.woff2$/,
          attributes: {
            as: 'font',
            type: 'font/woff2', crossorigin: true
          },
        },
      ]
    })
  ]
}

๐Ÿ‘จโ€๐Ÿ’ผ Licence

MIT

unplugin-inject-preload's People

Contributors

applelo avatar

Stargazers

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

Watchers

 avatar  avatar

Forkers

seektan lizc2003

unplugin-inject-preload's Issues

Redundant `/` prefixed the output path if `base` of vite config is relative, such as `./`

After upgraded from vite-plugin-inject-preload, the output path of each preloaded file got a redundant / if the base of vite config is relative.

Output
output

vite.config.ts
vite.config.ts

Digging into the source https://github.com/Applelo/unplugin-inject-preload/blob/main/src/helper/getTagsAttributes.ts#L12

function pathJoin(...strs: string[]) {
  let path = ''
  for (let index = 0; index < strs.length; index++) {
    const str = strs[index]
    const previousStr = index ? strs[index - 1] : ''

    if (str && !str.startsWith('/') && !previousStr.endsWith('/'))   <--- don't understand what scenario it deals with, but the problem is here
      path += `/${str}`
    else
      path += str
  }

  return path
}

And since it's a regression bug, it'd be nice to have a fix.

Add support for file path matching

I can only get this to work by providing regex for file names.

It would be better if I could specify the file path of the entry so I can preload based on folders and not rely on prefixing files.

I would like to do something like this:

.*\/wallpaper\/.*\.jpg

to match
src/assets/wallpaper/*

Am I missing something, or is this supported? I am using Vite.

Only supports Vite 'build'

Support for the "serve" target would be helpful when developing.

Right now it looks like this plugin is restricted to "build" only, which means it will not inject preloads while running 'dev' ('serve' target).

If this is intentional, it may be helpful to note in the documentation.

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.