npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vite-plugin-inject-css-to-js

v1.1.1

Published

Combine this with the Vite build.cssCodeSplit CSS code splitting capability to build css into individual js files instead of using css links.

Downloads

135

Readme

vite-plugin-inject-css-to-js

Combine this with the Vite 3+ build.cssCodeSplit CSS code splitting capability to build css into individual js files instead of using css links.

Install

Make sure your vite version is 3 or higher.

# pnpm
pnpm add -D vite-plugin-inject-css-to-js
# yarn
yarn add -D vite-plugin-inject-css-to-js
# npm
npm i -D vite-plugin-inject-css-to-js

Usage

// vite.config.js
import { defineConfig } from 'vite';

// 1. import the plugin
import { InjectCssToJsPlugin } from 'vite-plugin-inject-css-to-js';

export default defineConfig({
    plugins: [
        // 2. add it to the plugins list
        InjectCssToJsPlugin(),
    ],
});

Supports using the 'beforeInjectCss' hook to customize the return of your CSS code, such as in cases where a custom CDN domain exists.

// vite.config.js
import { defineConfig } from 'vite';

// 1. import the plugin
import { InjectCssToJsPlugin } from 'vite-plugin-inject-css-to-js';

export default defineConfig({
    plugins: [
        // 2. add it to the plugins list
        InjectCssToJsPlugin({
            beforeInjectCss: cssCode => {
                return JSON.stringify(cssCode)
                    .replace(/\/static\/images/g, '${window.cdnDomain}/static/images')
                    .replace(/^"|"$/g, '`');
            },
        }),
    ],
});

Q&A

Why can't I build all css files into js?

Since Vite vite:build-html plugin is executed before this plugin (i.e. enforce: pre is set by default), when this plugin generateBundle hook is executed, the html file has already been transformed, so it is not desirable to violently remove all the link css links on the html, and we can't rule out the scenarios where the plugin dynamically inserts link css links via transformIndexHtml hook. It is not desirable to violently remove all the link css links on html, we can't exclude the scenario that other plugins dynamically insert link css links through transformIndexHtml hook.

How transformIndexHtml hooks are implemented in vite:build-html plugin.

The vite:build-html plugin calls the resolveHtmlTransforms method to get all the transformIndexHtml hooks inside the plugin, which are classified as preHooks, normalHooks and postHooks.

If order: pre is set, it is classified as preHooks, if post is set, it is classified as postHooks, and if transformIndexHtml is a pure method, it is classified as normalHooks.

/** preHooks */
transformIndexHtml: {
    order: 'pre',
    handler: (html) => {
        return html;
    }
}

/** normalHooks */
transformIndexHtml() {}

/** postHooks */
transformIndexHtml: {
    order: 'post',
    handler: (html) => {
        return html;
    }
}

At this point, the vite:build-html plugin will call applyHtmlTransforms inside the transform hook to execute the preHooks, and then the generateBundle hook to execute the [... .normalHooks, . .postHooks] hooks. This also explains why we can't remove all css links from html by transformIndexHtml hook in this plugin, because other plugins may manually insert other css links inside transformIndexHtml hook.

How to get the path of the css external link referenced inside the html file?

Refer to Vite4 source code getCssTagsForChunk method to get the css external file name (i.e. final file path).

const cssTags: Set<string> = new Set();
const analyzedChunk: Map<OutputChunk, number> = new Map();
const getCssTagsForChunk = (chunk: OutputChunk, seen: Set<string> = new Set()) => {
    const tags: { filename: string }[] = [];
    if (!analyzedChunk.has(chunk)) {
        analyzedChunk.set(chunk, 1);
        chunk.imports.forEach(file => {
            const importee = ctx.bundle?.[file];
            if (importee?.type === 'chunk') {
                tags.push(...getCssTagsForChunk(importee, seen));
            }
        });
    }

    chunk.viteMetadata!.importedCss.forEach(file => {
        if (!seen.has(file)) {
            seen.add(file);
            tags.push({
                filename: file,
            });
        }
    });

    return tags;
};

Is it a concern that other plugins manually inject css files via the transformIndexHtml hook?

Personally, I don't need to pay attention to css files, because usually emitFile is used to create a file, and the path to the file will be available in the production package that is built.

License

MIT © Levix