如何将包含的 Pug 文件添加到 Vite 模块图中

How to add included Pug files to Vite module graph

我写了一个 Rollup 插件来将 Pug 作为 HTML 字符串导入:

// Rollup plugin imported to Vite config

import { render } from 'pug';

export default function pug() {
  return {
    name: 'rollup-plugin-pug-html',

    transform(src, id) {
      if (id.endsWith('.pug')) {
        const html = render(src, { filename: id });
        const code = `export default ${JSON.stringify(html)};`;

        return { code };
      }
    },
  };
}

我在 Vite 中使用它为 Vue 组件创建模板,如这个简化示例所示:

// ProofOfConceptSFC.vue

<script>
import { compile } from 'vue/dist/vue.esm-bundler.js';
import template from './template.pug';

export default {
  render: compile(template)
};
</script>

当我编辑 template.pug 时,HMR 运行良好。出现新模板,并且保留最新的反应值。

我的问题是 template.pug 可能依赖于其他 include:

的 Pug 文件
//- template.pug

include ./header.pug
p Hello {{ name }}
include ./footer.pug

Vite服务器不知道这些文件,我触摸它们也没有任何反应。理想情况下,我可以在任何 Pug 文件更改时使 template.pug 无效。

我猜我想让我的插件更新 ViteDevServer 的 server.moduleGraph。有支持的方法吗?

非常感谢友好的 Vite chat on Discord 为我指明了正确的方向。

我丢失的两个键:

  1. 使用 Pug compile 创建具有 render.dependenciesas done by Parcel
  2. render 方法
  3. 使用虚拟导入语句将依赖项附加到转换挂钩结果,as done by vite-plugin-svelte

这是工作插件:

import { compile } from 'pug';

export default function pluginPug() {
  return {
    name: 'vite-plugin-pug',

    transform(src, id) {
      if (id.endsWith('.pug')) {
        const render = compile(src, { filename: id });
        const html = render();
        let code = '';

        for (let dep of render.dependencies) {
          code += `import ${JSON.stringify(dep)};\n`;
        }

        code += `export default ${JSON.stringify(html)};`;

        return { code };
      }
    },
  };
}