{"id":21025108,"url":"https://github.com/krutsch/html-bundle","last_synced_at":"2025-05-15T08:33:40.488Z","repository":{"id":37086204,"uuid":"325346664","full_name":"Krutsch/html-bundle","owner":"Krutsch","description":"A very simple bundler for HTML SFC","archived":false,"fork":false,"pushed_at":"2025-05-06T16:30:04.000Z","size":15091,"stargazers_count":13,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-08T21:56:17.958Z","etag":null,"topics":["bundler","esbuild","html","hydro-js","sfc","typescript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Krutsch.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-12-29T17:24:27.000Z","updated_at":"2025-05-06T16:30:01.000Z","dependencies_parsed_at":"2022-06-24T15:25:02.721Z","dependency_job_id":"54a877f0-8a90-4d80-9bcd-826d4393b8ec","html_url":"https://github.com/Krutsch/html-bundle","commit_stats":{"total_commits":538,"total_committers":5,"mean_commits":107.6,"dds":"0.31226765799256506","last_synced_commit":"3ae26d6cdbd98a42c683d4d605f9bae26079a14d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Krutsch%2Fhtml-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Krutsch%2Fhtml-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Krutsch%2Fhtml-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Krutsch%2Fhtml-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Krutsch","download_url":"https://codeload.github.com/Krutsch/html-bundle/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254304837,"owners_count":22048480,"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":["bundler","esbuild","html","hydro-js","sfc","typescript"],"created_at":"2024-11-19T11:30:13.808Z","updated_at":"2025-05-15T08:33:38.324Z","avatar_url":"https://github.com/Krutsch.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# html-bundle\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./logo.jpg\" style=\"width:500px;\" /\u003e\n\u003c/p\u003e\n\nA (primarily) zero-config bundler for HTML files. The idea is to use HTML as Single File Components, because HTML can already include `\u003cstyle\u003e` and `\u003cscript\u003e` elements.\n\n## Features\n\n- 🦾 TypeScript (reference it as .js or write inline TS)\n- 📦 Automatic Package Installation\n- 💨 HMR and automatic reconnect\n- ⚡ [ESBuild](https://github.com/evanw/esbuild)\n- 🦔 [Critical CSS](https://www.npmjs.com/package/beasties)\n- 🚋 Watcher on PostCSS and Tailwind CSS and TS Config\n- 🛡️ Almost no need to restart\n\n## Demo\n\n![Demo](./example.gif)\n\n## Installation and Usage\n\n```properties\n$ npm install -D html-bundle\n```\n\nAdd an entry to script in package.json (see flags below).\n\n```json\n{\n  \"scripts\": {\n    \"build\": \"html-bundle\"\n  }\n}\n```\n\nAdd a `postcss.config.js` file and run the build command.\n\u003cem\u003eIf you do not create this config file, a minimal in-memory config file will be created with `cssnano` as plugin.\u003c/em\u003e\n\n```properties\n$ npm run build\n```\n\n## CLI\n\n`--hmr`: boots up a static server and enables Hot Module Replacement. **This generates a development build and works best when not triggered from the main index.html**\u003cbr\u003e\n`--secure`: creates a secure HTTP2 over HTTPS instance. This requires the files `localhost.pem` and `localhost-key.pem` in the root folder. You can generate them with [mkcert](https://github.com/FiloSottile/mkcert) for instance.\u003cbr\u003e\n`--isCritical`: uses critical to extract and inline critical-path CSS to HTML.\u003cbr\u003e\n`--handler`: path to your custom handler. Here, you can handle all non-supported files. You can get the filename via `process.argv[2]`.\n\n## Optional Config\n\n_The CLI flags can also be set by the config. Flags set by the CLI will override the config._\nGenerate the config in the root and call it \"bundle.config.js\"\n\n**src:** input path. Default to \"src\"\u003cbr\u003e\n**build:** output path. Defaults to \"build\"\u003cbr\u003e\n**port:** For the HMR Server. Defaults to 5000\u003cbr\u003e\n**deletePrev:** Whether to delelte the build folder. Defaults to true\u003cbr\u003e\n**esbuild:** Your additional config\u003cbr\u003e\n**html-minifier-terser:** Your additional config\u003cbr\u003e\n**critical:** Your additional config\u003cbr\u003e\n\nExample:\n\n```javascript\n/** @type {import('html-bundle').Config} */\nexport default {\n  secure: true,\n  handler: \"utils/staticFiles.js\",\n  esbuild: {\n    external: [\"images\"],\n  },\n};\n```\n\n## Concept\n\nThe bundler always globs all HTML, CSS and TS/JS files from the `src` (config) directory and processes them to the `build` (config) directory. PostCSS is being used for CSS files and inline styles, html-minifier-terser for HTML and esbuild to bundle, minify, etc. for inline and referenced TS/JS. Server-sent events and [hydro-js](https://github.com/Krutsch/hydro-js) are used for HMR. In order to trigger SPA Routers, the popstate event is being triggered after HMR Operations.\n\n## Example hydro-js\n\nGet the idea from [hydro-starter](https://github.com/Krutsch/hydro-starter).\u003cbr\u003e\nSet `\"jsxFactory\": \"h\"` in `tsconfig.json` for JSX.\n\n### Input\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"UTF-8\" /\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /\u003e\n    \u003ctitle\u003eExample\u003c/title\u003e\n    \u003cmeta name=\"Description\" content=\"Example for html-bundle\" /\u003e\n    \u003cscript type=\"module\"\u003e\n      import { render, h, reactive } from \"hydro-js\";\n\n      function Example({ name }) {\n        return \u003cmain id=\"app\"\u003eHi {name}\u003c/main\u003e;\n      }\n\n      const name = reactive(\"Tester\");\n      render(\u003cExample name={name} /\u003e, \"#app\");\n    \u003c/script\u003e\n    \u003cstyle\u003e\n      body {\n        background-color: whitesmoke;\n      }\n    \u003c/style\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cmain id=\"app\"\u003e\u003c/main\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Example Vue.js\n\nSet `\"jsxFactory\": \"h\"` in `tsconfig.json`.\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"UTF-8\" /\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /\u003e\n    \u003ctitle\u003eVue Example\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cscript type=\"module\"\u003e\n    import { createApp, h } from \"vue\";\n\n    const App = {\n      data() {\n        return {\n          name: \"Fabian\",\n        };\n      },\n      render() {\n        return \u003cp\u003e{this.name}\u003c/p\u003e;\n      },\n    };\n\n    createApp(App).mount(\"#app\");\n  \u003c/script\u003e\n  \u003cbody\u003e\n    \u003cdiv id=\"app\"\u003e\u003c/div\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Example React\n\nSet `\"jsxFactory\": \"React.createElement\"` in `tsconfig.json`.\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"UTF-8\" /\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /\u003e\n    \u003ctitle\u003eReact Example\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cscript type=\"module\"\u003e\n    import React, { useState } from \"react\";\n    import { createRoot } from \"react-dom/client\";\n\n    function Example() {\n      const [count, setCount] = useState(0);\n\n      return (\n        \u003cdiv\u003e\n          \u003cp\u003eYou clicked {count} times\u003c/p\u003e\n          \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003eClick me\u003c/button\u003e\n        \u003c/div\u003e\n      );\n    }\n\n    createRoot(document.getElementById(\"app\")).render(\u003cExample /\u003e);\n  \u003c/script\u003e\n  \u003cbody\u003e\n    \u003cdiv id=\"app\"\u003e\u003c/div\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrutsch%2Fhtml-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrutsch%2Fhtml-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrutsch%2Fhtml-bundle/lists"}