如何配置@rollup/plugin-html使index.html与main.js同目录?
解决Rollup多入口对应子目录index.html的问题
要实现每个入口的main.js所在子目录都生成对应index.html,需要自定义@rollup/plugin-html的文件名规则和模板逻辑,同时调整输出目录结构的保留规则,具体配置如下:
import { defineConfig } from "rollup"; import multiInput from "rollup-plugin-multi-input"; import typescript from "rollup-plugin-typescript2"; import html from "@rollup/plugin-html"; export default defineConfig([ { input: ["ui/**/main.tsx"], output: { dir: "out", // 保留入口文件的目录结构,让js输出路径和入口对应 preserveModulesRoot: "ui" }, plugins: [ multiInput(), typescript({ resolveJsonModule: true, tsconfig: "./tsconfig.react.json" }), html({ // 为每个入口生成对应子目录的index.html fileName: (chunk) => { // 从入口文件路径中提取子目录部分 const entryPath = chunk.facadeModuleId; // 适配ui/xxx/main.tsx的路径格式,提取xxx部分作为子目录 const subDir = entryPath.replace(/^ui\/(.+)\/main\.tsx$/, "$1"); return `${subDir}/index.html`; }, // 自定义HTML模板,引入当前目录下的main.js template: ({ files }) => { const jsFile = files.js.find(file => file.fileName.endsWith("main.js")); const jsFileName = jsFile ? jsFile.fileName.split("/").pop() : ""; return ` <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>页面入口</title> </head> <body> <div id="root"></div> <script src="${jsFileName}"></script> </body> </html> `.trim(); } }) ] } ]);
关键调整说明
output.preserveModulesRoot
设置为"ui"后,Rollup会将ui目录下的入口文件按照原有子结构输出到out目录,比如ui/demo/main.tsx会输出为out/demo/main.js,保证js文件和目标html在同一子目录。html.fileName
通过正则匹配入口文件的路径,提取出子目录名称,动态生成子目录/index.html的文件名,确保每个入口对应独立的html文件位置。html.template
自定义模板时,只引入当前子目录下的main.js(通过拆分js文件路径获取文件名),避免引入其他入口的资源。
适配说明
如果你的入口文件路径格式不同(比如入口不是main.tsx,或者ui下的层级更复杂),只需要调整fileName中的正则表达式即可,比如入口为ui/module/sub/page.tsx,正则可改为/^ui\/(.+)\/page\.tsx$/。
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

