emosheeep/vite-plugin-lib-inject-css

Replace `renderChunk` with `generateBundle` hook might be better? (vite:lib-inject-css)

Closed this issue · 10 comments

您好,在使用的时候遇到了这个问题,如果是放在 renderChunk 中的话,同一个 vue 文件在这个 hook 中可能对应有2个 chunk (搜了一圈不知道为啥),如图所示
在 OmegaDialog.vue2.mjs 这个 chunk 里面是有 importedCss & chunk.viteMetadata 的,另一个 chunk 是没有的,最终 build 完成 OmegaDialog.vue2.mjs 这个 chunk 却没有 emit 相应的文件出来

image

image

似乎把相应的逻辑写在 generateBundle 也可以,(这时候就只会一个 chunk 了):

    generateBundle(options, bundle) {
      Object.entries(bundle).forEach(([fileName, chunk]) => {
        // @ts-ignore
        if (!chunk.viteMetadata || chunk.type === "asset") return;
        const { importedCss } = (chunk as OutputChunk).viteMetadata!;
        if (!importedCss.size) return;

        const code = chunk.code;
        const ms = new MagicString(code);
        for (const cssFileName of importedCss) {
          let cssFilePath = path.relative(
            path.dirname(chunk.fileName),
            cssFileName
          );

          cssFilePath = cssFilePath.startsWith(".")
            ? cssFilePath
            : `./${cssFilePath}`;
          ms.prepend(`import '${cssFilePath}';\n`);
        }
        chunk.code = ms.toString();
        chunk.map = ms.generateMap();
      });
    }

你能把这个仓库给我看下吗。另外这个功能肯定是要尽可能在前面的钩子做的,在最后的那个钩子做就不能再享受构建工具的优化了,比如如果输出cjs就会自动变成require('style.css');。另外想问下,因此造成了什么后果吗,比如样式引入失败?

公司的代码,😂 有空我弄个 demo repo 。
后果就是因为第二个 chunk 没有生成文件,导致这一通操作都是虚空打靶

有的时候组件会进行chunk拆分,可能其中一个是chunk,另一个引了这个chunk,一个入口就是只有一份chunkcss对应来着。那等你整个demo吧,我在公司的项目试目前没有遇到什么问题。

在复现过程中发现 rollupOptions.output.preserveModules 设为 true 就会出现这种情况 。。。
reproduction link
pnpm build , logs/cheese.log 里面有日志

image

生成的文件:
image

rollupOptions.output.preserveModules 这个选项一般都为 false ,感觉是个 edge case

咦,奇怪了,你为何会主动设置这个呢🤔,单纯好奇

复现了,大概了解了情况,我再看看

咦,奇怪了,你为何会主动设置这个呢🤔,单纯好奇

我这里用到这个是把 vue/ts/tsx 文件翻译成 mjs 然后保持目录结构所以用到,像 element-plus 这种 (虽然在我的项目其实没啥必要,又不做浏览器的分发... 只是试一下 🤣)
image

虽然 generateBundle 钩子可以实现这个功能,但是这个钩子太靠后了,在这里改代码后续就无法享受其他插件的转换了,然后出现这种混合代码
image

明白了,这个确实是个 edge case