{"id":21294352,"url":"https://github.com/khc-zhihao/miniwebsitepacker","last_synced_at":"2026-07-12T01:31:24.171Z","repository":{"id":57297703,"uuid":"296934018","full_name":"KHC-ZhiHao/MiniWebsitePacker","owner":"KHC-ZhiHao","description":"簡單的網頁打包工具","archived":false,"fork":false,"pushed_at":"2022-12-19T16:40:31.000Z","size":803,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-22T06:48:02.657Z","etag":null,"topics":["buildtools","html"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/KHC-ZhiHao.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":"2020-09-19T19:04:36.000Z","updated_at":"2022-01-06T11:29:43.000Z","dependencies_parsed_at":"2023-01-29T22:15:26.268Z","dependency_job_id":null,"html_url":"https://github.com/KHC-ZhiHao/MiniWebsitePacker","commit_stats":null,"previous_names":["khc-zhihao/mini-website-packer"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KHC-ZhiHao%2FMiniWebsitePacker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KHC-ZhiHao%2FMiniWebsitePacker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KHC-ZhiHao%2FMiniWebsitePacker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KHC-ZhiHao%2FMiniWebsitePacker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KHC-ZhiHao","download_url":"https://codeload.github.com/KHC-ZhiHao/MiniWebsitePacker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243762269,"owners_count":20343979,"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":["buildtools","html"],"created_at":"2024-11-21T13:58:59.887Z","updated_at":"2025-10-17T01:10:05.488Z","avatar_url":"https://github.com/KHC-ZhiHao.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\u003cimg style=\"max-width: 300px; width: 150px\" src=\"./logo.png\"\u003e\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eMini Website Packer\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.npmjs.com/package/mini-website-packer\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/mini-website-packer.svg\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/KHC-ZhiHao/mini-website-packer\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/KHC-ZhiHao/mini-website-packer.svg?style=social\"\u003e\u003c/a\u003e\n    \u003cbr\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n這是一個快速開發靜態網站的建置工具，不需要安裝太多東西就能發布純HTML檔案，協助轉換 JS 支援 es5、auto prefix CSS 等複雜行為，甚至可以根據語系編譯 HTML，還會順便幫你壓縮圖片，適合簡單的 DEMO 網站或是形象網站。\n\n這個工具能做的不多，如果你有更複雜的需求請直接參考 webpack。\n\n## 安裝\n\n```bash\nmkdir my-static-page\ncd my-static-page\nnpm init\nnpm install mini-website-packer\nnpx mini-website-packer init\nnpx mini-website-packer serve --lang zh\n```\n\n## 開發與發佈\n\n**開啟開發模式**\n\n在開發模式中會有簡易的 hot reload 功能，選項 lang 可以指定使用哪種語言作為預覽。\n\n```bash\nnpx mini-website-packer serve --lang zh\n```\n\n**打包程式**\n\n打包後的結果會輸出在`dist`資料夾中，選項 mini 會壓縮文檔，選項 lang 則是選擇哪種語言作為主要語言，其他語言仍然會輸出自己的資料夾。\n\n```bash\nnpx mini-website-packer build --babel --mini --lang zh\n```\n\n* 使用 --mini 即壓縮所有檔案。\n* 使用 --babel 即支援相容舊瀏覽器。\n\n\u003e 如果使用 babel mode 出現 `regeneratorRuntime is not defined` 相關問題，必須引用 polyfill，可參考 [cdn](https://cdnjs.com/libraries/babel-polyfill)\n\n**唯獨模式**\n\n打包出來的檔案會經過複雜的加密過程，但仍然可以透過 HTML 上線，可以做為展示模式使用。\n\n```bash\nnpx mini-website-packer build --readonly --readonlyhost localhost\n```\n\n## 說明\n\n### 資料結構是固定的\n\nlocales、pages、static、templates 這四個資料夾是固定的。\n\n### 語法介紹\n\n#### 環境變數\n\n在 html、css 文件裡面可以被替換掉的系統變數，通常以 --{name}-- 的方式命名。\n\n##### env\n\n會有 dev、prod 兩種型態，分別代表現在是開發狀態還是部屬狀態。\n\n```js\n// 編譯前\n\u003cscript src=\"core.--env--.js\"\u003e\u003c/script\u003e\n// 編譯後\n\u003cscript src=\"core.dev.js\"\u003e\u003c/script\u003e\n```\n\n##### lang\n\n獲取當下編譯環境中的語系：\n\n```js\n// 編譯前\n\u003chtml lang=\"--lang--\"\u003e\u003c/html\u003e\n// 編譯後\n\u003chtml lang=\"zh\"\u003e\u003c/html\u003e\n```\n\n##### 自定義\n\n使用 `--conf config.json` 即可自定義自己的變數，例如我們定義主題顏色，如下：\n\n```bash\n# 部屬\nnpx mini-website-packer build --conf ./config.json --lang zh\n# 開發\nnpx mini-website-packer serve --conf ./config.json --lang zh\n```\n\nconfig.json\n\n```json\n{\n    // variables 會將變數塞入所有檔案\n    \"variables\": {\n        \"primary\": \"red\"\n    },\n    // renderData 只會在渲染階段注入全域變數或是 Handlebars 變數。\n    \"renderData\": {\n        \"users\": [\"dave\", \"james\"]\n    }\n}\n```\n\nsrc/static/style/index.css\n\n```css\n/* 編譯前 */\n* {\n    color: --primary--\n}\n/* 編譯後 */\n* {\n    color: red\n}\n```\n\n##### 高階自定義\n\n除了 config.json 外，也可以透過 js 來建構 config，只要副檔名是 `.js` 即可：\n\n\u003e 第一個參數 `handlebars` 即是 handlebars 的實例，可以讓使用者定義一些 helper 。\n\n```bash\n# 部屬\nnpx mini-website-packer build --conf ./mwp.confing.js --lang zh\n```\n\nmwp.confing.js\n\n```js\nmodule.exports = async({ handlebars }) =\u003e {\n    return {\n        variables: {\n            primary: '#EE8269',\n            secondary: '#221814'\n        }\n    }\n}\n```\n\n#### 模板\n\n使用`\u003ct-filename\u003e\u003c/t-filename\u003e`的標籤會在編譯過程中自動找尋`templates`檔案中相對應的檔案名稱，這個標籤**不支援任何Tag屬性**(例如: class)，且必須使用`\u003ctemplate\u003e\u003c/template\u003e`包裝起來，並使用`\u003cslot\u003e\u003c/slot\u003e`語法來表明插槽位置。\n\n\u003e 你也可以在模板中引用其他模板。\n\n```html\n\u003c!-- template/wrapper.html --\u003e\n\u003ctemplate\u003e\n    \u003cdiv\u003e\n        Hello，\u003cslot\u003e\u003c/slot\u003e\n    \u003cdiv\u003e\n\u003c/template\u003e\n```\n\n```html\n\u003c!-- pages/index.html --\u003e\n\u003ct-wrapper\u003eDave\u003c/t-wrapper\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003eHello，Dave\u003cdiv\u003e\n```\n\n#### Handlebars\n\n本庫原生支援 [Handlebars](https://handlebarsjs.com/)，只要將`.html`檔案改為`.hbs`副檔名即可啟用，可以借助該模板工具的邏輯來建構你的靜態網頁。\n\n\u003e 所有的 `.hbs` 檔案吃的變數都來自 `config.renderData`，但變數有兩額佔位符，分別是 `vars(環境變數)` 與 `props(模板傳遞的值)`。\n\n```html\n\u003c!-- template/wrapper.hbs --\u003e\n\u003ctemplate\u003e\n    \u003ct-wrapper.title text=\"名字是：\"\u003e\u003c/t-wrapper.title\u003e\n    {{#each users}}\n        \u003cdiv\u003e{{this}}\u003c/div\u003e\n    {{/each}}\n\u003c/template\u003e\n\n\u003ctemplate name=\"title\"\u003e\n    \u003cdiv\u003e{{ props.text }}\u003c/div\u003e\n\u003c/template\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003e名字是：\u003c/div\u003e\n\u003cdiv\u003edave\u003c/div\u003e\n\u003cdiv\u003ejames\u003c/div\u003e\n```\n\n#### 渲染模板\n\n可以使用 javascript 的邏輯來渲染模板，只要在 script 中加入關鍵字 render 就會在執行階段中執行，使用方式如下：\n\n```html\n\u003c!-- template/wrapper.html --\u003e\n\u003ctemplate\u003e\n    \u003cdiv\u003e\n        Hello，\u003cslot\u003e\u003c/slot\u003e\n    \u003cdiv\u003e\n\u003c/template\u003e\n```\n\n```html\n\u003c!-- pages/index.html --\u003e\n\u003cdiv\u003e\n    \u003cscript render\u003e\n        return '\u003ct-wrapper\u003eDave\u003c/t-wrapper\u003e'\n    \u003c/script\u003e\n\u003c/div\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003e\n    \u003cdiv\u003eHello，Dave\u003cdiv\u003e\n\u003c/div\u003e\n```\n\n你可以在此階段獲取到 `mwp` 物件，內部包含了 `variables`, `renderData`, `handlebars` 三個物件。\n\n```html\n\u003cscript render\u003e\n    return `\u003cdiv\u003e${mwp.variables.primary}\u003c/div\u003e`\n\u003c/script\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003ered\u003c/div\u003e\n```\n\n由於 render 的執行過程是在編譯階段，且支援`非同步`函數，你可以透過外部工具來建構你的應用程式，例如：\n\n```html\n\u003cscript render\u003e\n    const axios = require('axios')\n    const users = await axios.get('./users')\n    const template = `\n        {{#each peoples}}\n            \u003cdiv\u003e{{ this }}\u003c/div\u003e\n        {{/each}}\n    `\n    return mwp.handlebars.compile(template)({\n        peoples: users.data\n    })\n\u003c/script\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003edave\u003c/div\u003e\n\u003cdiv\u003ejames\u003c/div\u003e\n```\n\n#### Props\n\n在**模板**中使用`-name-`意味著這個值必須從外部傳遞。\n\n\u003e 注意空白鍵是敏感的。\n\n```html\n\u003c!-- template/wrapper.html --\u003e\n\u003ctemplate\u003e\n    \u003cdiv\u003e\n        Hello，-name-\n        Your age is -age-\n    \u003cdiv\u003e\n\u003c/template\u003e\n```\n\n```html\n\u003c!-- pages/index.html --\u003e\n\u003ct-wrapper name=\"Dave\" age=\"18\"\u003e\u003c/t-wrapper\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003e\n    Hello，Dave\n    Your age is 18\n\u003cdiv\u003e\n```\n\n#### Template Script\n\n有時候我們透過 `\u003cscript\u003e` 標籤開發並不方便，這裡提供一個專屬於 template 開發的方法：\n\n```html\n\u003c!-- template/wrapper.html --\u003e\n\u003ctemplate script=\"-name-\"\u003e\n    \u003cdiv\u003e\n        Hello，-name-\n    \u003cdiv\u003e\n\u003c/template\u003e\n```\n\n在與 html 相同檔案的路徑下建立一個同名的 js 檔案：\n\n```js\n// template/wrapper.js\n// 系統會自動執行並閉包，並傳遞一個 args 參數\nconsole.log(args)\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003e\n    Hello，Dave\n\u003cdiv\u003e\n\u003cscript\u003e\n    (function(args) {\n        console.log(args)\n    })(\"Dave\")\n\u003c/script\u003e\n```\n\n#### Children Template\n\n可以在 template file 內使用 `\u003ctemplate name=\"child\"\u003e\u003c/template\u003e` 來表明這是一個子模板，可以用`\u003ct-filename.childname\u003e`來獲取定義的子模板。\n\n\u003e 你可以在模板中引用自己的子模板，協助簡潔化程式碼。\n\n```html\n\u003c!-- template/wrapper.html --\u003e\n\u003ctemplate\u003e\n    \u003cdiv\u003e\n        Hello，\u003cslot\u003e\u003c/slot\u003e\n    \u003cdiv\u003e\n\u003c/template\u003e\n\n\u003ctemplate name=\"hi\"\u003e\n    \u003cdiv\u003e\n        Hi，\u003cslot\u003e\u003c/slot\u003e\n    \u003c/div\u003e\n\u003c/template\u003e\n```\n\n```html\n\u003c!-- pages/index.html --\u003e\n\u003ct-wrapper.hi\u003eDave\u003c/t-wrapper.hi\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003e\n    Hi，Dave\n\u003cdiv\u003e\n```\n\n#### Folder Template\n\n當然也是可以透過資料夾管理，但資料夾必須在 template 裡面才會生效，要獲取資料夾結構的模板必須用 `|` 符號分離。\n\n```html\n\u003c!-- template/home/wrapper.html --\u003e\n\u003ctemplate\u003e\n    \u003cdiv\u003e\n        Hello，\u003cslot\u003e\u003c/slot\u003e\n    \u003cdiv\u003e\n\u003c/template\u003e\n```\n\n```html\n\u003c!-- pages/index.html --\u003e\n\u003ct-home|wrapper\u003eDave\u003c/t-home|wrapper\u003e\n```\n\n#### Once\n\n可以在 template file 內使用使用 `once` 標籤，就只會執行一次。\n\n\u003e 執行一次的程式碼最終會被編譯在程式碼最下方，請注意執行順序。\n\n```html\n\u003c!-- template/wrapper.html --\u003e\n\u003ctemplate\u003e\n    \u003cdiv\u003eHello\u003cdiv\u003e\n\u003c/template\u003e\n\n\u003conce\u003e\n    \u003cstyle\u003e\n        div {\n            color: red\n        }\n    \u003c/style\u003e\n\u003c/once\u003e\n```\n\n```html\n\u003c!-- pages/index.html --\u003e\n\u003ct-wrapper\u003e\u003c/t-wrapper\u003e\n\u003ct-wrapper\u003e\u003c/t-wrapper\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003eHello\u003cdiv\u003e\n\u003cdiv\u003eHello\u003cdiv\u003e\n\u003cstyle\u003e\n    div {\n        color: red\n    }\n\u003c/style\u003e\n```\n\n#### Ref ID\n\n在 template file 中如果使用 ref 屬性，那會在獲取該 template 階段的時候配置一組隨機 id ，並取代該檔案所有的 `ref--{id}` 宣告。\n\n```html\n\u003ctemplate\u003e\n    \u003cdiv ref=\"click\"\u003e\n        Click Me!\n    \u003cdiv\u003e\n    \u003cscript\u003e\n        document.getElementById('ref--click').addEventListener('click', () =\u003e alert('hello!'))\n    \u003c/script\u003e\n    \u003cstyle\u003e\n        #ref--click {\n            cursor: pointer;\n        }\n    \u003c/style\u003e\n\u003c/template\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv id=\"click-qkgepor\"\u003e\n    Click Me!\n\u003cdiv\u003e\n\u003cscript\u003e\n    document.getElementById('click-qkgepor').addEventListener('click', () =\u003e alert('hello!'))\n\u003c/script\u003e\n\u003cstyle\u003e\n    #click-qkgepor {\n        cursor: pointer;\n    }\n\u003c/style\u003e\n```\n\n#### Script Scoped\n\n給予 `scoped` 標籤會讓內部程式碼包上一組閉包。\n\n```html\n\u003ctemplate\u003e\n    \u003cscript scoped\u003e\n        console.log('Hello.')\n    \u003c/script\u003e\n\u003c/template\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cscript\u003e\n    (function() {\n        console.log('Hello.')\n    })()\n\u003c/script\u003e\n```\n\n#### Style Scope\n\n給予 `scope` 標籤會讓內部 css 加上父類。\n\n```html\n\u003ctemplate\u003e\n    \u003cstyle scope=\".parent\"\u003e\n        div {\n            color: 'red'\n        }\n    \u003c/style\u003e\n\u003c/template\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cstyle\u003e\n    .parent div {\n        color: 'red'\n    }\n\u003c/style\u003e\n```\n\n#### 語系\n\n使用`{text}`會去找尋locales檔案中指定的語系(預設是zh)並填入，該語系檔案必須是json檔。\n\n\u003e 語系在編譯過程中會產生自己的目錄，請勿在pages中建立其語系相同名稱的資料夾以避免衝突。\n\n```js\n// locales/zh.json\n{\n    \"name\": \"Dave\"\n}\n```\n\n```html\n\u003c!-- pages/index.html --\u003e\n\u003cdiv\u003e\n    Hello {name}\n\u003c/div\u003e\n```\n\n以下是編譯後的結果：\n\n```html\n\u003cdiv\u003eHello Dave\u003cdiv\u003e\n```\n\n### 從Static獲取靜態資源\n\n當我們需要圖片或是管理css相關檔案時，請把檔案放在`static`中。\n\n\u003e 需注意的是該檔案會隨著編譯一起到專案的根目錄中，請勿在pages中建立static資料夾以避免衝突。\n\n```html\n\u003c!-- pages/index.html --\u003e\n\u003cdiv\u003e\n    \u003c!-- 這樣即可獲取static中的圖檔 --\u003e\n    \u003cimg src=\"./static/logo.png\"\u003e\n\u003cdiv\u003e\n```\n\n## 高級註解\n\n使用三減號註解可以在編譯過程中被移除，可以避免要交付的程式碼中包含自己的開發邏輯：\n\n```html\n\u003c!--- Props: title ---\u003e\n\u003cdiv\u003e-title-\u003c/div\u003e\n```\n\n使用警告註解可以在編譯過程中發出警告，目的在於給未定義的參數添加檢查提示：\n\n```html\n\u003c!--! 這裡還沒有填入資料 !--\u003e\n\u003cdiv\u003e...\u003c/div\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhc-zhihao%2Fminiwebsitepacker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkhc-zhihao%2Fminiwebsitepacker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhc-zhihao%2Fminiwebsitepacker/lists"}