從零開始使用 **Taki + Node.js** 實現動態網頁轉靜態網站的完整代碼方案

以下是從零開始使用 Taki + Node.js 實現動態網頁轉靜態網站的完整代碼方案,包含預渲染、自動化構建、靜態托管及優化功能:

一、環境準備

1. 初始化項目
mkdir static-site && cd static-site
npm init -y
2. 安裝依賴
npm install taki express fs-extra path

二、完整代碼 (generate.js)

const { request, cleanup } = require('taki');
const express = require('express');
const fs = require('fs-extra');
const path = require('path');// 配置參數
const config = {dynamicSiteUrl: 'http://localhost:3000', // 動態網站本地運行地址outputDir: path.join(__dirname, 'dist'), // 靜態文件輸出目錄routes: ['/', '/about', '/product/:id'], // 需靜態化的路由(支持動態參數)puppeteerOptions: { headless: "new" }, // 使用新版無頭模式resourceFilter: req => !['image', 'font'].includes(req.resourceType()), // 過濾非關鍵資源retries: 3 // 失敗重試次數
};// 1. 生成靜態頁面核心邏輯
async function generateStaticPage(url, outputPath) {let retry = 0;while (retry < config.retries) {try {const html = await request({url,wait: 2000, // 等待頁面渲染puppeteerOptions: config.puppeteerOptions,resourceFilter: config.resourceFilter,htmlSelector: 'body', // 僅抓取body內容(可選)manually: true // 手動觸發快照(等待異步加載)});await fs.outputFile(outputPath, html);console.log(`? 生成成功: ${path.basename(outputPath)}`);return;} catch (err) {retry++;console.error(`? 失敗重試 ${retry}/${config.retries}: ${err.message}`);}}throw new Error(`頁面生成失敗: ${url}`);
}// 2. 批量生成靜態文件
async function generateAllPages() {await fs.emptyDir(config.outputDir); // 清空舊文件for (const route of config.routes) {const dynamicParam = route.match(/:\w+/g)?.[0] || '';const fileName = route.replace(/:\w+/g, '[param]') + '.html';const outputPath = path.join(config.outputDir, fileName);const fullUrl = `${config.dynamicSiteUrl}${route}`;await generateStaticPage(fullUrl, outputPath);}
}// 3. 啟動靜態服務器
function startServer() {const app = express();const port = 3001;// 托管靜態資源(帶緩存優化)app.use(express.static(config.outputDir, {maxAge: '1d',setHeaders: (res) => res.set('Cache-Control', 'public, max-age=86400')}));// 處理SPA路由重定向app.get('*', (req, res) => {res.sendFile(path.join(config.outputDir, 'index.html'));});app.listen(port, () => {console.log(`🚀 靜態服務器運行于 http://localhost:${port}`);});
}// 4. 主流程控制
(async () => {try {await generateAllPages();startServer();} catch (err) {console.error('🔥 嚴重錯誤:', err);process.exit(1);} finally {await cleanup(); // 釋放Puppeteer資源}
})();

三、使用說明

1. 運行動態網站

確保你的 React/Vue 等動態網站在本地 http://localhost:3000 運行。

2. 啟動靜態生成
node generate.js
3. 訪問靜態站點

打開瀏覽器訪問 http://localhost:3001,所有頁面將以靜態形式呈現。


四、進階功能擴展

1. 動態參數處理(示例)

若路由為 /product/:id,將生成 /product/[param].html,Express 會自動匹配如 /product/123 的請求。

2. SEO 優化

generateAllPages 函數末尾添加:

// 生成sitemap.xml
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">${config.routes.map(route => `<url><loc>https://your-domain.com${route.replace(/:\w+/g, '')}</loc></url>`).join('')}
</urlset>`;
await fs.writeFile(path.join(config.outputDir, 'sitemap.xml'), sitemap);
3. 自動化部署腳本 (deploy.sh)
#!/bin/bash
node generate.js
tar -czvf dist.tar.gz dist/
scp dist.tar.gz user@server:/var/www/html
ssh user@server "tar -xzvf /var/www/html/dist.tar.gz"

五、技術要點解析

  1. Taki 核心能力

    • 基于 Puppeteer 實現無頭瀏覽器渲染,抓取動態內容139
    • 支持資源過濾(過濾圖片/字體)提升生成速度139
  2. Express 優化

    • 靜態資源托管 + 緩存控制,提升訪問速度4770
    • SPA 路由重定向解決 History 模式 404 問題25
  3. 可靠性設計

    • 失敗重試機制應對網絡波動23
    • 自動清理舊文件避免冗余34

六、與其他方案對比

方案適用場景優勢工具鏈推薦
Taki 預渲染SPA/動態內容快速靜態化無需改源碼,支持復雜交互Taki + Express
Next.js SSG新項目開發增量生成,開發體驗好Next.js + Vercel
純靜態生成器內容驅動型站點(博客)生成速度快,適合 MarkdownHugo/Jekyll

七、常見問題

  1. 圖片路徑錯誤

    • 在 Taki 配置中添加資源替換邏輯:
      html = html.replace(/src="\/assets\//g, 'src="assets/');
      
  2. 動態內容更新

    • 結合 Webhook 觸發定時重新生成

完整代碼參考:Taki 官方文檔

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73662.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73662.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73662.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

商業智能BI分析中,汽車4S銷售行業的返廠頻次有什么分析價值?

買過車的朋友會發現&#xff0c;同一款車不管在哪個4S店去買&#xff0c;基本上價格都相差不大。即使有些差別&#xff0c;也是帶著附加條件的&#xff0c;比如要做些加裝需要額外再付一下費用。為什么汽車4S銷售行業需要商業智能BI&#xff1f;就是因為在汽車4S銷售行業&#…

靜態鏈接過程發生了什么?

在靜態鏈接過程中主要發生了兩件事。一是空間與地址分配&#xff0c;鏈接器掃描所有輸入文件的段&#xff0c;合并相似段并且重新計算段長度和在虛擬內存中的映射關系&#xff0c;收集所有的符號放到全局符號表中。二是符號解析與重定位&#xff0c;鏈接器收集所有的段信息和重…

? 一次有趣的經歷

&#x1f4c6;2025年3月17日 | 周一 | ??晴 &#x1f4cd;今天路過學院樓7&#xff0c;見到了滿園盛開的花&#x1f33a;&#xff0c;心情瞬間明朗&#xff01; &#x1f4cc;希望接下來的日子也能像這些花一樣&#xff0c;充滿活力&#x1f525;&#xff01; &#x1…

docker安裝redis

第一步&#xff1a;docker拉取redis鏡像 這種命令如果沒有指定版本則是最新版本&#xff1a;docker pull redis 成功了 docker images 查詢已經拉取成功鏡像 然后因為在容器內部我們修改redis的配置不好修改&#xff0c;所以我們可以進行掛載配置文件 這個配置文件可以方便…

C語言學習筆記(第三部份)

說明&#xff1a;由于所有內容放在一個md文件中會非常卡頓&#xff0c;本文件將接續C_1.md文件的第三部分 整型存儲和大小端 引例&#xff1a; int main(void) {// printf("%d\n", SnAdda(2, 5));// PrintDaffodilNum(10000);// PrintRhombus(3);int i 0;int arr[…

Cortical Labs公司CL1人腦芯片:開啟生物智能計算新時代

Cortical Labs公司CL1人腦芯片&#xff1a;開啟生物智能計算新時代 在科技飛速發展的今天&#xff0c;人工智能已經深入到我們生活的各個角落&#xff0c;但隨著其發展&#xff0c;也面臨著能耗高、效率有限等諸多挑戰。為了突破這些瓶頸&#xff0c;科學家們開始探索將生物學…

Python學習第十八天

Django模型 定義&#xff1a;模型是 Django 中用于定義數據庫結構的 Python 類。每個模型類對應數據庫中的一張表&#xff0c;類的屬性對應表的字段。 作用&#xff1a;通過模型&#xff0c;Django 可以將 Python 代碼與數據庫表結構關聯起來&#xff0c;開發者無需直接編寫 S…

Windows 圖形顯示驅動開發-WDDM 3.0功能- 硬件翻轉隊列(一)

WDDM 3.0 之前的翻轉隊列模型 許多新式顯示控制器支持對按順序顯示的多個幀排隊的能力。 從 WDDM 2.1 開始&#xff0c;OS 支持將在下一個 VSync 中顯示的多個未完成的翻轉覆蓋請求。 顯示微型端口驅動程序 (KMD) 通過 DXGK_DRIVERCAPS 中的 MaxQueuedMultiPlaneOverlayFlipVS…

《Python深度學習》第二講:深度學習的數學基礎

本講來聊聊深度學習的數學基礎。 深度學習聽起來很厲害,其實它背后是一些很有趣的數學原理。本講會用簡單的方式解釋這些原理,還會用一些具體的例子來幫助你理解。 2.1 初識神經網絡 先從一個簡單的任務開始:識別手寫數字。 想象一下,你有一堆手寫數字的圖片,你想讓計算…

車載DoIP測試 --- CANoe DoIP中如何配置路由激活請求中的 OEM 特定場(RoutingActivationWithOEMSpecific)

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

JDBC數據庫連接池技術詳解——從傳統連接方式到高效連接管理

1. 引言 在開發數據庫應用時&#xff0c;我們通常需要與數據庫建立連接并執行SQL語句。傳統的JDBC連接方式雖然簡單直接&#xff0c;但在高并發場景下容易帶來性能問題&#xff0c;甚至導致系統崩潰。因此&#xff0c;引入數據庫連接池&#xff08;Connection Pool&#xff09…

【工具類】PDF文件轉圖片

PDF文件轉文件 1. 引入Maven依賴 主要使用了 pdfbox 包與 hutool 包。 pdfbox 負責 pdf 到圖片的轉換&#xff1b; hutool 負責文件讀取轉換。 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version…

使用DeepSeek,優化斐波那契數函數,效果相當不錯

下面這段代碼定義了一個遞歸函數 fibonacci&#xff0c;用于計算第 n 個斐波那契數。 def fibonacci(n):if n < 1:return nelse:return fibonacci(n - 1) fibonacci(n - 2)雖然代碼邏輯正確&#xff0c;但其性能較差&#xff0c;尤其是對于較大的 n 值&#xff0c;其復雜度…

Forward Looking Radar Imaging by Truncated Singular Value Decomposition 論文閱讀

Forward Looking Radar Imaging by Truncated Singular Value Decomposition and Its Application for Adverse Weather Aircraft Landing 1. 論文的研究目標與意義1.1 研究目標1.2 實際問題與意義2. 論文的創新方法與公式解析2.1 信號建模與問題轉化2.2 截斷奇異值分解(TSVD)…

provide/inject源碼實現

在 Vue 3 中&#xff0c;provide 和 inject 是通過 Vue 的響應式系統和組件實例機制實現的&#xff0c;底層是依賴 Vue 3 中的 Proxy 和 Reactive 來實現跨層級的數據傳遞和響應式綁定。以下是一個簡化版的實現邏輯&#xff0c;幫助理解 Vue 3 中 provide 和 inject 是如何實現…

Unix時間戳BKP備份寄存器RTC實時時鐘

Unix時間戳 Unix時間戳&#xff0c;也稱為POSIX時間或Epoch時間&#xff0c;是一種在Unix和類Unix操作系統中使用的時間表示方法。它表示的是自1970年1月1日00:00:00 UTC&#xff08;協調世界時&#xff09;至當前時間經過的秒數&#xff0c;不考慮閏秒。Unix時間戳通常以秒為…

【Linux內核系列】:進程板塊與文件板塊的綜合

&#x1f525; 本文專欄&#xff1a;Linux &#x1f338;作者主頁&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客勵志語錄&#xff1a; 人生中成功只是一時的&#xff0c;失敗卻是人生的主旋律&#xff0c;但是如何面對失敗卻把人分成了不同的樣子&#xff0c;有的人會被…

CellOracle|基因擾動研究基因功能|基因調控網絡+虛擬干預

在gzh“生信小鵬”同步文章 論文來源: 發表期刊:Nature發表時間:2023年2月23日論文題目:Dissecting cell identity via network inference and in silico gene perturbation研究團隊:Kenji Kamimoto 等,華盛頓大學醫學院1. 研究背景與問題提出 細胞身份(Cell Identit…

專線、云 和 物聯網(IoT)

專線、云 和 物聯網&#xff08;IoT&#xff09; 是現代信息與通信技術&#xff08;ICT&#xff09;領域的三大重要組成部分&#xff0c;它們在企業和個人的數字化轉型中扮演著關鍵角色。以下是對這三者的詳細介紹及其相互關系&#xff1a; 1. 專線&#xff08;Leased Line&…

[Lc14_priority_queue] 最后一塊石頭重量 | 數據流中的第 K 大元素 | 前K個高頻單詞 | 數據流的中位數

目錄 1.最后一塊石頭的重量 題解 2.數據流中的第 K 大元素 題解 3.前K個高頻單詞 題解 代碼 ?4.數據流的中位數 題解 在C中&#xff0c;使用標準庫中的priority_queue&#xff0c;默認情況下它是一個最大堆&#xff08;即大堆排序&#xff09;&#xff0c;這意味著最…