0

I'm trying to use an external script to create static-generated content (SSG) but can't figure out how to plug it into Vite.

I've looked into plugins like vite-plugin-run but that dosn't seem to be able and get the file that changed to pass into the command. I also looked into transform hook but can't manage to get something working.

Is it possible to do something like below? How can I pass the source to the command (aka redirect content as input to command)?

// vite.config.js
import { exec } from 'child_process';

...

  plugins: [
    {
      name: "Transform HTML",
      transform(code, id) {
        
        // Transform HTML via external script
        if (id.endsWith(".html")) {
          // TODO: Replace 'echo test' with actually passing the content to myscript.sh and using the output
          exec('echo test', (err, stdout, stderr) => {
            code = stdout;
          });
        }

        return {code, map: null}
      }
    }
  ]


Pithikos
  • 18,827
  • 15
  • 113
  • 136

2 Answers2

0

In my case I write Vite plugins in separate .mjs files and import them as other Vite pluings:

import fs from 'fs';

export default function (pluginOptions = {}) {

    let config;

    return {

        name: 'test-vite-plugin',

        config(val) {
            config = val; // get Vite config to use inside your plugin
        },

        async resolveId(id, importer) {
            // you can resolve your custom bare imports here and return a resolved file path
        },

        async load(id) {

            let code = fs.readFileSync(id).toString();
    
            // you can load a file before any transform filters and transform it

            return {
                code
            };
        },

        async transform(code, id){
           // transform you code here (the code's content depends on plugin inject order and plugin order flags)
        }
    }
}
Alexander Nenashev
  • 8,775
  • 2
  • 6
  • 17
0

OK, after some digging I figured you can use transformIndexHtml hook as mentioned here. However to make it work in our case it needs some changes so it goes through another script.

vite.config.js

const { execSync } = require('child_process');

const htmlPlugin = () => {
  return {
    name: 'html-transform',
    transformIndexHtml(html) {
      try {
        const modifiedHtml = execSync('python jinja2parse.py', {
          input: html,
          encoding: 'utf-8',
        });
        return modifiedHtml;
      } catch (error) {
        console.error('Failed to execute the Python script:', error);
        return html; // Return the original HTML in case of an error
      }
    },
  }
}

jinja2parse.py

import sys
import jinja2

def parse_content(content, **kwargs):
    template = jinja2.Template(content)
    return template.render(**kwargs)

if __name__ == '__main__':
    html_content = sys.stdin.read()
    print(parse_content(html_content))

That's the basic idea.

Pithikos
  • 18,827
  • 15
  • 113
  • 136