You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For web apps, one or multiple HTML files are the de-facto entrypoint. I’d love for rollup to be able to handle this (with the help of a plugin).
Feature Proposal
To bring this to a more generic level, and with #2823 and #2872 in mind, I’d propose to allow assets (non-JS files) to be entry points. Plugins that handle these assets can then analyze these files and emit dependencies, which can be both further assets and JavaScript files.
I have written a small experimental plugin to teach Rollup to handle HTML. I’m mostly including this code fragment to show how weird this currently feels. Maybe we can come up with something better.
exportdefaultfunctionhtmlPlugin(opts){// ... set up filter ...constcontentMap=newMap();return{name: "html-plugin",asyncload(id){if(!filter(id)){return;}constcontents=awaitfs.promises.readFile(id,{encoding: "utf-8"});constdoc=parseHTML(contents);// Find references to JavaScript and CSS files.constreferences=[
... awaitfindScriptTags(doc,id),
... awaitfindStylesheets(doc,id)];contentMap.set(id,{doc, references});// Because Rollup expects JavaScript, we return an empty file// and will inject the original contents in `generateBundle`.return{code: ""};},generateBundle(outputOptions,bundles){for(constbundleIdofObject.keys(bundles)){constbundle=bundles[bundleId];if(bundle.isAsset){continue;}if(!contentMap.has(bundle.facadeModuleId)){continue;}const{doc, references}=contentMap.get(bundle.facadeModuleId);// Replace the references to JavaScript and CSS// with their new Rollup-generated file names.for(constreferenceofreferences){reference.value=this.getChunkFileName(reference.value);}bundle.code=serializeHTML(doc);}}};}
I would be very wary of adding HTML handling to Rollup core. This is a very web specific feature that will possibly come with quite some overhead and a huge maintenance cost that I do not want to carry around. Also it is unclear to me what advantage it would have to have the HTML files as part of the dependency graph. Thus I will try to focus more on the problem you are attempting to solve.
As a suggestion how I would change your approach:
If you like to abuse Rollup's input option to specify an HTML file, you absolutely can! Just use the options hook and replace the input with an empty array. Yes, that should work! Of course if there are no inputs, then you MUST emit some chunks in the buildStart hook so that there is something to bundle.
Alternatively, you can ask the user to provide no inputs but I guess this feels wrong to the user.
Then you will not need to specify a load hook that filters ids but just a buildStart hook that emits chunks.
What is missing is a clean way to emit the updated HTML file(s) as you probably do not want to place them next to the other assets but next to the entry points or possibly in yet another location. As a "hack" you can currently just add new stuff to the bundle in generate bundle. I hope to add a proper context helper function for this in the future (so that you can also emit from other hooks).
I would be very wary of adding HTML handling to Rollup core. This is a very web specific feature that will possibly come with quite some overhead and a huge maintenance cost that I do not want to carry around.
That original snippet works basically exactly how I'd expect it to work, and doesn't seem that weird at all to me. Maybe I've been too deep into rollup plugins that support non-JS content for too long, dunno.
I definitely do not want to add full HTML support to Rollup core. The core of my proposal was to allow assets (non-JS files) to be entry points. In combination with #2872, a plugin could then take care of emitting the chunks found in the asset file.
If you like to abuse Rollup's input option to specify an HTML file, you absolutely can! Just use the options hook and replace the input with an empty array. Yes, that should work! Of course if there are no inputs, then you MUST emit some chunks in the buildStart hook so that there is something to bundle.
This is probably a sane-ish solution. I’ll close this and rather focus in #2872 :D
Reacted by Workruft, Owen Buckley, Daniele Orlando, Gabriel Francisco, Miriam Vellacott and Bill Coloe
E.g. I have HTML file entry point which has a <script> which imports some things from npm-installed modules. I'd like to have a single self-contained HTML file as output, with all JavaScript dependencies' source code embedded in <script> tags. Can one achieve this with rollup?
You can do exactly as was stated above. To clean up the output, the official way is to specify a generateBundle hook. To remove the unwanted files, just delete from the bundle object. The HTML output can be added at this point via this.emitFile using the fileName option, as it also states in the docs:
You can prevent files from being emitted by deleting them from the bundle object in this hook. To emit additional files, use the this.emitFile plugin context function.
Activity
lukastaegert commentedon May 24, 2019
This does not look "too bad" to me :)
I would be very wary of adding HTML handling to Rollup core. This is a very web specific feature that will possibly come with quite some overhead and a huge maintenance cost that I do not want to carry around. Also it is unclear to me what advantage it would have to have the HTML files as part of the dependency graph. Thus I will try to focus more on the problem you are attempting to solve.
As a suggestion how I would change your approach:
If you like to abuse Rollup's
inputoption to specify an HTML file, you absolutely can! Just use theoptionshook and replace theinputwith an empty array. Yes, that should work! Of course if there are no inputs, then you MUST emit some chunks in thebuildStarthook so that there is something to bundle.Alternatively, you can ask the user to provide no inputs but I guess this feels wrong to the user.
Then you will not need to specify a
loadhook that filters ids but just abuildStarthook that emits chunks.What is missing is a clean way to emit the updated HTML file(s) as you probably do not want to place them next to the other assets but next to the entry points or possibly in yet another location. As a "hack" you can currently just add new stuff to the
bundlein generate bundle. I hope to add a proper context helper function for this in the future (so that you can also emit from other hooks).shellscape commentedon May 24, 2019
Seconded.
tivac commentedon May 24, 2019
That original snippet works basically exactly how I'd expect it to work, and doesn't seem that weird at all to me. Maybe I've been too deep into rollup plugins that support non-JS content for too long, dunno.
LongTengDao commentedon May 26, 2019
You want this?
(input)
(config)
(output)
surma commentedon May 26, 2019
I should have been clearer, apologies.
I definitely do not want to add full HTML support to Rollup core. The core of my proposal was to allow assets (non-JS files) to be entry points. In combination with #2872, a plugin could then take care of emitting the chunks found in the asset file.
This is probably a sane-ish solution. I’ll close this and rather focus in #2872 :D
vadimkantorov commentedon Nov 16, 2025
Curious, what is the situation in 2025?
E.g. I have HTML file entry point which has a
<script>which imports some things from npm-installed modules. I'd like to have a single self-contained HTML file as output, with all JavaScript dependencies' source code embedded in<script>tags. Can one achieve this with rollup?Thanks!
lukastaegert commentedon Nov 16, 2025
You can do exactly as was stated above. To clean up the output, the official way is to specify a
generateBundlehook. To remove the unwanted files, justdeletefrom the bundle object. The HTML output can be added at this point viathis.emitFileusing thefileNameoption, as it also states in the docs:vadimkantorov commentedon Nov 16, 2025
Also, I found that official HTML plugin exists now, but does not support HTML entry points for some reason...