Go to file
Mai Lapyst e707ccf969
Bump version
2024-04-06 04:08:33 +02:00
src Add sri plugin 2024-04-06 02:57:13 +02:00
.gitignore Initial commit - release v1.0.0 2023-10-10 20:24:22 +02:00
.nvmrc Add .nvmrc 2024-03-07 23:05:20 +01:00
LICENSE Initial commit - release v1.0.0 2023-10-10 20:24:22 +02:00
package.json Bump version 2024-04-06 04:08:33 +02:00
readme.md Add sri plugin 2024-04-06 02:57:13 +02:00
tsconfig.json Initial commit - release v1.0.0 2023-10-10 20:24:22 +02:00
vite.config.ts Add sri plugin 2024-04-06 02:57:13 +02:00
yarn.lock Add sri plugin 2024-04-06 02:57:13 +02:00



Npm package version Npm package version Npm package types

A range of vite plugins I wrote sometime and use them in some of my projects.


This project is licensed under AGPL-3.0-or-later. See the LICENSE file for more informations.


If you install this package, it will tell you about some peer dependencies. The only "hard" required peer dependency is vite. All others are only needed if you use a particular plugin. Each plugin declares the needed peer dependencies down below, as well as in it's doc-comment.



The preload_assets plugin helps you in preloading your assets in your application by emitting <link rel="preload" elements at the very top of your index.html document, which means they're the first entries inside the <head> element.

import { preload_assets, defaultPreloadFilters } from '@bithero/vite-plugins';

export default defineConfig({
    plugins: [
            // note that filters have a order: filters are checked in order,
            // and the first match is taken.
            // This means that later filter will not alter a type applied
            // by an matched earlier filter.
            filters: [
                // defaultPreloadFilters() returns the default filters, which
                // are also used when you do not specify any yourself.

                    // the type used for the `as` attribute inside the preload element.
                    // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload#what_types_of_content_can_be_preloaded
                    // Note that some types are missing since we only use assets here anyway.
                    type: 'image',

                    // the filter is a regex that's matched against the asset's filename,
                    // and only if it's matches, the type above is used to preload the asset.
                    filter: /\.(?:png|jpe?g|svg|gif|tiff|bmp|ico)$/,


With pubdir_to_assets, you can let vite handle all your assets inside the public directory like regular assets. That means they end up in dist/assets/, get a mangled name with their source hash, and are subjective to other things like being mangled by build.rollupOptions.output.assetFileNames.

import { pubdir_to_assets, mk_pubdir } from '@bithero/vite-plugins';

export default defineConfig(function (env) {
    return {
        // this needs to be done in order for pubdir_to_assets to work;
        // it's only purpose is to set the public directory
        // to `false` when we're in build-mode.
        publicDir: mk_pubdir(env, '../public'),

        plugins: [
            // Only option is the publicdir to use;
            // it should have the same value as you passed into `mk_pubdir`.


typegroup_assets provides a plugin that allows you to group assets in dist/assets by their "type". This works by setting assetFileNames, chunkFileNames and entryFileNames of build.rollupOptions.output; this also means that your config cannot set those.

import { typegroup_assets, defaultTypeMap } from '@bithero/vite-plugins';

export default defineConfig(function (env) {
    return {
        plugins: [
                // Maps a type to file extensions;
                // the key is here the type, and the value is the matcher.
                typemap: {
                    // defaultTypeMap() returns the default typemap, which
                    // are also used when you do not specify any yourself.

                    // map files with the (case sensitive) literal
                    // extension '.png' to the type 'img1'
                    'img1': 'png',

                    // map files where the file extension passes the regex
                    // (i.e. '.jpeg' or '.jpg') to the type 'img2'
                    'img2': /jpe?g/i,

                    // map files that are one of the (case sensitive) literal
                    // extensions in the list (i.e. '.bmp' or '.ico')
                    // to the type 'img3'
                    'img3': ['bmp', 'ico'],


A plugin that allows to do simple mocking of requests:

import { IncomingMessage, ServerResponse } from 'node:http';
import { Connect } from 'vite';
import { mock_requests } from '@bithero/vite-plugins';

export default defineConfig({
    plugins: [
            // List of requests to mock.
            // Each entry is either a MockFile or a MockRequestHandler;
            // both have a member url, which behaves exactly the same: 
            // If it's a string, its matched literally against the incomming
            // request url; if it's a RegExp, it's tested against it.
            mocks: [
                    url: /^\/data\/.*\.txt$/i,

                    // if file is a string, its used as-is as reponse body
                    file: "Lorum ipsum",

                    url: '/data/numbers.json',

                    // if file is a Object or an Array,
                    // it is serialized to JSON
                    file: [1, 2, 3, 4, 5],

                    url: /^\/texts\/.*\.txt$/i,

                    // if file is a function; it is called.
                    // As return value it expects one of
                    // the plain values (string, Object or Array),
                    // and behaves with them like normal.
                    file(url: string) {
                        return `This is the text from ${url}!`;

                    url: /^\/dynamic\//i,

                    // MockRequestHandler are essentially just middlewares.
                    // They get the request and response objects simply forwarded,
                    // and can do anything a normal middleware would do.
                    handle(req: IncomingMessage, resp: ServerResponse, next: Connect.NextFunction): void {
                        // Just use req and resp like in any other middleware:
                        resp.statusCode = 403;
                        resp.write('No Access');


Simple plugin to aid in the process of including css files from node modules inside your own css files:

import { css_node_resolve } from '@bithero/vite-plugins';

export default defineConfig({
    plugins: [
        // with the optional parameter you can configure the prefix
        // the plugin should look out for.

Then in your css:

/* this will resolve to <projectdir>/node_modules/@blueprintjs/core/lib/css/blueprint.css */
@import url('~@blueprintjs/core/lib/css/blueprint.css');


A plugin that allows to define "codegen"-jobs via virtual modules.

Note: this does not generate type information or any form of .d.ts file. So if you're using typescript, you'll need to provide it with a additional .d.ts file to declare the module and what's inside.

Note: Needs both fast-glob and chokidar to be present.


import { BaseCtx, sourcegen } from '@bithero/vite-plugins';

interface MyCtx extends BaseCtx {
  pages: string[];

export default defineConfig({
    plugins: [
            name: 'mysite-data',
            sourceIds: ['mysite/data'],
            patterns: ['src/pages/*.js'],
            log: true,
            onStart(ctx) { ctx.pages = {}; },
            handleFileEvent(event, info, ctx) {
                const name = basename(info.path);
                if (event === 'add') { ctx.pages[name] = true; }
                else if (event === 'unlink') { delete ctx.pages[name]; }
            codegen(sourceId, ctx) {
                if (sourceId !== 'mysite/data') { return undefined; }
                return `export const pages = ${JSON.stringify(Object.keys(ctx.pages))};`;


Plugin to add SRI integrity attributes to both <script src="..."> and <link rel="stylesheet" href="..."> elements.

Note: Needs both node-html-parser to be present.

Important: This ONLY works if these elements are present at buildtime in the index.html. Because of this, ALWAYS use this plugin AFTER ALL OTHER PLUGINS that transform the index.html via the transformIndexHtml hook.

import { sri } from '@bithero/vite-plugins';

export default defineConfig({
    plugins: [
            name: 'some-plugin',
            transformIndexHtml() {
                return [{
                    injectTo: 'head',
                    tag: 'script',
                    attrs: {
                        src: '/some/other/source.js'
        // Placeing the plugin here will ensure the script tag added by the plugin above is also picked up
            // Allows to set the hashing algorithm.
            // By default this is sha256
            algorithm: 'sha512',

            // Option to also hash remote sources (src / href begins with 'http').
            // By default this is disabled. To enable, set to 'true'.
            includeRemote: false,

If you want to access the hashes created by this plugin without the need to parse any html, you can do that by calling __getSriHashes on the plugin's instance (i.e. what is returned by the call to sri()). It will return you an Record<string, string>, where the key is the value of either the src or href attribute, and the key will be the complete sri hash / value for the integrity attribute.