greasify / vite-userscript-plugin

⚡️📦 A Vite plugin to build userscripts for Tampermonkey, Greasemonkey and Violentmonkey.

Home Page:https://npmjs.com/vite-userscript-plugin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Inject css (sometimes it doesn't work)

crashmax-dev opened this issue · comments

vitejs/vite#1579 (comment)

vitejs/vite#1579 (comment)

import fs from 'fs'
import { resolve } from 'path'
import type { ResolvedConfig, PluginOption } from 'vite'

const fileRegex = /\.(css)$/

const injectCode = (code: string) =>
  `function styleInject(css,ref){if(ref===void 0){ref={}}var insertAt=ref.insertAt;if(!css||typeof document==="undefined"){return}var head=document.head||document.getElementsByTagName("head")[0];var style=document.createElement("style");style.type="text/css";if(insertAt==="top"){if(head.firstChild){head.insertBefore(style,head.firstChild)}else{head.appendChild(style)}}else{head.appendChild(style)}if(style.styleSheet){style.styleSheet.cssText=css}else{style.appendChild(document.createTextNode(css))}};styleInject(\`${code}\`)`
const template = `console.warn("__INJECT__")`

let viteConfig: ResolvedConfig
const css: string[] = []

export default function injectCss(): PluginOption {
  return {
    name: 'inject-css',
    apply: 'build',
    configResolved(resolvedConfig) {
      viteConfig = resolvedConfig
    },
    transform(code, id) {
      if (fileRegex.test(id)) {
        css.push(code)
        return {
          code: ''
        }
      }

      if (id.includes(viteConfig.build.lib.entry)) {
        return {
          code: code + template
        }
      }

      return null
    },
    async writeBundle(options, bundle) {
      for (const file of Object.entries(bundle)) {
        const { root } = viteConfig
        const outDir = viteConfig.build.outDir || 'dist'
        const fileName = file[0]
        const filePath = resolve(root, outDir, fileName)

        try {
          let data = fs.readFileSync(filePath, {
            encoding: 'utf8'
          })

          if (data.includes(template)) {
            data = data.replace(template, injectCode(css.join('\n')))
          }

          fs.writeFileSync(filePath, data)
        } catch (e) {
          console.error(e)
        }
      }
    }
  }
}