{"id":16641808,"url":"https://github.com/samthor/html-modules-polyfill","last_synced_at":"2025-10-26T08:45:00.790Z","repository":{"id":38417784,"uuid":"202659814","full_name":"samthor/html-modules-polyfill","owner":"samthor","description":"HTML Modules Rewriter","archived":false,"fork":false,"pushed_at":"2022-12-09T22:55:03.000Z","size":121,"stargazers_count":12,"open_issues_count":6,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-18T02:44:47.915Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/samthor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-16T04:44:54.000Z","updated_at":"2024-05-14T03:34:22.000Z","dependencies_parsed_at":"2023-01-25T23:46:27.578Z","dependency_job_id":null,"html_url":"https://github.com/samthor/html-modules-polyfill","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samthor%2Fhtml-modules-polyfill","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samthor%2Fhtml-modules-polyfill/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samthor%2Fhtml-modules-polyfill/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samthor%2Fhtml-modules-polyfill/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/samthor","download_url":"https://codeload.github.com/samthor/html-modules-polyfill/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244822734,"owners_count":20516156,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-12T07:47:57.269Z","updated_at":"2025-10-26T08:44:55.750Z","avatar_url":"https://github.com/samthor.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Rewrites HTML Modules, [as proposed here](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md), to equivalent JS modules.\nThis can enable use of HTML Modules inside a build system or in a development environment: as of August 2019, no browser has a native implementation.\n\n# Why\n\nHTML Modules are an interesting future proposal that let you wrap up script and template HTML easily (because HTML from a HTML Module is not automatically added to your global page), rather than having to create your own `\u003ctemplate\u003e` tags.\nInside a HTML Module, you can access the current scoped HTML with `import.meta.document`: see below for an example of exporting a chunk of HTML.\n\n# Usage\n\nThis is published on NPM as [html-modules-polyfill](https://www.npmjs.com/package/html-modules-polyfill).\nThe package exports a single method, `rewrite`.\n\n```js\nconst rewrite = require('html-modules-polyfill');\n\nasync function build() {\n  const htmlModuleSource = `\n\u003cdiv id=\"blogPost\"\u003e\n    \u003cp\u003eContent...\u003c/p\u003e\n\u003c/div\u003e\n\u003cscript type=\"module\"\u003e\n    let blogPost = import.meta.document.querySelector(\"#blogPost\");\n    export {blogPost}\n\u003c/script\u003e\n  `;\n  const rewritten = await rewrite(htmlSource);\n  // do something with generated source (e.g., use as output from Rollup plugin)\n}\n```\n\n## Intended Use\n\nThis single method should be used as part of a Rollup plugin, or perhaps to dynamically rewrite HTML files when fetched as modules.\nIf you check out the repository, run `./demo/rewrite.js` to see the output for [the demo module](demo/module.html).\n\n## Example Output\n\nThe output of the example above will be a single file (regardless of the number of top-level `\u003cscript\u003e` tags used) and look like:\n\n```js\nconst template = document.createElement('template');\nconst moduleDocument = document.implementation.createHTMLDocument();\ntemplate.innerHTML = `\n\u003cdiv id=\"blogPost\"\u003e\n    \u003cp\u003eContent...\u003c/p\u003e\n\u003c/div\u003e\n\u003cscript type=\"module\"\u003e\n    let blogPost = import.meta.document.querySelector(\"#blogPost\");\n    export {blogPost}\n\u003c/script\u003e\n  `;\nmoduleDocument.body.appendChild(template.content);\nimport.meta.document = moduleDocument;\n\nlet blogPost = import.meta.document.querySelector(\"#blogPost\");\n\nexport default moduleDocument;\nexport { blogPost };\n```\n\n# Implementation\n\nThe rewriter uses JSDOM and Rollup to find and concatenate every `\u003cscript type=\"module\"\u003e` found in the passed source, as well as providing the top-level `import.meta.document` based on the HTML itself.\nThese dependencies aren't exposed, you can't control their inputs, and are entirely internal dependencies.\n\nNotably, the generated HTML still includes the source `\u003cscript type=\"module\"\u003e` tags, even though they won't be executed by any browser inside a template.\n\n## Explanation\n\nWe convert every found `\u003cscript type=\"module\"\u003e` to a \"virtual\" import that is imported by a single, virtual entrypoint that we dynamically generate, which also includes the HTML template itself.\nThis entrypoint script _re-exports_ everything from each module, in order.\nWe then use Rollup to merge _just_ these virtual imports and the top-level script.\n\nExternal scripts are imported without re-exporting: i.e., `\u003cscript type=\"module\" src=\"foo.js\"\u003e\u003c/script\u003e` becomes `import './foo.js';`.\n\n# Further Work\n\nModern browsers provide a unique `import.meta` to every JS module, so adding `.document` property at run-time within a single module is fine.\n\nHowever, since most further build tools don't understand `import.meta.document` at all (although you can write [a plugin for Rollup](https://github.com/rollup/rollup/pull/2785) which does), rewritten HTML Modules that are later bundled together will probably override each other's document.\nWe should add a flag to the rewriter to use a local variable name instead (and rewrite usage) so that Rollup and other tools can play nice.\n\nAdditionally, there's no source map support ([tracked here](https://github.com/samthor/html-modules-polyfill/issues/1)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamthor%2Fhtml-modules-polyfill","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamthor%2Fhtml-modules-polyfill","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamthor%2Fhtml-modules-polyfill/lists"}