🔍 搜尋結果:javasc

🔍 搜尋結果:javasc

簡短概述:微前端 🧩

當人們談論**微前端**時,他們首先提到的就是其驚人的擴展能力。他們透過將服務分成更小的部分並無縫協作來實現這一目標。 微前端的優勢👍 ------- - **微前端**支援團隊可以實現後續前端功能,從而顯著加快迭代速度。 - 微前端的**水平可擴展性**旨在使組織能夠透過水平擴展來擴展其前端架構。 📈 微前端的缺點👎 ------- - 微前端會使網站的開發、維護和建置**變得複雜**。然而,可以透過使用智慧設計、有助於自動部署和測試的工具以及確保團隊之間的清晰溝通來緩解這些挑戰。 📉 - 如果團隊之間不進行溝通,**依賴管理**可能會成為問題。但可以透過在團隊之間建立清晰的溝通管道來討論更新來解決! 👌 單體應用程式經常遇到有效擴展的挑戰。透過將前端分解為微前端,可以更有效地實現延遲載入和**服務工作者**等高階邏輯結構。 **JavaScript 的**靈活性允許團隊加入各種框架和程式庫,從而促進微前端之間的無縫整合和互通性。豐富的 JavaScript 工俱生態系統為開發人員提供了強大的資源來建立動態和響應式的使用者介面。 - 受到以下書的啟發: [***建立微前端、擴展團隊和專案、為開發人員提供支援***。](https://www.amazon.com/Building-Micro-Frontends-Projects-Empowering-Developers/dp/1492082996/ref=sr_1_2?crid=RCBAUE4OKJ0J&dib=eyJ2IjoiMSJ9.0ZJp2IXMP9BkahJYaiHl9ez2Wm6vlnMHRLwunki8JYstYZfM_ukCSBNN1JAldlIqkOUuSa70q6nEYv5Rle1a2vzND0PJ_BEBt_kCHgnNjO9tg-Kp9V1tGAtMW7QtLmY53ZAuOFX4lfXTM2DTu5KCUiwIHGHiERCZ9ehXTueraXmWd4AAl5aP6VkEgs56_BamuYAo7pHw1nb6ceTIouGXkdImZ4fB-y81_da06oyWRY8.601H27Rq2LULtNXKVir3Z3QOGJlbx6ovOrmk3Iny2Bg&dib_tag=se&keywords=micro+frontend&qid=1717013751&sprefix=microfronten,aps,223&sr=8-2)作者:*盧卡‧梅札里拉 (Luca Mezzalira) 尼爾‧福特 (Neal Ford) 作序* 加入我們! ----- 那麼...您喜歡 Javascript 並想為開源專案做出貢獻嗎?**你在等什麼?** 😁 前往[Webcrumbs](https://www.webcrumbs.org/)並加入一個致力於為開源愛好者提供 JavaScript 生態系統的社群! --- 原文出處:https://dev.to/buildwebcrumbs/short-overview-micro-frontends-2f5i

為什麼 Theo 是錯的 & 我們會得到一個 JavaScript 版的 Laravel

JavaScript 對全端框架的需求 ------------------- 「*為什麼我們沒有適用於 JavaScript 的 Laravel?」。*這是[西奧在他最近的影片中提出的](https://www.youtube.com/watch?v=yaodD79Q4iE)問題。 如果您不熟悉[Laravel](https://laravel.com/)和[Ruby-on-Rails](https://rubyonrails.org/)等工具,它們是固執己見的全端框架(適用於 PHP 和 Ruby),具有許多遵循既定約定的內建功能,以便開發人員可以編寫更少的樣板檔案和更多的業務邏輯,同時將行業最佳實踐融入他們的應用程式中。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dndfaz2hjet9nisbiimc.png) 他回答這個問題時認為 JavaScript*不需要*這樣的框架,因為最好選擇你想要的工具並自己建立你需要的解決方案。 這聽起來很棒——如果你是一位經驗豐富的開發者,這也恰好是一個很好的靈活性——但我覺得他並沒有很好地支持這一說法,**我來這裡是為了告訴你我認為他錯在哪裡**。 在我看來,更好的問題是為什麼我們*還*沒有適用於 JavaScript 的 Laravel?答案是我們仍在努力。 在他對 JavaScript 世界中可以與 Laravel 或 Rails 相媲美的全端框架的總結中,他沒有考慮到一些重要的點: 1. **人們真的想要一個 Laravel/Rails for JavaScript** 。如果他們不這樣做,就不會進行如此多的嘗試來建立一個,他也不會製作一個影片,其唯一目的是回應“*為什麼 JAVASCRIPT 沒有自己的 Laravel!?* 」 2. **他沒有考慮 JS 生態系中底層工具的時機和成熟度**。也許並不是說 Laravel for JavaScript*不需要*存在,只是由於生態系統本身存在一些重大差異,例如它們的歷史有多長以及創新主要發生在哪裡,所以它還不存在。 3. **他也沒有詢問這些類型的解決方案適合誰**。當然,並非所有開發人員都有相同的目標,因此有些人可能會選擇可組合方法,而有些人則喜歡使用框架。 那麼讓我們看看我們是如何走到今天這一步的,以及我們如何能夠將像 Laravel 或 Rails 這樣的全端框架引入 JavaScript 世界。 完成任務 ---- 在他的影片中,Theo 提出了這樣一個觀點:「*現在 React 世界裡有一句俗話,那就是『如果你不使用框架,那麼你就在建立一個框架』」。*批評,Theo 認為大多數JavaScript 開發人員都沒有抓到重點,建立自己的「自己的框架」實際上是一種優勢。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5ft5f1j2zemurcvvzzk.png) 他認為 JavaScript 生態系統的模組化特性是一個巨大的優勢,但這聽起來對普通開發人員來說承受著很大的壓力,需要做出不必要的判斷呼叫並管理大量樣板程式碼。 當然,您的團隊需要創新並滿足特殊用例的需求。這些是優先考慮模組化的。他們盡可能調整、改進和榨取開發人員體驗 (DX) 和性能,以正確完成他們獨特的工作。 但另一方面,也有許多團隊的主要目標是在他們正在建立的產品方面創造價值和創新,而不是他們用來建立產品的工具。這些開發人員會青睞一個允許他們只專注於業務邏輯的框架。這為他們提供了一種穩定的方式來建立具有最佳實踐的東西,以便他們可以輕鬆地從一個專案推進到另一個專案。在這個陣營中,還有精幹、刻薄的獨立駭客,他們正在尋找框架,以便他們能夠快速行動並將想法推向市場! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/21tanpp8rmrboal0jl57.png) 這有點像Mac和Linux之間的差別。 Mac 的統一堆疊開箱即用,這意味著許多專業人士因其生產力而喜歡它,而如果您尋求靈活性並有時間和知識來根據自己的需求進行調整,那麼 Linux 是很棒的選擇。兩者都是有效的解決方案,可以共存以滿足不同的需求。 這種對生產力的關注使得 Rails 在當時如此強大,也是 Laravel 目前如此受歡迎的框架的原因。建立這樣一個 JavaScript 框架的多次嘗試足以證明,有很大一部分 JavaScript 開發人員也想要這樣的解決方案。 但也許這樣一個框架還不存在的原因與開發人員是否想要一個框架無關,而是為了使這樣一個框架組合在一起所需的重要因素直到現在才協調一致。為了使這樣的框架廣泛採用,它首先需要足夠穩定的底層技術來建造。之後,它需要時間和許多迭代周期才能達到成熟度,以便開發人員可以放心採用它。 這些因素在 JavaScript 世界中是否一致,為我們提供了 PHP 和 Ruby 已經擁有的框架類型?也許還沒有,但他們似乎正在慢慢走在一起。 比較生態系統 ------ Theo 的要點之一是JavaScript 作為一種語言能夠實現一定程度的模組化和可組合性,而Ruby 和PHP 等語言則無法做到這一點,這就是為什麼Ruby 和PHP 生態系統可以得到全端框架的良好服務,但JavaScript*不需要因為*你可以自己創作東西。 雖然 JavaScript 是一種特殊的語言,它支援函數式和命令式範式以及動態特性,但它也有很多缺陷(儘管它最近已經有了很大的改進),所以你通常不會聽到它在就像西奧在這裡所做的那樣。事實上,您可能更有可能聽到 Ruby 及其作為模組化和靈活語言特性的讚揚。 因此,如果 JavaScript 作為一種語言的一些獨特屬性使它成為 Web 開發之王,那麼它又是什麼呢? ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r051nlojgrvt9crc03jd.png) 嗯,答案非常簡單: **JavaScript 是瀏覽器的語言**。 *早在*大多數 Web 開發都發生在伺服器端的時候,PHP、Java、Ruby 和其他語言佔據了主導地位。在這個時代,開發人員只會用 JavaScript 寫一小部分功能,因為大部分的工作都是在伺服器端處理。 但隨著Web 開發的發展,我們開始建立更豐富的應用程式,具有更動態、響應更快和即時的功能,許多程式碼從伺服器轉移到客戶端上的JavaScript,因為它(基本上)是唯一可以實現的語言。因此,您不再主要使用 PHP 或 Ruby 進行開發,並在其中撒上一點 JavaScript,而是將應用程式劃分為客戶端上的大量 JavaScript,以及伺服器上的 Ruby 或 PHP。 隨著 NodeJS 的到來以及在伺服器上編寫 JavaScript 的能力,JavaScript 的最後一個權力舉措隨之而來,這鞏固了它作為 Web 開發語言之王的地位。如今,開發人員可以(而且確實)用 JavaScript 編寫整個應用程式。這意味著您需要更少地了解一種語言,同時您也可以在前端和後端之間共用程式碼。這為前端和後端之間更好的整合開闢了一條途徑,它已經像滾雪球一樣進入了我們今天所知的生態系統。 因此,與其說 JavaScript 作為語言的獨特屬性使其成為 Web 開發的主導生態系統,不如說是其作為唯一可用於編寫客戶端程式碼的語言的獨特壟斷地位,而且它還可以用於伺服器 -邊。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ulc5eo5qu3a0nuv6bnv5.png) 正如 Theo 所說,「在 JavaScript 生態系統中*,我們有無數的人正在製定出色的解決方案*」。這是正確的。正是那些在該領域工作的無數開發人員為 JavaScript 建立了靈活性和模組化解決方案,而不是程式語言的固有品質。 由於 JavaScript 生態系統仍然是最熱門的生態系統,因此它擁有最多的開發人員,同時每天不斷吸引新的開發人員。這意味著我們擁有一個龐大、多元化的社區,主要做兩件事: 1. 創新 2. 大樓 創新者(和影響者)往往聲音最大,因此輿論很大程度上偏向他們。但也有很多建築或「正常」使用正在發生!只是創新者往往代表建設者說話。 那麼,鑑於 JavaScript 生態系統中正在發生的一切,嘗試為 JavaScript 開發人員建立一個持久的框架是否毫無意義,正如 Theo 所建議的那樣,或者無論創新者如何聲稱,我們是否都在實現這一目標? 顯示您正在使用的內容 ---------- Theo 也提到了目前一些 JavaScript 框架的名字,這些框架要么未能成功,要么在成為全面的全端解決方案時「*似乎無法做到正確*」。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/susa9icldz2hzysqo1qm.png) 他的觀點確實有道理。到目前為止,像[Blitz](https://blitzjs.com/) 、 [Redwood](https://redwoodjs.com/) 、 [Adonis](https://adonisjs.com/)或[T3](https://create.t3.gg/)這樣的解決方案還沒有能夠像 Rails 或 Laravel 一樣在其生態系統中普及。 **但這些事情需要時間。** 看看上面的圖表。 Laravel 和 Rails 已經存在了 13-15 年!相較之下,使用的 JavaScript 框架才剛起步,其中一些框架(例如[Wasp](https://wasp-lang.dev)和[Redwood](https://redwoodjs.com/) )正處於與 Laravel 和 Rails 最初幾年類似的開發階段。 正如您所看到的,好的解決方案需要時間才能成熟。即使其中一些框架開始停滯其最初的巨大增長,也證明對這些工具的需求確實存在! 困擾這些工具的主要問題是 Javascript 作為一個生態系統正在快速發展,因此對於像這樣的解決方案要長期生存,它不僅需要足夠固執己見,而且還需要足夠模組化以跟上生態系統的變化。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/biqe18hoeb6d06ughjhh.png) 阻止框架達到這種狀態的一個因素是與錯誤的技術連結得太緊密。這是 BlitzJS 的 NextJS、Redwood 的 GraphQL 和 MeteorJS 的 Blaze。另一個因素是框架*不夠大*,因為在JavaScript 生態系統中,這似乎是一項過於艱鉅的任務,在這個生態系統中,事情發展得很快,每個人都“害怕固執己見”,因為他們可能會受到現場最響亮聲音的批評。 換句話說,避免自行發展壯大並*真正*實現全端的框架(如 Ruby-on-Rails 和 Laravel)就錯過了解決持續困擾 JavaScript 開發人員的最常見痛點的機會。 但是,JavaScript 生態系統正在成熟和穩定,我們正在從以前的嘗試中學習,並且*將會*出現一個足夠大膽的全端框架,可以一路走下去,做足夠多的事情,並堅持足夠長的時間以確保其地位。 向黃蜂打個招呼 ------- Theo 在比較當今市場上的 JavaScript 框架時,也沒有提到我們目前正在開發的 React 和 NodeJS 全端框架[Wasp](https://wasp-lang.dev) 。 我們一直在努力讓[Wasp](https://wasp-lang.dev)成為*真正的*全端框架,滿足 Web 開發人員的需求,並填補 JavaScript 生態系統的空白,成為他們喜歡使用的框架。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7j67hychqw770nrau3f.png) **對於 Wasp,我們決定做大、有主見、真正的全端**。換句話說,我們將*全力支持*這個框架。 這意味著從首要原則出發思考並設計一種只有Wasp 使用的新穎方法,例如為我們的配置語言建置我們自己的編譯器,並真正實現全棧,同時保持其足夠的模組化,以便隨著生態系統的發展與生態系統一起發展。 這意味著我們在一開始就花了更多的時間嘗試不同的方法並建立基礎,最終從 2023 年底開始使我們的使用量大幅躍升。 今天看到 Wasp 被用來發布大量新應用程式和業務,甚至被一些大公司和組織內部使用(更多資訊很快就會正式發布),這對我們來說真的很酷! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1eo9feum42heb2qcua9o.png) Wasp 與 JavaScript 世界中其他全端框架的不同之處在於,它將主要抽象層分離到自己的設定檔`main.wasp`中。這個設定檔為Wasp 提供了處理大量樣板檔案、以基礎設施為中心的程式碼所需的知識,並允許它擁有這個獨特的初始編譯時步驟,在該步驟中,它能夠在生成Web 應用程式之前推理出您的Web 應用程式在後台為其編寫程式碼(在生成它時使用該知識)。 實際上,這意味著您所要做的就是在 Wasp 的設定檔中高層描述您的 Wasp 應用程式,然後使用您熟悉的技術(例如 React、NodeJS 和 Prisma)實現其他所有內容。這也意味著 Wasp 具有很高的模組化潛力,這意味著我們正在建立它來支援未來的其他前端框架,如 Vue、Solid 或 Svelte,甚至支援其他後端語言,如 Python、Go 或 Rust。 如果您是那種希望存在 Rails 或 Laravel for JavaScript 的開發人員,那麼您應該[嘗試 Wasp](https://wasp-lang.dev/) (然後[進入我們的 Discord](https://discord.gg/rzdnErX) ,讓我們知道您的想法)! 我們要去哪裡? ------- 我們堅信 JavaScript 將會有一個全端框架,就像 PHP 的 Laravel 和 Ruby 的 Ruby-on-Rails 一樣。 目前看來,我們仍在努力實現這一目標。鑑於當前元框架和堆疊(例如 NextJS 和 T3)的流行,我們似乎很快就會實現這一目標。 但這些東西需要時間和耐心。 另外,你必須有足夠的勇氣去嘗試新的東西,因為你知道你的工作會受到生態系統中一些最響亮的聲音的批評。 這就是我們所準備的,也是我們*全力*支持黃蜂的原因。 到時候那裡見! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nig9t4pr85jqtz536frn.png) --- 原文出處:https://dev.to/wasp/why-we-dont-have-a-laravel-for-javascript-yet-45bi

PHP:Laravel,Ruby:Rails,JavaScript:?

最近,Twitter 上發生了 JS 開發者與 Laravel 和 Rails 開發者之間的熱烈討論。它始於 Laravel 的作者 Taylor Otwell 的一條長推文: https://twitter.com/taylorotwell/status/1791468060903096422 簡而言之,他認為整個 JavaScript 生態系統缺乏像 Laravel 或 Rails 這樣真正的「全端」框架,而這些框架可以讓單一開發人員建立下一個 GitHub、AirBnb 或 Shopify。 我對此深表同情,因為我在建立[ZenStack](https://zenstack.dev/) (Prisma ORM 之上的打字稿工具包)時有著相同的目標。事實上,我常在社區裡聽到這樣的話: ![聊天影像](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vikbshwmv16hxolkhw2s.png) 沒有人可以否認 JS 生態系統的受歡迎程度和快速增長,即使在非會員中也是如此。那麼這是為什麼呢? 歷史原因 ---- > 人們創造自己的歷史,但他們並不是隨心所欲地創造歷史;他們不是在自我選擇的環境下成功的,而是在已經存在的、給定的、從過去傳承下來的環境下成功的——卡爾·馬克思 PHP 和 Ruby 從一開始就被設計為伺服器端語言。 PHP 於 1994 年建立,用於建立動態網頁,而 Ruby 於 20 世紀 90 年代中期出現,是為通用程式設計而設計的。 鑑於它們的伺服器端起源,PHP 和 Ruby 自然適合綜合框架,可以處理 Web 開發的各個方面,從路由和控制器到資料庫互動和模板引擎。這導致了 Laravel 和 Rails 等框架的建立,以提供完整的、固定的方式來建立 Web 應用程式。 相較之下,JavaScript 是作為網頁瀏覽器的客戶端腳本語言而誕生的。直到 2009 年 Node.js 推出之前,它與後端無關。如果您聽說過 Netscape Navigator 和 Internet Explorer 之間的“瀏覽器戰爭”,您可能會意識到前端中持續存在的混亂,這種混亂今天繼續以瀏覽器兼容性的名義讓前端開發人員瘋狂。因此,早期的網路是將不同的技術拼湊在一起。因此,JavaScript 開發人員開始習慣模組化,允許靈活地混合和匹配庫和工具以求生存。這就是為什麼與 Node.js 一起出現的 NPM 以驚人的速度成長,迅速成為世界上最大的軟體註冊中心。 這種不同的情況導致了不同的開發人員文化: - **PHP/Ruby 開發人員:** “給我一個可以正常工作的框架。我想要約定、穩定性和清晰的交付路徑。” - **JS 開發人員:** “不要限制我!我想要靈活性、最新的工具以及以我的方式建置的自由,即使這意味著需要更多的前期工作。” 因此,即使擴展到後端世界之後,單一的、「一刀切」的方法也很難在 Javascript 生態系統中行得通。 當代努力 ---- 一方面,這種文化導致不斷的演變,使整個生態系統保持興奮和創新。然而,這也會導致新人更決策疲勞和更陡峭的學習曲線。 “哪裡有泥土,哪裡就有黃銅。”有些人踏上了冒險之旅,建造一個類似 Rails 的、包含電池的框架來挑戰現狀。以下是一些流行的例子: - [redwoodjs](https://redwoodjs.com/) ``` Full-stack JavaScript framework that integrates React, GraphQL, and Prisma. It simplifies development with a unified setup and automatic code generation, perfect for scalable applications. ``` - [blitzjs](https://blitzjs.com/) ``` Blitz.js extends Next.js into a full-stack framework featuring a zero-API data layer and Prisma for database access. It aims to simplify development by allowing direct server-side code calls from the frontend. ``` - [adonisjs](https://adonisjs.com/) ``` AdonisJS is a TypeScript-first web framework for building web apps and API servers. It offers a rich set of features out-of-the-box, including an ORM, authentication, and a powerful CLI, making it ideal for developers seeking a comprehensive and structured development environment. ``` 他們會成為 JS 世界的 Laravel 或 Rails 嗎?現在說可能還為時過早,但至少 RedwoodJS 顯示出巨大的勢頭: ![紅木流行趨勢](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rwf3tizoy59tbck2q5j.png) 另一群人正試圖透過提供**固定**電池的工具包的「啟動套件」來解決這個問題。其中,最受歡迎的是[Create-T3-App](https://create.t3.gg/) ,它結合了 Next.js、tRPC、Tailwind CSS 和其他強大的工具,為您建立類型安全的 Web 應用程式奠定了堅實的基礎。 有趣的是,T3 的建立者 Theo 似乎對 JavaScript 世界的整個努力持悲觀態度: https://twitter.com/t3dotgg/status/1792136001345003748 樂觀的未來 ----- > 任何可以用 JavaScript 編寫的應用程式最終都會用 JavaScript 編寫。 — 傑夫·阿特伍德 雖然我並不完全相信阿特伍德定律,但我確實預見到 JavaScript 在 Web 開發領域的光明前景。原因很簡單: **這是歷史上第一次可以使用程式語言開發整個網頁應用程式。** 這是一個顯著的好處,特別是對於新手開發人員來說。感謝 TypeScript 優秀的類型推斷系統,我們不僅有能力這麼做,而且也願意這麼做。 Laravel 或 Rails 使用者常見的批評是,這些框架缺乏對系統中不同實體之間的關係進行建模的傳統方法,如下所示: https://twitter.com/chantastic/status/1791531154212033004 雖然它可能還沒有達到 Laravel 或 Rails 的水平,但目前 JS 界的努力已經認識到了這個問題。如果您查看上述解決方案的工具包,您會發現一個通用名稱: [Prisma](https://www.prisma.io/) 如果您還沒有聽說過 Prisma,它是一種現代的 TypeScript-first ORM,可讓您輕鬆管理資料庫模式,以極大的靈活性進行查詢和變更,並確保出色的類型安全性。這使 JavaScript 開發人員能夠實現 Laravel 和 Rails 中傳統的資料處理複雜性和輕鬆的關係建模,就像 Laravel 的 Eloquent ORM 一樣。 我在 Prisma 之上建立的[ZenStack](https://zenstack.dev/)工具包旨在進一步縮小差距。它在架構之上加入了授權層,然後自動為您產生 API 和前端掛鉤。因此,簡單地說,一旦您完成了架構,您就幾乎完成了後端。然後,您可以選擇任何前端框架(例如 React、Vue 或 Svelte)來完成您的 UI。 [![zenstack 架構](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g3h4wsn2ha5znwzq88u3.png)](https://zenstack.dev/) 開始就要考慮如何結束 ---------- JavaScript 會迎來 Laravel/Rails 時刻嗎?就我個人而言,我相信,或至少希望,標準化約定可以帶來整個生態系統的全局最佳化。然而,考慮到 JavaScript 的歷史和文化,實現這一目標可能需要大量時間。目前還不清楚人工智慧是否會加速這一過程,或徹底顛覆它。 所以,看來我們只能拭目以待了。然而,我們不要在這場辯論中迷失方向,忘記我們的初衷,正如李羅賓遜所說: https://twitter.com/leeerob/status/1792215708715122752 所以,我在最後引用[W3C Web平台設計原則](https://www.w3.org/TR/design-principles/#priority-of-constituencies)中的一句話: > 使用者需求先於網頁作者的需求,網頁作者的需求先於使用者代理實現者的需求,後者先於規範編寫者的需求,後者先於理論純粹性。 --- 原文出處:https://dev.to/zenstack/php-laravel-ruby-rails-javascript-36dc

如何建置:具有嵌入式 AI copilot 的待辦事項清單應用程式(Next.js、GPT4 和 CopilotKit)

**長話短說** -------- 待辦事項清單是每個開發人員的經典專案。在當今世界,學習如何使用人工智慧進行建構並在你的投資組合中加入一些人工智慧專案是很棒的。 今天,我將逐步介紹如何使用嵌入式 AI 副駕駛來建立待辦事項列表,以實現一些 AI 魔法🪄。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nw0jituk3y5tosz6f34u.gif) 我們將介紹如何: - 使用 Next.js、TypeScript 和 Tailwind CSS 建立待辦事項清單產生器 Web 應用。 - 使用 CopilotKit 將 AI 功能整合到待辦事項清單產生器中。 - 使用 AI 聊天機器人新增清單、將清單分配給某人、將清單標記為已完成以及刪除清單。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/guf0l2fiq1g1jv86o7bg.png) --- CopilotKit:建構應用內人工智慧副駕駛的框架 -------------------------- CopilotKit是一個[開源的AI副駕駛框架](https://github.com/CopilotKit/CopilotKit)。我們可以輕鬆地將強大的人工智慧整合到您的 React 應用程式中。 建造: - ChatBot:上下文感知的應用內聊天機器人,可以在應用程式內執行操作 💬 - CopilotTextArea:人工智慧驅動的文字字段,具有上下文感知自動完成和插入功能📝 - 聯合代理:應用程式內人工智慧代理,可以與您的應用程式和使用者互動🤖 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/myp7zashy99m33ya8kaf.gif) {% cta https://go.copilotkit.ai/bonnie %} 明星 CopilotKit ⭐️ {% endcta %} --- 先決條件 ---- 要完全理解本教程,您需要對 React 或 Next.js 有基本的了解。 以下是建立人工智慧驅動的待辦事項清單產生器所需的工具: - [Nanoid](https://github.com/ai/nanoid) - 一個小型、安全、URL 友善、唯一的 JavaScript 字串 ID 產生器。 - [OpenAI API](https://platform.openai.com/api-keys) - 提供 API 金鑰,讓您能夠使用 ChatGPT 模型執行各種任務。 - [CopilotKit](https://github.com/CopilotKit) - 一個開源副駕駛框架,用於建立自訂 AI 聊天機器人、應用程式內 AI 代理程式和文字區域。 專案設定和套件安裝 --------- 首先,透過在終端機中執行以下程式碼片段來建立 Next.js 應用程式: ``` npx create-next-app@latest todolistgenerator ``` 選擇您首選的配置設定。在本教學中,我們將使用 TypeScript 和 Next.js App Router。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tc6he9eivkt3hhxnj3p.png) 接下來,安裝 Nanoid 套件及其相依性。 ``` npm i nanoid ``` 最後,安裝 CopilotKit 軟體套件。這些套件使我們能夠從 React 狀態檢索資料並將 AI copilot 新增至應用程式。 ``` npm install @copilotkit/react-ui @copilotkit/react-textarea @copilotkit/react-core @copilotkit/backend @copilotkit/shared ``` 恭喜!您現在已準備好建立由人工智慧驅動的待辦事項清單產生器。 **建立待辦事項清單產生器前端** ----------------- 在本節中,我將引導您完成使用靜態內容建立待辦事項清單產生器前端的過程,以定義生成器的使用者介面。 首先,請在程式碼編輯器中前往`/[root]/src/app`並建立一個名為`types`資料夾。在 types 資料夾中,建立一個名為`todo.ts`的文件,並新增以下程式碼來定義名為**`Todo`的 TypeScript 介面。** **`Todo`**介面定義了一個物件結構,其中每個待辦事項都必須具有**`id`** 、 **`text`**和**`isCompleted`**狀態,同時也可以選擇具有**`assignedTo`**屬性。 ``` export interface Todo { id: string; text: string; isCompleted: boolean; assignedTo?: string; } ``` 然後轉到程式碼編輯器中的`/[root]/src/app`並建立一個名為`components`的資料夾。在 Components 資料夾中,建立三個名為`Header.tsx` 、 `TodoList.tsx`和`TodoItem.tsx`的檔案。 在`Header.tsx`檔案中,新增以下程式碼,定義一個名為`Header`的功能元件,該元件將呈現生成器的導覽列。 ``` import Link from "next/link"; export default function Header() { return ( <> <header className="flex flex-wrap sm:justify-start sm:flex-nowrap z-50 w-full bg-gray-800 border-b border-gray-200 text-sm py-3 sm:py-0 "> <nav className="relative max-w-7xl w-full mx-auto px-4 sm:flex sm:items-center sm:justify-between sm:px-6 lg:px-8" aria-label="Global"> <div className="flex items-center justify-between"> <Link className="w-full flex-none text-xl text-white font-semibold p-6" href="/" aria-label="Brand"> To-Do List Generator </Link> </div> </nav> </header> </> ); } ``` 在`TodoItem.tsx`檔案中,新增以下程式碼來定義名為**`TodoItem`**的 React 功能元件。它使用 TypeScript 來確保類型安全性並定義元件接受的 props。 ``` import { Todo } from "../types/todo"; // Importing the Todo type from a types file // Defining the interface for the props that the TodoItem component will receive interface TodoItemProps { todo: Todo; // A single todo item toggleComplete: (id: string) => void; // Function to toggle the completion status of a todo deleteTodo: (id: string) => void; // Function to delete a todo assignPerson: (id: string, person: string | null) => void; // Function to assign a person to a todo hasBorder?: boolean; // Optional prop to determine if the item should have a border } // Defining the TodoItem component as a functional component with the specified props export const TodoItem: React.FC<TodoItemProps> = ({ todo, toggleComplete, deleteTodo, assignPerson, hasBorder, }) => { return ( <div className={ "flex items-center justify-between px-4 py-2 group" + (hasBorder ? " border-b" : "") // Conditionally adding a border class if hasBorder is true }> <div className="flex items-center"> <input className="h-5 w-5 text-blue-500" type="checkbox" checked={todo.isCompleted} // Checkbox is checked if the todo is completed onChange={() => toggleComplete(todo.id)} // Toggle completion status on change /> <span className={`ml-2 text-sm text-white ${ todo.isCompleted ? "text-gray-500 line-through" : "text-gray-900" // Apply different styles if the todo is completed }`}> {todo.assignedTo && ( <span className="border rounded-md text-xs py-[2px] px-1 mr-2 border-purple-700 uppercase bg-purple-400 text-black font-medium"> {todo.assignedTo} {/* Display the assigned person's name if available */} </span> )} {todo.text} {/* Display the todo text */} </span> </div> <div> <button onClick={() => deleteTodo(todo.id)} // Delete the todo on button click className="text-red-500 opacity-0 group-hover:opacity-100 transition-opacity duration-200"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-5 h-5"> <path strokeLinecap="round" strokeLinejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" /> </svg> </button> <button onClick={() => { const name = prompt("Assign person to this task:"); assignPerson(todo.id, name); }} className="ml-2 text-blue-500 opacity-0 group-hover:opacity-100 transition-opacity duration-200"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-5 h-5"> <path strokeLinecap="round" strokeLinejoin="round" d="M18 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0ZM3 19.235v-.11a6.375 6.375 0 0 1 12.75 0v.109A12.318 12.318 0 0 1 9.374 21c-2.331 0-4.512-.645-6.374-1.766Z" /> </svg> </button> </div> </div> ); }; ``` 在`TodoList.tsx`檔案中,加入以下程式碼來定義名為**`TodoList`**的 React 功能元件。此元件用於管理和顯示待辦事項清單。 ``` "use client"; import { TodoItem } from "./TodoItem"; // Importing the TodoItem component import { nanoid } from "nanoid"; // Importing the nanoid library for generating unique IDs import { useState } from "react"; // Importing the useState hook from React import { Todo } from "../types/todo"; // Importing the Todo type // Defining the TodoList component as a functional component export const TodoList: React.FC = () => { // State to hold the list of todos const [todos, setTodos] = useState<Todo[]>([]); // State to hold the current input value const [input, setInput] = useState(""); // Function to add a new todo const addTodo = () => { if (input.trim() !== "") { // Check if the input is not empty const newTodo: Todo = { id: nanoid(), // Generate a unique ID for the new todo text: input.trim(), // Trim the input text isCompleted: false, // Set the initial completion status to false }; setTodos([...todos, newTodo]); // Add the new todo to the list setInput(""); // Clear the input field } }; // Function to handle key press events const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === "Enter") { // Check if the Enter key was pressed addTodo(); // Add the todo } }; // Function to toggle the completion status of a todo const toggleComplete = (id: string) => { setTodos( todos.map((todo) => todo.id === id ? { ...todo, isCompleted: !todo.isCompleted } : todo ) ); }; // Function to delete a todo const deleteTodo = (id: string) => { setTodos(todos.filter((todo) => todo.id !== id)); }; // Function to assign a person to a todo const assignPerson = (id: string, person: string | null) => { setTodos( todos.map((todo) => todo.id === id ? { ...todo, assignedTo: person ? person : undefined } : todo ) ); }; return ( <div> <div className="flex mb-4"> <input className="border rounded-md p-2 flex-1 mr-2" value={input} onChange={(e) => setInput(e.target.value)} onKeyDown={handleKeyPress} // Add this to handle the Enter key press /> <button className="bg-blue-500 rounded-md p-2 text-white" onClick={addTodo}> Add Todo </button> </div> {todos.length > 0 && ( // Check if there are any todos <div className="border rounded-lg"> {todos.map((todo, index) => ( <TodoItem key={todo.id} // Unique key for each todo item todo={todo} // Pass the todo object as a prop toggleComplete={toggleComplete} // Pass the toggleComplete function as a prop deleteTodo={deleteTodo} // Pass the deleteTodo function as a prop assignPerson={assignPerson} // Pass the assignPerson function as a prop hasBorder={index !== todos.length - 1} // Conditionally add a border to all but the last item /> ))} </div> )} </div> ); }; ``` 接下來,前往`/[root]/src/page.tsx`文件,新增以下程式碼,匯入`TodoList`和`Header`元件並定義名為`Home`的功能元件。 ``` import Header from "./components/Header"; import { TodoList } from "./components/TodoList"; export default function Home() { return ( <> <Header /> <div className="border rounded-md max-w-2xl mx-auto p-4 mt-4"> <h1 className="text-2xl text-white font-bold mb-4"> Create a to-do list </h1> <TodoList /> </div> </> ); } ``` 接下來,刪除`globals.css`檔案中的 CSS 程式碼並新增以下 CSS 程式碼。 ``` @tailwind base; @tailwind components; @tailwind utilities; body { height: 100vh; background-color: rgb(16, 23, 42); } ``` 最後,在命令列上執行命令`npm run dev` ,然後導航到 http://localhost:3000/。 現在您應該在瀏覽器上查看待辦事項清單產生器前端,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wmd8j3brrtiqackalul1.png) **使用 CopilotKit 將 AI 功能整合到待辦事項清單產生器** ------------------------------------- 在本節中,您將學習如何將 AI 副駕駛新增至待辦事項清單產生器,以使用 CopilotKit 產生清單。 CopilotKit 提供前端和[後端](https://docs.copilotkit.ai/getting-started/quickstart-backend)套件。它們使您能夠插入 React 狀態並使用 AI 代理在後端處理應用程式資料。 首先,我們將 CopilotKit React 元件新增至待辦事項清單產生器前端。 ### **將 CopilotKit 新增至待辦事項清單產生器前端** 在這裡,我將引導您完成將待辦事項清單產生器與 CopilotKit 前端整合以促進清單產生的過程。 首先,使用下面的程式碼片段匯入`/[root]/src/app/components/TodoList.tsx`檔案頂部的`useCopilotReadable`和`useCopilotAction`自訂掛鉤。 ``` import { useCopilotAction, useCopilotReadable } from "@copilotkit/react-core"; ``` 在`TodoList`函數內的狀態變數下方,新增以下程式碼,該程式碼使用`useCopilotReadable`掛鉤來新增將作為應用程式內聊天機器人的上下文產生的待辦事項清單。該鉤子使副駕駛可以讀取待辦事項清單。 ``` useCopilotReadable({ description: "The user's todo list.", value: todos, }); ``` 在上面的程式碼下方,新增以下程式碼,該程式碼使用`useCopilotAction`掛鉤來設定名為`updateTodoList`的操作,該操作將啟用待辦事項清單的產生。 此操作採用一個名為 items 的參數,該參數可以產生待辦事項列表,並包含一個根據給定提示產生待辦事項列表的處理程序函數。 在處理函數內部, `todos`狀態會使用新產生的 todo 清單進行更新,如下所示。 ``` // Define the "updateTodoList" action using the useCopilotAction function useCopilotAction({ // Name of the action name: "updateTodoList", // Description of what the action does description: "Update the users todo list", // Define the parameters that the action accepts parameters: [ { // The name of the parameter name: "items", // The type of the parameter, an array of objects type: "object[]", // Description of the parameter description: "The new and updated todo list items.", // Define the attributes of each object in the items array attributes: [ { // The id of the todo item name: "id", type: "string", description: "The id of the todo item. When creating a new todo item, just make up a new id.", }, { // The text of the todo item name: "text", type: "string", description: "The text of the todo item.", }, { // The completion status of the todo item name: "isCompleted", type: "boolean", description: "The completion status of the todo item.", }, { // The person assigned to the todo item name: "assignedTo", type: "string", description: "The person assigned to the todo item. If you don't know, assign it to 'YOU'.", // This attribute is required required: true, }, ], }, ], // Define the handler function that executes when the action is invoked handler: ({ items }) => { // Log the items to the console for debugging purposes console.log(items); // Create a copy of the existing todos array const newTodos = [...todos]; // Iterate over each item in the items array for (const item of items) { // Find the index of the existing todo item with the same id const existingItemIndex = newTodos.findIndex( (todo) => todo.id === item.id ); // If an existing item is found, update it if (existingItemIndex !== -1) { newTodos[existingItemIndex] = item; } // If no existing item is found, add the new item to the newTodos array else { newTodos.push(item); } } // Update the state with the new todos array setTodos(newTodos); }, // Provide feedback or a message while the action is processing render: "Updating the todo list...", }); ``` 在上面的程式碼下方,新增以下程式碼,程式碼使用`useCopilotAction`掛鉤來設定名為`deleteTodo`的操作,該操作使您能夠刪除待辦事項。 該操作採用名為id 的參數,該參數可讓您透過id 刪除待辦事項,並包含一個處理函數,該函數透過過濾掉具有給定id 的已刪除待辦事項來更新待辦事項狀態。 ``` // Define the "deleteTodo" action using the useCopilotAction function useCopilotAction({ // Name of the action name: "deleteTodo", // Description of what the action does description: "Delete a todo item", // Define the parameters that the action accepts parameters: [ { // The name of the parameter name: "id", // The type of the parameter, a string type: "string", // Description of the parameter description: "The id of the todo item to delete.", }, ], // Define the handler function that executes when the action is invoked handler: ({ id }) => { // Update the state by filtering out the todo item with the given id setTodos(todos.filter((todo) => todo.id !== id)); }, // Provide feedback or a message while the action is processing render: "Deleting a todo item...", }); ``` 之後,請前往`/[root]/src/app/page.tsx`檔案並使用下面的程式碼匯入頂部的 CopilotKit 前端套件和樣式。 ``` import { CopilotKit } from "@copilotkit/react-core"; import { CopilotPopup } from "@copilotkit/react-ui"; import "@copilotkit/react-ui/styles.css"; ``` 然後使用`CopilotKit`包裝`CopilotPopup`和`TodoList`元件,如下所示。 `CopilotKit`元件指定 CopilotKit 後端端點 ( `/api/copilotkit/` ) 的 URL,而`CopilotPopup`則呈現應用程式內聊天機器人,您可以提示產生待辦事項清單。 ``` export default function Home() { return ( <> <Header /> <div className="border rounded-md max-w-2xl mx-auto p-4 mt-4"> <h1 className="text-2xl text-white font-bold mb-4"> Create a to-do list </h1> <CopilotKit runtimeUrl="/api/copilotkit"> <TodoList /> <CopilotPopup instructions={ "Help the user manage a todo list. If the user provides a high level goal, " + "break it down into a few specific tasks and add them to the list" } defaultOpen={true} labels={{ title: "Todo List Copilot", initial: "Hi you! 👋 I can help you manage your todo list.", }} clickOutsideToClose={false} /> </CopilotKit> </div> </> ); } ``` 之後,執行開發伺服器並導航至[http://localhost:3000](http://localhost:3000/) 。您應該會看到應用程式內聊天機器人已整合到待辦事項清單產生器中。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ryeqnymp5lm397thpn5f.png) ### **將 CopilotKit 後端加入博客** 在這裡,我將引導您完成將待辦事項清單產生器與 CopilotKit 後端整合的過程,該後端處理來自前端的請求,並提供函數呼叫和各種 LLM 後端(例如 GPT)。 首先,在根目錄中建立一個名為`.env.local`的檔案。然後將下面的環境變數加入到儲存`ChatGPT` API 金鑰的檔案中。 ``` OPENAI_API_KEY="Your ChatGPT API key” ``` 若要取得 ChatGPT API 金鑰,請導覽至 https://platform.openai.com/api-keys。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x0bibiuouk5wvrxcuy2g.jpeg) 之後,轉到`/[root]/src/app`並建立一個名為`api`的資料夾。在`api`資料夾中,建立一個名為`copilotkit`的資料夾。 在`copilotkit`資料夾中,建立一個名為`route.ts`的文件,其中包含設定後端功能以處理POST 請求的程式碼。 ``` // Import the necessary modules from the "@copilotkit/backend" package import { CopilotRuntime, OpenAIAdapter } from "@copilotkit/backend"; // Define an asynchronous function to handle POST requests export async function POST(req: Request): Promise<Response> { // Create a new instance of CopilotRuntime const copilotKit = new CopilotRuntime({}); // Use the copilotKit to generate a response using the OpenAIAdapter // Pass the incoming request (req) and a new instance of OpenAIAdapter to the response method return copilotKit.response(req, new OpenAIAdapter()); } ``` 如何產生待辦事項列表 ---------- 現在轉到您之前整合的應用程式內聊天機器人,並給它一個提示,例如「我想去健身房做全身運動。加入到我應該遵循的鍛煉程序列表” 生成完成後,您應該會看到應遵循的全身運動程序列表,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48n9ssymxhm5i2yv0pdf.png) 您可以透過向聊天機器人發出「將待辦事項清單指派給 Doe」之類的提示來將待辦事項清單指派給某人。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6r1f816c1o8da5z0t1kk.png) 您可以透過向聊天機器人提供「將待辦事項清單標記為已完成」等提示來將待辦事項清單標記為已完成。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qx2wpg6ee7hswjl68t4q.png) 您可以透過向聊天機器人發出「刪除待辦事項清單」之類的提示來刪除待辦事項清單。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ksoj6mtlxt8ag8opsocs.png) 恭喜!您已完成本教學的專案。 結論 -- [CopilotKit](https://copilotkit.ai/)是一款令人難以置信的工具,可讓您在幾分鐘內將 AI Copilot 加入到您的產品中。無論您是對人工智慧聊天機器人和助理感興趣,還是對複雜任務的自動化感興趣,CopilotKit 都能讓您輕鬆實現。 如果您需要建立 AI 產品或將 AI 工具整合到您的軟體應用程式中,您應該考慮 CopilotKit。 您可以在 GitHub 上找到本教學的源程式碼:https://github.com/TheGreatBonnie/AIpoweredToDoListGenerator --- 原文出處:https://dev.to/copilotkit/how-to-build-an-ai-powered-to-do-list-nextjs-gpt4-copilotkit-20i4

如何在AWS部署自己的網站

完全控制您的網站,並遵循我們的操作指南。 從頭開始建立和部署網站的好處: - 擁有程式碼並以您認為合適的方式控制它 - 了解 AWS 以及如何將網站部署到 AWS S3 - 了解 DNS 和 Route53 - 如何使用DevOps解決自動化問題 請繼續閱讀以開始使用。 > [在 Twitter 上關注我](https://x.com/rolfstreefkerk),隨時了解有關 AWS 等的最新文章。 您將需要以下內容才能開始 ------------ 1. **靜態站點**,我推薦以下框架之一(我已經使用過): ``` - [Hugo](https://gohugo.io/) ``` ``` - existing [themes](https://themes.gohugo.io/) will get you a website quick, such that you only have to modify color schemes and layouts. ``` ``` - or [Astro](https://astro.build/); if you’d like to integrate React, VueJS etc. code as well. ``` ``` - use their themes page [here](https://astro.build/themes/) to get a starting point. ``` 2. **一個[AWS 帳戶](https://aws.amazon.com/)**,需要信用卡才能設定。 3. **一個域名**,無論您在哪裡註冊。 ``` - In this how-to I use [Porkbun](porkbun.com) as my favorite registrar. ``` 4. **一台電腦**; ``` - [Terraform](https://www.terraform.io/)/[OpenTofu](https://opentofu.org/) installed. We use Terraform in this article. ``` ``` - [AWS CLI](https://aws.amazon.com/cli/) installed with profile configured you want to use for your website deployment. ``` ``` - [Git](https://git-scm.com/downloads) command line tooling. ``` ``` - your code editor of choice, I use [VSCode](https://code.visualstudio.com/). ``` 5. **一個[GitHub](https://github.com/)帳戶**,以便您可以建立我的範例儲存庫。 6. *(可選)電子郵件收件匣供應商*,我使用[Migadu](migadu.com) 。 今天我們在創造什麼? ---------- 我們正在建立以下服務和配置: -------------- - 用於將網站來源檔案傳送到的 AWS S3 儲存桶; - AWS CloudFront 發行版將在全球範圍內快取、優化向您的受眾交付的網站。 - AWS Route53 適合您; ``` - Email service records with DNSSec configuration, ``` ``` - You can then hookup a newsletter service like `ConvertKit.com` ``` ``` - Name Server Configuration for your domain; `yourwebsite.com` ``` ``` - and the CloudFront distribution to optimize your website hosting. ``` - 適用於 CI/CD 管道的 GitHub Actions,可在一分鐘內根據命令部署您的網站。 ![將您的網站部署到 AWS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/40hkfi68ukl8m6vw3y02.png) 在 AWS 上設定您的網域 ------------- 登入您的 AWS 控制台。 1. 登入後,前往 Route53,然後導覽至`Hosted zones` 。 2. 建立您的託管區域並輸入您的網站網域; `yourwebsite.com` 3. 記下`Hosted zone ID` ,我們將在下一步中使用 Terraform 將所有 Route53 記錄自動化到正確的網域。 ![Terraform 託管區域 ID](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ydaop4rxoper3xj7xt1.png) 如果您選擇使用 Terraform 實現自動化; - 從您的網域註冊商(Porkbun 等)匯出名稱伺服器。 - 將託管區域資源配置新增至[我的範例 Terraform 模組](https://github.com/rpstreef/terraform-static-site)中,並將其連接到需要託管區域 ID 的所有相關資源。 ### (可選)電子郵件託管 如果您想設定電子郵件託管解決方案,我使用 migadu.com,保持 Route53 網站開啟。 我們將向 Route53 匯入其他設定文字區塊,以使您的網域與收件匣服務搭配使用。 - 在郵件收件匣服務中,有一個`DNS Configuration`面板。 - 取得`BIND`記錄輸出,複製/貼上所有 DNS 記錄的文字。 > 如果您需要自動發現您的電子郵件的郵件伺服器; > 在提供的 DNS 記錄中檢查這些字串; `_autodiscover`或`autoconfig` ![取得BIND記錄](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mfczsfjwddthnluqs9d.png) - 然後在 AWS Route53 中,針對您的託管區域; `Import zone file` ,然後複製貼上該對話方塊中的文字行。 ![Route53 託管區域文件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dj7gfedvyf4egixw2s2c.png) - 現在您可以在郵件應用程式中新增新的電子郵件收件匣。 如果您有`_autodiscover`和/或`autoconfig` DNS 記錄,您可以; - 轉到您的電子郵件應用程式, - 使用新增收件匣;電子郵件和密碼。 - 完成,收件匣已新增,無需進一步配置。 否則,請記下您的郵件收件匣服務 SMTP 和 IMAP 伺服器設定。 使用 Terraform 自動設定您的 AWS 帳戶 -------------------------- 現在我們已經有了網域和郵件收件匣(可選),我們可以設定實際的網站部署。 透過 Forking 建立一個新專案:https://github.com/rpstreef/terraform-yourwebsite.com 這是一個將使用另一個 Git 儲存庫中的 Terraform 模組的範本; https://github.com/rpstreef/terraform-static-site ### 這個模板建立了什麼? 此範本將建立以下資源集; - Terraform 狀態的 S3 儲存桶 - `yourwebsite.com`的 S3 儲存桶 ``` - S3 CORS configuration for ConvertKit.com , this will allow CORS between ConvertKit JavaScript and your domain without warnings. ``` - SSL 的 ACM 憑證、 `*.yourwebsite.com`以及用於自動續訂 SSL 的 Route53 的 ACM 驗證記錄。 - Route53 A 和 AAAA 記錄 (IPv6) - Route53 DNSSec, ``` - only the first step! The second step must be done manually with your Domain Registrar. ``` - 用於重定向到索引的 Lambda 函數可確保您擁有良好的 URL。 ``` - E.g. https://yourwebsite.com/contact instead of https://yourwebsite.com/contact/index.html ``` - CloudFront 用於快取、網頁速度優化以及 SSL 保護。 ### 如何調整模板? 使模板適合您的網站。 請執行下列操作 - 更改`terraform.tfvars`檔案中的這些行: ``` - where you read `yourdomain.com`, ``` ``` - and your `hosted_zone_id` for `yourdomain.com`. ``` ``` - check 404 response at the bottom of the file to see if that matches up with your website structure. Additionally HTTP response codes can be added as blocks; `{}`. ``` 如果您需要額外的 CORS 設置,請按照與`f.convertkit.com`相同的方式加入額外規則。 ``` # General environment = "prod" region = "us-east-1" project = "yourdomain.com" # use tags to track your spend on AWS, seperate by 'product' for instance. tags = { environment = "production" terraform = true product = "yourdomain.com" } # Which config line used in .aws/config aws_profile = "yourdomain-profile" # Route53 hosted_zone_id = "Z000000000" # www.yourdomain.com product_name = "yourdomain" # avoid to use `.`, this cause an error. bucket_name = "yourdomain.com" # your site is deployed here. # S3 bucket CORS settings: bucket_cors = { rule1 = { allowed_headers = ["*"] allowed_methods = ["GET", "PUT", "POST"] allowed_origins = ["https://f.convertkit.com"] expose_headers = ["ETag"] max_age_seconds = 3000 } } domain_names = ["yourdomain.com", "www.yourdomain.com"] custom_error_responses = [{ error_code = 404 error_caching_min_ttl = 10 response_code = 200 response_page_path = "/404.html" }] ``` - 確保`project-state.tf`檔案中的配置正確; ``` - check the bucket name, ``` ``` - and the AWS `profile` name used, e.g. `yourwebsite-profile`. ``` ``` locals { projects_state_bucket_name = "tfstate-yourwebsite.com" } provider "aws" { region = "us-east-1" profile = "yourwebsite-profile" } terraform { # First we need a local state backend "local" { } # After terraform apply, switch to remote S3 terraform state /*backend "s3" { bucket = "tfstate-yourwebsite" key = "terraform.tfstate" region = "us-east-1" profile = "yourwebsite-profile" encrypt = true acl = "private" }*/ } ``` - 如果所有配置都檢查通過; ``` - run `terraform init`, this will download the dependent modules. ``` ``` - then; `terraform apply` > `yes` ``` - 完成部署後,記下輸出中的變數。我們稍後會需要它們。若要稍後檢索這些,請鍵入; `./environments/production`目錄中的`terraform output` 。 > 哪一個先出現?雞還是雞蛋? - 完成後,我們需要調整`project-state.tf`檔案: ``` - Place the `backend "local"` block in comments. ``` ``` - Remove the comments from the `backend "s3"` block. ``` ``` - Migrate the state from `local` to `S3`: ``` ``` - `terraform init -migrate-state` ``` ``` - type: `yes` to copy state from local to s3. ``` 現在它已完全部署,我們已將 Terraform 狀態儲存到 AWS S3,它不再位於您的磁碟上。如果您願意,可以刪除這些`tfstate`檔案。 ### 建立 DNSSec“信任鏈” DNSSec 的好處是建立了「信任鏈」。 這意味著,已驗證; - 您擁有該域名, - 當您導航到該網域時,資訊來自您的伺服器而不是來自其他人的伺服器(例如駭客等) > 如果您想了解有關 DNSSec 的更多訊息, [本文](https://www.csoonline.com/article/569685/dnssec-explained-why-you-might-want-to-implement-it-on-your-domain.html)是一本很好的入門讀物 現在要完成 DNSSec 配置,您必須手動修改網域註冊商資訊。 - 首先,取得DNSSec所需的`DS`記錄; `View information to create DS record` ![路由 53:DNSSec](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrbuax3y4n65hjr0pm5v.png) - 然後,在下一個畫面中點擊; `Establish a Chain of Trust` 。 您將看到一個概述配置專案的表格。 如果您沒有在 Route53 上註冊網域,請按一下`Another Domain registrar` 在我的網域註冊商 Porkbun 上,畫面如下所示: ![Porkbun.com DNSSec](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yavg03ukeye7ienuuswp.png) - 在`dsData`區塊中輸入以下內容;左邊是 Porkbun 輸入欄位名稱,右邊是值,我將放置在`Route53`中使用的名稱: ``` - Key Tag: `Key tag` ``` ``` - DS Data Algorithm: `Signing algorithm type` ``` ``` - Digest Type: `Digest algorithm type` ``` ``` - Digest: `Digest` ``` > 如果您有不同的註冊商,您需要查看他們的文件,可能會略有不同。 #### 如何檢查您的配置是否有效? - 最後,使用這個線上工具;如果您獲得所有綠色複選標記,請使用 https://dnssec-debugger.verisignlabs.com/ 檢查您的網域。 如果都是綠色的,那就表示你的信任鏈已經成功建立了! 現在我們有了一個 DNSSec 安全性網域配置,其中包含一個透過 CloudFront 使用 SSL 的 S3 靜態託管網站。 - 高效率的 - 便宜的 - 和安全。 上傳您的網站 ------ 我們可以透過 AWS CLI 或 GitHub Actions 使用本地部署設定。 ### 使用腳本進行本地部署 根據您的系統(Linux、Windows、Mac),您可能需要變更此腳本。 在 Linux 上,我們可以使用以下 bash 腳本自動化您的網站部署,如下所示: ``` #! /bin/bash npm run build aws s3 sync dist s3://yourwebsite.com --profile yourwebsite-profile aws cloudfront create-invalidation --distribution-id <CloudFront Distr. Id> --paths "/*" --profile yourwebsite-profile ``` 確保; - 將`npm run build`替換為產生靜態網站建置的腳本。 - 如果您的網站建置位於另一個資料夾中,請取代`aws s3 sync dist`中的`dist` 。 - 替換`<CloudFront Distr. Id>`與您的 CloudFront 指派 ID。 ``` - you can find it in the outputs after `terraform apply` has finished; `cloudfront_distribution_id` ``` ### GitHub 操作 如果您喜歡使用自動化,那麼設定起來非常簡單且便宜。 #### 無論如何,這要花多少錢? |計劃|儲存|分鐘(每月)| | ----------- | -------- | ------------------- | | GitHub 免費 | 500 MB | 2,000 | | GitHub 專業版 | 1 GB | 3,000 | 在達到`Pro` `Minutes per month`上限之前,您可以部署多次: `storage`大小取決於您的儲存庫大小,對於大多數人來說,這將很難達到。 |作業系統 |分鐘乘數 | | ---------------- | ----------------- | | Linux | 1 | |窗戶| 2 | 我們選擇`Linux`建置環境,特別是`ubuntu-latest` ,以充分利用我們的空閒時間。 [在此處](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions)查看有關 GitHub Action 定價的更多資訊。 #### 它是如何運作的? 若要使用 GitHub Actions 進行部署,請執行下列操作: - 首先,在網站的 GitHub 儲存庫中建立一個新檔案(位於`.github/workflows/deploy-on-comment.yml` 。 - 將以下程式碼新增至文件: > **筆記**;我假設您的網站是基於 Node (v20) 的。在需要的地方進行調整! ``` name: Deploy on Comment on: issue_comment: types: [created, edited] push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up Node.js uses: actions/setup-node@v3 with: node-version: '20' - name: Install dependencies run: npm install - name: Build website run: npm run build - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - name: Sync build output with S3 bucket run: aws s3 sync ./dist s3://your-s3-bucket-name - name: Invalidate CloudFront cache run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*" ``` 需要在 GitHub 上建立幾個秘密變數,這些變數來自我們之前收到的 Terraform 輸出: - `AWS_ACCESS_KEY_ID` : - `AWS_SECRET_ACCESS_KEY` : - `CLOUDFRONT_DISTRIBUTION_ID` - 如果您需要再次尋找這些內容,請導覽至您的`terraform-yourwebsite.com` git 儲存庫,然後; ``` - `cd ./environments/production` ``` ``` - `terraform output` ``` - 在 GitHub 中的以下位置輸入它們: ![GitHub 秘密配置](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uddfhnlxicco614wxx72.png) - 例如,您現在可以`create an issue` ,詳細說明您網站上的更新。 ``` For each comment that is added, the deployment will start. ``` - 您可以按照`Actions`標籤中所採取的部署步驟和日誌進行操作。 ![GitHub問題,評論部署](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g4srw32r69d97j7za1dj.png) - (可選)如果您想要變更 GitHub 操作以使用`Pull request` ,您可以在部署腳本中進行修改。 ``` > For more alternative triggers, check out the [GitHub Actions documentation](https://docs.github.com/en/actions/using-workflows/triggering-a-workflow). ``` 您的網站上線了! -------- 現在,當您造訪您的網址時; `yourwebsite.com` ,一切都應該啟動並執行。 我們已經建造了什麼; - (可選)使用 Migadu 託管電子郵件(或選擇您擁有的任何託管服務);例如`[email protected]` ``` - You can connect this to your ConvertKit.com mailing list for example. ``` - 您自己的受 DNSSec 保護的個人網域。 ``` - You’ll be certain no hackers can hi-jack your domain. ``` - 您在 \[\[AWS\]\] 上使用 AWS S3 的靜態網站。 ``` - Free web-hosting! ``` - CloudFront 內容傳遞網路 (CDN),支援: ``` - SSL protected website. Form submits are all encrypted by default. ``` ``` - Increased performance in load speeds, latency across the globe. ``` ``` - URL rewrites for static websites. No `index.html` will be displayed when navigating. ``` ``` - and redirects for 404 not found pages. Your visitors will see the `404.html` page instead of an error text message. ``` 問題?來! ----- 您在 AWS 上遇到什麼困難? 您在 AWS 上部署時遇到問題嗎? 你會怎麼做? 請在評論或[Twitter](https://x.com/rolfstreefkerk)上告訴我 感謝您的寶貴時間,直到下次! --- 原文出處:https://dev.to/rolfstreefkerk/how-to-deploy-your-own-website-on-aws-1l05

加入我們參加下一個前端挑戰:六月版

等待已經結束!我們又帶著另一場前端挑戰賽回來了。 持續到**6 月 9 日**,前端挑戰:六月版將提供兩個六月主題提示: **CSS Art**和**Glam Up My Markup** 。對於那些錯過“一位元組解釋器”的人,我們保證很快就會恢復該提示! 像往常一樣,每個提示都會有一名獲勝者。這是贏得吹牛權利的兩次機會、DEV 商店的禮物和專屬 DEV 徽章。 另外,如果您不知道 - 徽章可以疊加在您的個人資料上以炫耀多次獲勝!但當然,這不是關於獲勝的目的地,而是關於*旅程*。我們希望這是一個挑戰自我並享受樂趣的機會。 繼續閱讀以了解每個提示以及如何參與! 我們的兩個提示: -------- ### CSS 藝術:六月 畫出您想到六月時想到的事情。根據您居住的地方,這可能是夏至或落葉和冬季的過渡。或者也許是父親節或驕傲月。 當您想到六月時,您會想到什麼,請告訴我們! 這是供任何想要直接參與的人使用的提交模板,但請在提交之前查看[官方挑戰頁面](https://dev.to/challenges/frontend-2024-05-29)上的所有評審標準和挑戰規則。 {% cta https://dev.to/new?prefill=---%0Atitle%3A%20%0Apublished%3A%20%0Atags%3A%20frontendchallenge%2C%20devchallenge%2C%20css%0A---% 0A%0A\_This%20is%20a%20submission%20for%20%5BFrontend%20Challenge%20v24.04.17%5D(https%3A%2F%2Fdev.to%2Fchallenges%2Ffrontend-2024-05-202020CSS% %3A%20June.\_%0A%0A%23%23%20靈感%0A%3C! --%20什麼%20是%20you%20highlighting%20today%3F%20--%3E%0A%0A%23 %23% 20Demo%20%0A%3C!--%20Show%20us%20your%20CSS%20Art!%20You%20can%20直接%20embed%20an%20editor%20into%20this%20post%20(%200%20(%20the%參見20FAQ%20section% 20of%20the%20challenge%20page)%20or%20you%20can%20share%20an%20image%20of%20your%20project%20and%20share%20a%200%20link%200%200%。 20--%3E% 0A%0A%23%23%20旅程%20%0A%3C!--%20告訴%20us%20about%20your%20process%2C%20what%20you%20learned%2C%20anything%20you %20are%20尤其%20proud%20of %2C%20what%20you%20hope%20to%20do%20next%2C%20etc.%20--%3E%0A%0A%3C!--%20Team%20Submissions%3A% 20Please%20pick%20one%20member%20to %20發布%20the%20submission%20和%20credit%20隊友%20by%20listing%20他們的%20DEV%20用戶名%20直接%20in%20the% 20the%20post。 20。 )。 CSS 藝術提交模板 {% 結束%} ### 讓我的標記變得迷人:海灘 使用 CSS 和 JavaScript 使下面的入門 HTML 標記美觀、互動且有用。我們提供了一個網站的入門模板,其中列出了世界上最好的海灘以及每個海灘的一些資訊。由於該模板不包含照片,因此您可能需要發揮創意,使其具有視覺吸引力。 您提交的內容應該比我們提供的 HTML 更有趣、更具互動性,但也應該可用且易於存取。您不應直接編輯提供的 HTML,除非是透過 JavaScript。我們期待風格和實質。您可以加入基本樣板,包括元標記等以用於演示目的。 ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Best Beaches in the World</title> </head> <body> <header> <h1>Best Beaches in the World</h1> </header> <main> <section> <h2>Take me to the beach!</h2> <p>Welcome to our curated list of the best beaches in the world. Whether you're looking for serene white sands, crystal-clear waters, or breathtaking scenery, these beaches offer a little something for everyone. Explore our top picks and discover the beauty that awaits you.</p> </section> <section> <h2>Top Beaches</h2> <ul> <li> <h3>Whitehaven Beach, Australia</h3> <p>Located on Whitsunday Island, Whitehaven Beach is famous for its stunning white silica sand and turquoise waters. It's a perfect spot for swimming, sunbathing, and enjoying the natural beauty of the Great Barrier Reef.</p> </li> <li> <h3>Grace Bay, Turks and Caicos</h3> <p>Grace Bay is known for its calm, clear waters and powdery white sand. This beach is ideal for snorkeling, diving, and enjoying luxury resorts that line its shore.</p> </li> <li> <h3>Baia do Sancho, Brazil</h3> <p>Baia do Sancho, located on Fernando de Noronha island, offers stunning cliffs, vibrant marine life, and crystal-clear waters, making it a paradise for divers and nature lovers.</p> </li> <li> <h3>Navagio Beach, Greece</h3> <p>Also known as Shipwreck Beach, Navagio Beach is famous for the rusting shipwreck that rests on its sands. Accessible only by boat, this secluded cove is surrounded by towering cliffs and azure waters.</p> </li> <li> <h3>Playa Paraiso, Mexico</h3> <p>Playa Paraiso, located in Tulum, offers pristine white sands and turquoise waters against the backdrop of ancient Mayan ruins. It's a perfect blend of history and natural beauty.</p> </li> <li> <h3>Anse Source d'Argent, Seychelles</h3> <p>Anse Source d'Argent is renowned for its unique granite boulders, shallow clear waters, and soft white sand. This beach is perfect for photography, snorkeling, and relaxation.</p> </li> <li> <h3>Seven Mile Beach, Cayman Islands</h3> <p>Stretching for seven miles, this beach offers soft coral sand, clear waters, and numerous activities such as snorkeling, paddleboarding, and enjoying beachside restaurants and bars.</p> </li> <li> <h3>Bora Bora, French Polynesia</h3> <p>Bora Bora is known for its stunning lagoon, overwater bungalows, and vibrant coral reefs. It's a perfect destination for honeymooners and those seeking luxury and tranquility.</p> </li> <li> <h3>Lanikai Beach, Hawaii</h3> <p>Lanikai Beach features powdery white sand and calm, clear waters, making it a favorite for swimming, kayaking, and enjoying the scenic views of the Mokulua Islands.</p> </li> <li> <h3>Pink Sands Beach, Bahamas</h3> <p>Pink Sands Beach is famous for its unique pink-hued sand, clear waters, and serene atmosphere. It's an idyllic spot for beachcombing, swimming, and relaxing in paradise.</p> </li> </ul> </section> </main> </body> </html> ``` 這是供任何想要直接參與的人使用的提交模板,但請在提交之前查看[官方挑戰頁面](https://dev.to/challenges/frontend-2024-05-29)上的所有評審標準和挑戰規則。 {% cta https://dev.to/new?prefill=---%0Atitle%3A%20%0Apublished%3A%20%0Atags%3A%20devchallenge%2C%20frontendchallenge%2C%20css%2C%20javascript%2C%20frontendchallenge%2C%20css%2C%20javascript%0Ajava ---%0A%0A\_This%20is%20a%20submission%20for%20%5BFrontend%20Challenge%20v24.04.17%5D((https%3A%2F%2Fdev.to%2Fchallenges%2FF-202F%2F%2Fdev.to%2Fchallenges%2FF-202F-frontend5-294-front05-29)% 2C%20Glam%20Up%20My%20Markup%3A%20Beaches\_%0A%0A%23%23%20What%20I%20Built%0A%0A%3C!--%20告訴%20us%20what%20you%20what0%200and% 20what %20you%20were%20looking%20to%20實作。 20direct% 20將%20an%20editor%20嵌入%20this%20post%20(參見%20the%20challenge%20頁的%20the%20FAQ%20section%20)%20或%20you%20can%20share%20an%% 20of%20your%20project%20和%20share%20a%20public%20link%20到%20the%20碼。告訴%20us%20about%20your%20process%2C %20what%20you%20已學會%2C%20anything%20you%20are%20尤其%20proud%20of%2C%20what%20you%20hope%20to%20what%20next20what%20you%20hope%20to%20what%C %20etc.%20--%3E%0A%0A% 3C! --%20Team%20Submissions%3A%20請%20pick%20one%20member%20to%20publish%20the%20submission%20and%20ammacre%20and%200%20and%200%20and%200%20and%200%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%20and%207%。 20listing%20their%20DEV%20usernames%20directly%20in%20the%20body %20of%20the%20post。%20--%3E%0A%0A%3C! 20考慮%20為%20您的%20程式碼加入%20a%20許可證%20。 %20cover%20image%20to%20your%20post%20(如果%20you%20想要)。 --%3E %} 使我的標記提交模板更加迷人 {% 結束%} 如何參與 ---- 為了參與,您需要使用與每個提示關聯的提交範本來發布貼文。 請在提交之前查看我們的[評審標準、規則、指南和常見問題解答頁面,](https://dev.to/challenges/frontend-2024-05-29)以便您了解我們的參與指南和官方競賽規則(例如資格要求)。 重要的日子 ----- - 5 月 29 日:前端挑戰:六月版開始! - 6 月 9 日:提交截止時間為太平洋夏令時間晚上 11:59 - 6 月 11 日:得獎者公佈 ![驕傲月快樂](https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExemNkZWg1YTQ5dWw3Mmg1Z2tpdTdzbnM3c2Zocm1obmwzajBxYXgzNSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/4C0NVY0fI5OOuTOCUe/giphy.gif) 我們很高興看到您六月的專案!問題?請在下面詢問他們。 祝你好運,編碼愉快! --- 原文出處:https://dev.to/devteam/join-us-for-the-next-frontend-challenge-june-edition-3ngl

🚀 利用這些前端資源加速您的開發! 🚀

🚀 利用這些資源加速您的發展! 🚀 👋大家好! 👋 我很高興能分享我多年來收集的這些資源,這些資源在我從事的許多專案中都是救星。該編譯匯集了從使用者介面建立到效能最佳化等各種工具和函式庫。希望您也能充分利用這些精彩資源。讓我們開始吧! 請隨意評論您使用或感興趣的任何其他資源,以便我可以將它們加入到帖子中! ### 使用者介面: - [Material Tailwind](https://www.material-tailwind.com) :一個強大的 UI 套件,結合了 Material Design 和 Tailwind CSS - [Aceternity UI](https://ui.aceternity.com) :適合您下一個專案的時尚而現代的 UI 元件 - [NextUI](https://nextui.org) :使用 NextUI 輕鬆製作漂亮的介面 - [ChakraUI](https://chakra-ui.com) :一個簡單、模組化且可存取的元件庫 - [交易視圖圖表](https://www.tradingview.com/lightweight-charts/):使用 TradingView 的輕量級圖表增強您的資料視覺化遊戲 - [AutoAnimate](https://auto-animate.formkit.com) :使用 AutoAnimate 輕鬆創造令人驚嘆的動畫 - [React-magic-motion](https://www.react-magic-motion.com) :為你的 React 元件加入一點魔力 - [Keep React](https://react.keepdesign.io) :讓你的 React 元件保持新鮮和時尚 - [Daisy UI](https://daisyui.com) :使用 Daisy UI 建立令人愉悅的介面 - [ShadCn](https://ui.shadcn.com) :透過時尚優雅的元件提升您的 UI - [剪輯路徑](https://bennettfeely.com/clippy/):使用 Clippy 對形狀進行創意 - [Radix](https://www.radix-ui.com/primitives) :使用 Radix 建立強大且可組合的 UI - [佈局產生器](https://layout.bradwoods.io):輕鬆設計靈活的佈局 - [實用工具](https://omatsuri.app):漸層、遊標等的便利工具包 - [圖像產生器](https://www.freepik.com/pikaso):使用高品質圖像立即美化您的設計 - [按鈕](https://buttons.ibelick.com):用風格來扣住你的使用者介面 - [PrimeReact](https://primereact.org) :React 應用程式的主要元件 - [一切盡在一頁](https://freesets.vercel.app):探索精選的資源集合 - [Beer CSS](https://www.beercss.com) :基於 Material Design 3 的語意 HTML CSS 框架。 ### 漸層: - [Firecms](https://neat.firecms.co) :為您的專案提供動態漸變 - [Shadergradient](https://www.shadergradient.co) :輕鬆創造令人驚嘆的著色器漸變 ### SVG: - [形狀](https://shapes.framer.website):適合您設計的美麗 SVG 形狀 - [SVG](https://svgl.vercel.app) :發現大量 SVG - [SVG 插圖](https://undraw.co/illustrations):使用 Undraw 的插圖為您的專案增添活力 ### 其他的: - [滑桿 — Swiper](https://swiperjs.com) :無縫滑動內容 - [Toast 通知 — Sonner](https://sonner.emilkowal.ski) :Toast 通知變得簡單 - [Atropos - 3D 元素](https://atroposjs.com):為您的專案加入沉浸式 3D 元素 - [自動動畫(原生 Javascript)](https://auto-animate.formkit.com) :使用原生 JavaScript 輕鬆為元素製作動畫 - [Vaul (Slider desde abajo)](https://vaul.emilkowal.ski) :用 Vaul 提升您的滑桿 - [影片效能優化器](https://lite.youtube.com):使用 Lite YouTube Web Component 優化影片效能 - [日曆](https://wicky.nillia.ms/cally):簡化您的日程安排流程 - [對比度選擇器](https://coolors.co/contrast-checker/483c14-d2cfcb):使用 Coolors 的對比度檢查器確保可存取性 - [影像優化器](https://squoosh.app):壓縮影像以獲得更好的性能 ### 順風: - [動畫](https://www.tailwindcss-animated.com):使用 Tailwind CSS Animated 為您的 UI 增添風格 - [Intersection Observer](https://github.com/heidkaemper/tailwindcss-intersect) :Tailwind CSS Intersect 用來觀察交叉路口 - [背景](https://bg.ibelick.com):輕鬆美化您的背景 ### JavaScript: - [Masonry Grid](https://masonry.desandro.com) :輕鬆建立動態網格佈局 - [MiniMasonry](https://spope.github.io/MiniMasonry.js) :磚石佈局的輕量級替代方案 - [Gallery PhotoSwipe](https://photoswipe.com) :使用 PhotoSwipe 優雅地展示您的影像 - [Gallery LightGallery](https://www.lightgalleryjs.com) :LightGallery 提供令人驚嘆的影像畫廊 - [Tempo](https://tempo.formkit.com) :使用 Tempo 簡化基於時間的操作 - [Tippy(工具提示)](https://atomiks.github.io/tippyjs) :透過可自訂的工具提示增強使用者體驗 - [Intersection Observer](https://www.youtube.com/watch?v=T24PsErQGPg) :Intersection Observer 高效能滾動指南 - [無限滾動](https://www.youtube.com/watch?v=FA1Y4pamIP8):輕鬆實現無限滾動 - [Just](https://github.com/angus-c/just) :常見 JavaScript 實用程式的函式庫 - [GLTFs into JSX](https://github.com/pmndrs/gltfjsx) :將 GLTF 檔案轉換為 JSX 元件 ### 反應: - [計數器](https://use-count-up.vercel.app):動態計算你的數字 - [砌體佈局](https://blog.logrocket.com/create-responsive-masonry-layouts-react-app):在 React 中建立響應式砌體佈局 - [拖放](https://drag-and-drop.formkit.com):輕鬆實現拖放功能 - [FilePond](https://pqina.nl/filepond) :使用 FilePond 簡化檔案上傳 - [Faker](https://fakerjs.dev) :用 Faker 產生真實的假資料 - [隨機](https://www.npmjs.com/package/random-words):用隨機單字為你的專案增添趣味 - [圖表](https://www.chartjs.org/docs/latest):使用 Chart.js 完美地視覺化資料 - [UseSound](https://github.com/joshwcomeau/use-sound) :將聲音效果合併到您的 React 應用程式中 - [ReCharts](https://recharts.org/en-US) :基於 React 元件建構的圖表庫 - [浮動 UI(工具提示)](https://floating-ui.com) :互動式工具提示的浮動 UI - [Tippy(工具提示)](https://github.com/atomiks/tippyjs-react) :用於 React 應用程式的 Tippy.js - [日曆](https://wicky.nillia.ms/cally):滿足您所有日程安排需求的另一個日曆資源 - [CMDK Console](https://github.com/pacocoursey/cmdk) :React 應用程式的控制台 --- 原文出處:https://dev.to/miguelrodriguezp99/frontend-resources-1dl4

動態導覽選單

上週末,我使用 HTML 和 CSS 編寫了[互動式導覽](https://codepen.io/alvaromontoro/full/yLWeozP)(這次沒有使用 JavaScript): https://codepen.io/alvaromontoro/pen/yLWeozP (如果您錯過了初始動畫,或者想再次看到它,請點擊右下角的「重新執行」。) --- 對於這個演示: - 我嘗試堅持使用語義 HTML 並提供一種可存取的方法(希望我沒有搞亂這部分)。 - 初始載入動畫是只執行一次並在之後保持原樣的`animation` 。 - 使用 3D CSS 使清單元素彈出和返回。 - 焦點和懸停狀態受到同等對待,因此滑鼠和鍵盤使用者都會獲得相似的體驗。 - 它具有減少運動的樣式,可以降低動畫和過渡速度,因此沒有太多的運動(導航專案仍會彈出,但不會動畫化)。 - 我使用`drop-shadow()`過濾器產生整個選單的陰影(獨立於選單專案的陰影)。 - 還使用`box-shadow`為兄弟姐妹加入嵌入陰影並提供更大的深度感。我一開始是用陰影來做的,但我遇到了一些麻煩,所以我可能會把它們弄得過於複雜了。 - 我使用`:has()`選擇處於活動狀態的兄弟姐妹(前一個和後一個),並為其加入一些深度和陰影。 - 它使用 Font Awesome 作為圖示。 感謝您檢查該元件。如果您有任何疑問,請告訴我。歡迎所有回饋和建議! --- 原文出處:https://dev.to/alvaromontoro/animated-navigation-menu-57o7

您可能不知道的 HTML 標籤

開發者們大家好👋 在這篇文章中,我將分享一些在 HTML5 中加入的新的、有用的 html 標籤,用於編寫簡單快速的程式碼來建立複雜、動態、引人入勝且有效的網站。 讓我們開始吧🚀 對話 -- ➡ 現在您可以使用`<dialog>`標籤輕鬆建立對話方塊或彈出視窗。這是建立自訂模式對話方塊的好方法,而無需嚴重依賴**JavaScript** 。 ``` <dialog id="myDialog"> <p>This is a dialog box</p> <button onclick="document.getElementById('myDialog').close()">Close </button> </dialog> <button onclick="document.getElementById('myDialog').showModal()">Open Dialog </button> ``` 範本 -- ➡ `<template>`標籤用作儲存頁面載入時不希望顯示的客戶端內容的容器。可以使用**JavaScript**克隆該內容並將其插入到文件中。 ``` <button onclick="showContent()">Show hidden content</button> <template> <h2>Hello, This is Kiran</h2> <p>Thanks for reading this</p> </template> <script> function showContent() { let temp = document.getElementsByTagName("template")[0]; let clon = temp.content.cloneNode(true); document.body.appendChild(clon); } </script> ``` 圖片 -- ➡ 透過使用`<picture>`標籤,您可以為一張圖片定義多個來源,現在瀏覽器會根據螢幕尺寸、解析度選擇最佳的來源。這對於**響應式**設計特別有用。 ``` <picture> <source media="(min-width:650px)" srcset="img_pink_flowers.jpg"> <source media="(min-width:465px)" srcset="img_white_flower.jpg"> <img src="img_orange_flowers.jpg" alt="Flowers" style="width:auto;"> </picture> ``` 儀表 -- ➡ `<meter>`標籤可用來表示已知範圍內的標量測量,例如磁碟使用情況或查詢結果的相關性。它有助於**直觀地**顯示一定範圍內的值。 ``` <label for="diskUsage">Disk Usage:</label> <meter id="diskUsage" value="0.6">60%</meter> ``` 輸出 -- ➡ `<output>`標籤代表計算的結果。它可以與**JavaScript**一起使用來顯示計算**結果**。 ``` <form oninput="result.value=parseInt(a.value)+parseInt(b.value)"> <input type="number" id="a" value="50"> + <input type="number" id="b" value="25"> = <output name="result" for="a b">75</output> </form> ``` 進步 -- ➡ `<progress>`標籤代表**任務**的完成進度,例如下載或檔案上傳。 ``` <label for="fileProgress">File upload progress:</label> <progress id="fileProgress" value="70" max="100">70%</progress> ``` 標記 -- ➡ `<mark>`標籤用於反白顯示文字。它對於您想要**突出顯示**匹配文字的搜尋結果頁面特別有用。 ``` <p>The word <mark>highlighted</mark> is important.</p> ``` 縮寫 -- ➡ `<abbr>`標籤用於定義縮寫詞或首字母縮寫詞,在**標題**屬性中提供完整的**描述**。 ``` <p>I'm a true<abbr title="Marvel Cinematic Universe">MCU</abbr>fan.</p> ``` 時間 -- ➡ `<time>`標籤用於表示日期、時間或持續時間。它對於使與時間相關的資料變得機器可讀非常有用。 ``` <p>The concert starts at <time datetime="20:00">8 PM</time>.</p> ``` 巴迪 -- ➡ `<bdi>`標籤用於隔離可能與外部其他文字的格式方向不同的文字部分。無論涉及何種語言或文字**方向**,它都能確保您的網頁內容保持**一致**和可讀。 ``` <ul> <li>Product: <bdi>ABC1234</bdi></li> <li>Product: <bdi>مرحبا5678</bdi></li> </ul> ``` 沃伯 -- ➡ `<wbr>`標記指定文字可以在何處**換行**(如有必要)。這對於長單字或 URL 很有用。 ``` <p>Thisisaverylongword<wbr>thatmightneedbreaking.</p> ``` 主要的 --- ➡ `<main>`標籤用於指定文件的**主要內容**。它每頁只能使用一次,並且排除文件中重複的內容,例如頁首、頁尾、導覽和側邊欄。 ``` <main> <h1>Welcome to my blog post</h1> <p>Today we will learn some new html tags</p> </main> ``` 圖片標題 ---- ➡ `<figcaption>`標籤用於為圖形提供**標題**。 ``` <figure> <img src="Thanos.jpg" alt="Thanos image"> <figcaption>Thanos snapping his fingers</figcaption> </figure> ``` 這就是本文的內容。 感謝您的閱讀❤ 在 👉 https://x.com/kiran\_\_a\_\_n X https://github.com/Kiran1689 GitHub 上找到我 https://dev.to/dev\_kiran --- 原文出處:https://dev.to/dev_kiran/html-tags-you-might-not-know-about-3gk7

可以使用 Python 和 AI 建構的 25 個專案

今天,我們將介紹 25 個可以使用 Python 和 AI 模型建構的副專案。 大多數專案都會有生產級程式碼,因此您可以學到很多東西。 我們開始做吧! --- [Taipy](https://github.com/Avaiga/taipy) - 將資料和人工智慧演算法整合到生產就緒的 Web 應用程式中。 ------------------------------------------------------------------------- ![打字](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wd10iiofzmt4or4db6ej.png) 大多數初始專案都會使用 Taipy,所以讓我們討論一下這個概念的用例。 Taipy 是一個開源 Python 庫,可用於輕鬆的端到端應用程式開發,具有假設分析、智慧管道執行、內建調度和部署工具。 需要明確的是,Taipy 用於為基於 Python 的應用程式建立 GUI 介面並改進資料流管理。 關鍵是性能,而 Taipy 是最佳選擇。 雖然 Streamlit 是一種流行的工具,但在處理大型資料集時,其效能可能會顯著下降,這使得它在生產級使用上不切實際。 另一方面,Taipy 在不犧牲性能的情況下提供了簡單性和易用性。透過嘗試 Taipy,您將親身體驗其用戶友好的介面和高效的資料處理。 ![大資料支持](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnvk0tozn0lgj083rzcb.gif) Taipy 有許多整合選項,可以輕鬆地與領先的資料平台連接。 ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7yv31uir3erina587zp8.png) 開始使用以下命令。 ``` pip install taipy ``` 他們還使用分散式運算提高了效能,但最好的部分是 Taipy,它的所有依賴項現在都與 Python 3.12 完全相容,因此您可以在使用 Taipy 進行專案的同時使用最新的工具和程式庫。 您可以閱讀[文件](https://docs.taipy.io/en/latest/)。 ![用例](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xdvnbejf9aivxmqsd3hx.png) 另一個有用的事情是,Taipy 團隊提供了一個名為[Taipy Studio](https://docs.taipy.io/en/latest/manuals/studio/)的 VSCode 擴充功能來加速 Taipy 應用程式的建置。 ![太皮工作室](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kc1umm5hcxes0ydbuspb.png) 如果您想閱讀部落格來了解程式碼庫結構,您可以閱讀 HuggingFace[的使用 Taipy 在 Python 中為您的 LLM 建立 Web 介面](https://huggingface.co/blog/Alex1337/create-a-web-interface-for-your-llm-in-python)。 嘗試新技術通常很困難,但 Taipy 提供了 10 多個演示教程,其中包含程式碼和適當的文件供您遵循。我將詳細討論其中一些專案! ![示範](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wigid2aokt6spkkoivr.png) 這些用例非常驚人,所以一定要檢查一下。 Taipy 在 GitHub 上有超過 8,500 個 Star,並且處於`v3.1`版本,因此它們正在不斷改進。 https://github.com/Avaiga/taipy Star Taipy ⭐️ --- 1.[實時污染儀表板](https://docs.taipy.io/en/release-3.0/knowledge_base/demos/pollution_sensors/) ----------------------------------------------------------------------------------------- 使用工廠周圍的感測器測量空氣品質的用例,展示 Taipy 儀表板流資料的能力。 資料在另一台伺服器上產生並透過 WebSocket 發送到此 Taipy 應用程式。 然後 Taipy 處理資料並將其顯示在儀表板上。 當收到新資料時,儀表板會即時更新。 ![即時污染儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a0i6pm0ggx6yb655uvd1.png) 如果您想要有關可視化資料流的教程,請查看[有關多線程的文件](https://docs.taipy.io/en/release-3.0/knowledge_base/tips/multithreading/)。 它討論瞭如何建立發送者腳本和接收者腳本,包括套接字參數等。 它涉及到前端和後端的概念。 查看[現場演示](https://realtime-pollution.taipy.cloud/)。 https://github.com/Avaiga/demo-realtime-pollution Star 即時污染儀表板 ⭐️ --- 2.[詐欺檢測](https://github.com/Avaiga/demo-fraud-detection) -------------------------------------------------------- Taipy 應用程式可分析信用卡交易以偵測詐欺行為。 ![詐欺檢測演示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v90fuimlplxuj4llp1zb.png) 它顯示信用卡交易清單。 用戶可以選擇一個日期範圍來預測詐欺。 然後,該應用程式將使用 XGB 模型將潛在的詐欺交易標記為紅色或黃色。 用戶可以選擇一個交易來查看模型預測的解釋,以及客戶的其他交易。 ![詐欺檢測演示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8odxbhc9h3z3vzm4i4yk.png) 使用者還可以選擇模型的閾值。閾值是模型輸出,高於該閾值的交易將被視為詐欺。使用者可以根據顯示的混淆矩陣並透過查看誤報和漏報交易來選擇模型。 ![詐欺檢測演示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s8ri5h0ky5zie53g2wk7.png) 查看[現場演示](https://fraud-detection.taipy.cloud/Transactions)。 https://github.com/Avaiga/demo-fraud-detection 明星詐欺偵測 ⭐️ --- 3.[新冠儀表板](https://github.com/Avaiga/demo-covid-dashboard) --------------------------------------------------------- 這裡使用 2020 年的 Covid 資料集。 頁面顯示有關 COVID-19 的不同圖表和資訊。還有一個預測頁面來預測傷亡人數。 該應用程式包括四個部分,如下所示: > ✅ 國。 - 特定國家/地區的 COVID-19 統計資料。 - 在累積資料視圖和密度資料視圖之間輕鬆切換。 - 用於動態資料探索的互動式長條圖。 - 餅圖顯示病例分佈(確診、復健、死亡)。 ![國家](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j22qqjmpd39qwwb4it4o.png) > ✅ 地圖。 透過動態可縮放顏色編碼地圖直觀地展示 COVID-19 的影響。 ![地圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ngdy1pkmujgdel1rz81.png) > ✅ 預測。 透過為不同的預測日期和不同的國家建立場景來產生 COVID-19 預測。 這會分別使用 ARIMA 模型和線性迴歸模型產生 2 個不同的預測(橘色的預測\_x 和綠色的預測\_y)。 透過指定名稱、指定預測日期、選擇國家/地區並點擊「提交」按鈕繼續來啟動新場景。 您可以在“結果”部分的“場景”選項卡中存取它。 ![預測](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8idl5ys0zhkztexujcmh.png) > ✅ 世界。 全球 COVID-19 統計資料透過折線圖和圓餅圖進行匯總。透過更改`Absolute`和`Relative`之間的切換可以看到 Covid 國家/地區影響的比較。 ![世界](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9kd3rjxa7qjqne798ua.png) 總的來說,對於您的業餘專案和建立非常酷的專案來說,這是一個非常有用的應用程式:) 您可以查看[現場演示](https://covid-dashboard.taipy.cloud/Country)。 https://github.com/Avaiga/demo-covid-dashboard Star Covid 儀表板 ⭐️ --- 4.[建立 LLM 聊天機器人](https://github.com/Avaiga/demo-chatbot) -------------------------------------------------------- 該演示展示了 Taipy 使最終用戶能夠使用 LLM 執行推理的能力。在這裡,我們使用 GPT-3 建立一個聊天機器人,並將對話顯示在互動式聊天介面中。 ![法學碩士聊天機器人](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/olaw6u8w3fj2wrg0au2r.png) 下面給出了主要函數,該函數將字串提示(即用戶訊息)作為輸入,並從 LLM 傳回回應字串。 ``` def request(state: State, prompt: str) -> str: """ Send a prompt to the GPT-3 API and return the response. Args: - state: The current state. - prompt: The prompt to send to the API. Returns: The response from the API. """ response = state.client.chat.completions.create( messages=[ { "role": "user", "content": f"{prompt}", } ], model="gpt-3.5-turbo", ) return response.choices[0].message.content ``` 您可以閱讀有關如何建立此 LLM 聊天機器人的[完整文件](https://docs.taipy.io/en/release-3.0/knowledge_base/tutorials/chatbot/)。 最好的部分是,您可以根據您的使用情況輕鬆更改程式碼以使用任何其他 API 或模型。 您可以查看[現場演示](https://demo-llm-chat.taipy.cloud/)。 https://github.com/Avaiga/demo-chatbot 明星聊天機器人 ⭐️ --- 5.[即時人臉辨識](https://github.com/Avaiga/demo-face-recognition) ----------------------------------------------------------- 該演示將人臉辨識無縫整合到我們的平台中,借助 OpenCV 庫,使用網路攝影機提供即時人臉偵測體驗。 ![即時人臉辨識](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qs9kpit8byxsqq67mhql.png) 您可以非常輕鬆地使用它: A。打開應用程式時,您會透過網路攝影機看到自己。你的臉周圍有一個紅色方塊,上面寫著別人的名字。 b.透過點擊`Capture`按鈕並多次輸入您的名字來訓練模型辨識您。 C。現在點選`Re-train`按鈕。現在應該會出現您的名字。模型現在認出了您。 查看[現場演示](https://face-recognition.taipy.cloud/)。 確保在瀏覽器中啟用相機設置,這是首要條件! 進行人臉偵測和人臉辨識的程式碼位於`src/demo/faces.py`下。自述文件中提供了完整的目錄結構。 https://github.com/Avaiga/demo-face-recognition 明星人臉辨識 ⭐️ --- 6.[庫存可視化](https://github.com/Avaiga/demo-stock-visualization) ------------------------------------------------------------- 在金融市場領域,資料為王。快速、輕鬆地視覺化歷史股票資料並做出預測的能力對於投資者和金融分析師來說至關重要。 這是一個股票資料儀表板,具有互動式視覺元素,可以視覺化歷史股票資料並對 1 至 5 年內的股票進行預測。 ![庫存視覺化](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dz5jagdfvcnup1jq7qgx.png) 由 Facebook 使用 Taipy 和[Prophet Library](https://facebook.github.io/prophet/docs/quick_start.html)建構。此示範適用於高於 3.8 的 Python 版本。 您可以這樣使用它: A。選擇您想要預測的股票程式碼。 b.打開歷史資料面板。 C。選擇預測週期(從 1 到 5)。 d.點選`PREDICT`按鈕。 e.在預測資料面板中查看您的預測。 F。使用不同的程式碼重複嘗試以比較結果。 您也可以透過點擊底部的`More info`按鈕以表格形式取得預測範圍。 您可以在[src 目錄](https://github.com/Avaiga/demo-stock-visualization/tree/develop/src)下找到負責的主要原始碼。 這個完全互動的 Web 應用程式只需不到 120 行 Python 程式碼即可建立。 查看[現場演示](https://stock-visualization.taipy.cloud/)。 https://github.com/Avaiga/demo-stock-visualization 明星股票視覺化 ⭐️ --- 7.[情感分析](https://github.com/Avaiga/demo-sentiment-analysis)。 ------------------------------------------------------------ 情感分析就像一個機器人,可以從人們的言語中讀出他們的感受。 它會根據快樂、悲傷或憤怒等字眼來判斷它們的感覺是好是壞。然後,它告訴我們大多數人在說話時是高興還是悲傷。 因此,只需看看人們所說的內容,它就可以幫助我們了解人們對事物(例如電影或遊戲)的感受! 簡而言之,它是自然語言處理(NLP)中的一種技術,用於確定文本中傳達的情緒基調。它可以幫助企業和個人更好地掌握書面內容所表達的情感和語氣。 結果是一個兩頁的應用程式,它使用情感分析模型來分析輸入和整個文本。 第一頁分析使用者輸入,而第二頁讓使用者選擇要上傳的檔案(文字)。該文本將被分析並顯示背後的情感。 > ✅ 第 1 頁:Line - 分析使用者輸入 我們的情緒分析應用程式的初始頁面名為“Line”,用於即時分析使用者輸入。無論是簡短的句子還是較長的段落,只需將文字輸入或貼到輸入框中,Taipy 就會快速評估文本中傳達的情感。 ![第1頁情緒分析](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/826k2if80arn6y3uz3dz.png) > ✅ 文字 - 上傳和分析文字文件 第二個頁面名為“文字”,允許使用者上傳整個文字檔案 (.txt) 以進行全面的情感分析。 用戶可以從他們的設備中選擇一個文字文件,該應用程式將提供對整個文件所表達的情緒的洞察。 此功能對於處理較長的文字(例如文章、報告或廣泛的客戶回饋)非常有用。 ![第2頁情緒分析](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nb3xmtfi7fz6vm8807ph.png) 您可以查看[現場演示](https://sentiment-analysis.taipy.cloud/line)。 https://github.com/Avaiga/demo-sentiment-analysis 明星情感分析 ⭐️ --- 8.[漂移檢測](https://github.com/Avaiga/demo-drift-detection)- 檢測糖尿病資料集中的漂移。 ----------------------------------------------------------------------- ![漂移檢測](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ey1f4ygskvkk6dwqc2c8.png) 資料漂移是主要在機器學習中使用的概念,其中推理資料的分佈偏離訓練資料的分佈。 各種因素,例如底層資料來源的變化、資料收集過程的變化或資料儲存過程的變化,都可能導致資料漂移。 這通常會導致稱為訓練服務偏差的效能問題,其中用於推理的模型不用於推理資料的分佈並且無法泛化。 存在統計測試來檢測資料集中的漂移。這些檢定計算兩個系列來自同一分佈的機率。如果機率低於閾值,我們認為存在漂移。 如何使用該應用程式? ✅ 選擇比較資料集。 在這裡,我們選擇 data\_big,這是一個與參考資料集類似的資料集,但其中的行具有較高的血壓值。我們在血壓分佈圖上看到,與綠色參考資料集相比,紅色比較資料集的分佈向右移動。 ![資料集](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1752b8elnpwalycyex4.png) ✅ 按一下此處執行場景。 ![執行應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cel6qa0xxiplxgghwhyi.png) ✅ 在頁面底部可視化結果。 在這裡,我們看到血壓列的柯爾莫哥洛夫檢定的 p 值低於 0.05,這意味著兩個血壓資料集來自同一分佈的機率低於 5%。我們可以拒絕兩個資料集來自相同分佈的假設,並得出血壓列存在漂移的結論。 ![視覺化](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mh8lftfjiypr27p10ec.png) 您可以按照下面所附的即時示範中的步驟操作,並在 GitHub 上查看原始程式碼。 這使用資料管道來比較資料集並檢測漂移。 ![資料管道](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7s7v5hpicjyoe2eojwx8.png) 查看[現場演示](https://drift-detection.taipy.cloud/)。 https://github.com/Avaiga/demo-drift-detection 星漂移偵測 ⭐️ --- 9.[錢包明智](https://github.com/Ujj1225/from_Taipy-walletWISE) ---------------------------------------------------------- ![錢包明智](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vva4tu9dxrz9fgaiavlb.png) WalletWise 就像是我們財務的友善幫手,幫助我們追蹤收入和支出。它使用 Gemini 進行交易,使用 Taipy 來了解支出。 一些不錯的功能是: ✅ 使用者可以輸入他們的收入和支出以及部門作為標題。這使他們能夠了解和探索他們從哪個部門賺了多少錢以及在哪個部門花了多少錢。 ✅ 對使用者的收入和支出進行分析,以數學方式顯示,並顯示 7 個做出更好、更明智的財務決策的提示。 ✅ 實現了一個視覺化工具,您可以在其中看到您賺錢的不同標題和您花錢的不同標題。 這是一個非常優秀的用例,並且在創造力方面非常好。 您可以閱讀[安裝說明](https://github.com/Ujj1225/from_Taipy-walletWISE?tab=readme-ov-file#installation)並查看[專案演示](https://github.com/Ujj1225/from_Taipy-walletWISE?tab=readme-ov-file#demo)。 https://github.com/Ujj1225/from\_Taipy-walletWISE Star WalletWise ⭐️ --- 10.[太皮象棋](https://github.com/KorieDrakeChaney/taipy-chess) ---------------------------------------------------------- ![棋](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xasxqldf7z1q5ie3r4nn.png) 所有應用程式中我最喜歡的一個,因為我喜歡國際象棋。哈哈! 這是一個基於20,000盤棋的國際象棋視覺化工具。您可以查看所有比賽、他們參加的開局、對手、表現最好的開局以及最成功的開局。 您可以查看資料的熱圖和圖表。 ![總移動熱圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jh1llp4vx24xtxjji042.png) 總移動熱圖 ![棋子的第一個動作](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5s9do6lop5immbmjtqwa.png) 棋子的第一個動作 您可以觀看 Korie 的[示範](https://github.com/KorieDrakeChaney/taipy-chess?tab=readme-ov-file#demo)。我愛它 :) 這清楚地表明我們使用 Taipy 的可能性沒有限制。 https://github.com/KorieDrakeChaney/taipy-chess Star Taipy Chess ⭐️ --- 11.[奧運獎牌](https://github.com/enarroied/Olympic-Medals-Taipy-App) ---------------------------------------------------------------- ![奧運獎牌](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qkl0llaopepdb1s2jxy2.png) 這是一個 Taipy 儀表板,顯示從現代奧運會開始到 2024 年初頒發的奧運獎牌資訊(即不包括 2024 年巴黎奧運會)。 ✅ 儀表板有兩個選項卡: - 一個選項卡顯示所有奧運獎牌的總結資料 - 第二個選項卡重點關注奧林匹克委員會(國家,但也包括特別委員會,例如難民委員會等)獲得的獎牌。 它還具有多種類型的圖表,例如長條圖、旭日圖、折線圖、分區統計圖和網格圖。 另外,儀表板會根據所選年份和區域類型動態更新資料。 您可以在這裡觀看演示! https://www.youtube.com/watch?v=\_1X7etBFTk0 其中涉及到許多概念,而 Eric 實現了一個非常優秀的用例! https://github.com/enarroied/Olympic-Medals-Taipy-App 奧運明星獎牌 ⭐️ --- 12. [GPT Researcher](https://github.com/assafelovic/gpt-researcher) - 基於 GPT 的線上研究自主代理。 --------------------------------------------------------------------------------------- ![GPT研究員](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4vbqw84mrere5bcfalhk.png) GPT Researcher 是領先的自主代理,負責處理從準確的來源收集到研究結果組織的一切事務。 好的一點是它也引用了研究結果的來源,從而提高了可信度。我喜歡整個概念:) 一些瘋狂的功能是: ✅ 可以產生長而詳細的研究報告(超過2K字)。 ✅ 每項研究總結 20 多個網路資源,以形成客觀和事實的結論。 ✅ 包括易於使用的網路介面(HTML/CSS/JS)。 ✅ 透過 JavaScript 支援抓取網路資源。 ✅ 追蹤存取和使用的網路資源的追蹤和上下文。 ✅ 將研究報告匯出為 PDF、Word 等。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0o49xyzfmzuvmlotgal.png) 開始使用以下命令。 ``` pip install gpt-researcher ``` 您可以這樣使用它。 ``` from gpt_researcher import GPTResearcher query = "why is Nvidia stock going up?" researcher = GPTResearcher(query=query, report_type="research_report") # Conduct research on the given query await researcher.conduct_research() # Write the report report = await researcher.write_report() ``` 請閱讀下面隨附的[安裝說明](https://github.com/assafelovic/gpt-researcher?tab=readme-ov-file#%EF%B8%8F-getting-started)和快速入門指南。 如果您想了解架構的細節,代理商會利用 gpt3.5-turbo 和 gpt-4-turbo(128K 上下文)來完成研究任務。我們僅在必要時才使用每種方法來優化成本。研究任務平均需要大約 3 分鐘才能完成,成本約為 0.1 美元。 ![建築學](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ls54ua4d3nhn473ek04.png) 您可以閱讀官方部落格了解[GPT Researcher 的工作原理](https://docs.tavily.com/blog/building-gpt-researcher)。 您可以閱讀[常見問題](https://docs.tavily.com/docs/faq)以了解有關準確性等的更多資訊。 您可以閱讀[文件](https://docs.tavily.com/docs/gpt-researcher/getting-started)並存取他們的[官方網站](https://gptr.dev/)。 在這裡觀看演示! ![GPT 研究員演示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xfgnes109mqfyk0r3uq.gif) 它在 GitHub 上有 8700 顆星,並且正在不斷改進。 https://github.com/assafelovic/gpt-researcher GPT 明星研究員 ⭐️ --- 13.[私人 GPT](https://github.com/zylon-ai/private-gpt) - 在沒有網路的情況下詢問有關您的文件的問題。 ---------------------------------------------------------------------------- ![私有GPT](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nshjqmm5xq6kgqkgfdc.png) PrivateGPT 是一個可立即投入生產的 AI 專案,即使在沒有網路連線的情況下,您也可以使用大型語言模型 (LLM) 的功能來詢問有關文件的問題。 100% 私有意味著任何時候都沒有資料離開您的執行環境。 API 分為兩個邏輯區塊: A。高級 API,抽象化了 RAG(檢索增強生成)管道實現的所有複雜性: - 文件攝取:內部管理文件解析、分割、元資料擷取、嵌入產生和儲存。 - 使用所攝取文件中的上下文進行聊天和完成:抽像上下文檢索、提示工程和回應產生。 b.低階 API,允許高階用戶實現複雜的管道: - 嵌入生成:基於一段文字。 - 上下文區塊檢索:給定查詢,從攝取的文件中傳回最相關的文字區塊。 您可以閱讀[安裝指南](https://docs.privategpt.dev/installation/getting-started/installation)來開始。 您可以閱讀[文件](https://docs.privategpt.dev/overview/welcome/introduction)以及所涉及的[詳細架構](https://github.com/zylon-ai/private-gpt?tab=readme-ov-file#-architecture)。 PrivateGPT 現在正在發展成為產生 AI 模型和原語的網關,包括補全、文件攝取、RAG 管道和其他低階建置塊。 他們在 GitHub 上擁有超過 51,000 顆星,並且發展迅速。 https://github.com/zylon-ai/private-gpt 明星私人 GPT ⭐️ --- [14.facefusion](https://github.com/facefusion/facefusion) - 下一代臉部交換器和增強器。 ------------------------------------------------------------------------- ![臉部融合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ea0w92sm51da799632vr.png) 這是下一代臉部交換器和增強器。有多種用途,您可以輕鬆做到。 他們還提供了一個[研討會部分](https://docs.facefusion.io/workshop),您可以在其中了解如何建立 UI 元件和定義框架處理器。 例如,這就是建立 UI 元件的方式。 ``` // create a new file facefusion/uis/components/example.py // Implement the essential methods of the UI component from typing import Optional import gradio from facefusion.uis.typing import Update EXAMPLE_IMAGE : Optional[gradio.Image] = None def render() -> None: global EXAMPLE_IMAGE EXAMPLE_IMAGE = gradio.Image() def listen() -> None: EXAMPLE_IMAGE.change(update, inputs = EXAMPLE_IMAGE, outputs = EXAMPLE_IMAGE) def update() -> Update: return gradio.update() ``` 您只需加入該元件即可。 ``` from facefusion.uis.components import example ``` ![作坊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxznqz8rg23q4tb2brne.png) 安裝可能有點複雜,所以我建議根據您使用的特定環境閱讀[安裝指南](https://docs.facefusion.io/installation)。 您可以使用此命令檢查基準測試。 ``` python run.py --ui-layouts benchmark ``` ![基準](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdc3s7xwjxoukee784ds.png) 您可以閱讀[文件](https://docs.facefusion.io/)並了解有關[技術術語的](https://docs.facefusion.io/knowledgebase/technical-terms)更多資訊。 他們在 GitHub 上擁有超過 14k 個 star,並且發布了`v2.5`版本。 https://github.com/facefusion/facefusion 明星facefusion ⭐️ --- 15. [H2O LLMStudio](https://github.com/h2oai/h2o-llmstudio) - 用於微調 LLM 的無程式碼 GUI。 --------------------------------------------------------------------------------- ![H2O法學碩士工作室](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a03nefeobwwf9bkhcgwg.png) H2O LLM Studio 是一個開源、無程式碼的 LLM 圖形使用者介面 (GUI),專為微調最先進的大型語言模型而設計。 微調預訓練的語言模型需要編碼專業知識以及有關模型及其超參數的廣泛知識,但是,H2O LLM Studio 使 NLP 從業者能夠輕鬆微調他們的 LLM,無需編碼,並且比定制具有更好的靈活性。 H2O LLM Studio 還可讓您與微調模型聊天並接收有關模型效能的即時回饋。 NLP 從業者和資料科學家尤其可能會發現輕鬆有效地建立和微調大型語言模型很有用。您可以閱讀[詳細的效能統計資料](https://h2oai.github.io/h2o-llmstudio/get-started/llm-studio-performance)及其雲端[架構](https://docs.h2o.ai/haic-documentation/overview/architecture)。 如果您正在開始,我建議您觀看此內容! https://www.youtube.com/watch?v=u48QaIAIFw4 您可以閱讀有關[核心功能的](https://h2oai.github.io/h2o-llmstudio/get-started/core-features)訊息,例如: ✅ 無程式碼微調 ✅ 高度可自訂 ✅ 關於模型性能的即時回饋 您可以使用以下命令啟動 H2O LLM Studio。 ``` make llmstudio ``` 如果你不知道這些概念,他們也有[清晰的概念指南,](https://h2oai.github.io/h2o-llmstudio/concepts)包括 Generative AI、LoRA、Quantization、LLM Backbone 等等。 您可以閱讀[文件](https://docs.h2o.ai/haic-documentation/)。 您可以使用它非常輕鬆且符合標準地製作一個副專案。 他們在 GitHub 上有 3,600 顆星,並且發布了`v1.5`版本。 https://github.com/h2oai/h2o-llmstudio 明星 H2O LLMStudio ⭐️ --- 16. [Mac 上的語音助理](https://github.com/chidiwilliams/GPT-Automator)- 您的語音控制 Mac 助理。 -------------------------------------------------------------------------------- ![GPT自動機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdzv06jnr3z33s7qll5k.png) 您的語音控制 Mac 助理。 GPT Automator 可讓您使用語音在 Mac 上執行任務。例如,打開應用程式、尋找餐廳、綜合資訊。太棒了:D 它是在倫敦黑客馬拉松期間建構的。 它有兩個主要部分: A。語音命令:它使用本地執行的 Whisper(Buzz 的一個分支)來產生命令。 b.命令到行動:您向配備了我們編寫的自訂工具的 LangChain 代理程式發出命令。這些工具包括使用 AppleScript 控制電腦的作業系統以及使用 JavaScript 控制活動瀏覽器。最後,就像任何優秀的人工智慧一樣,我們讓代理商使用 AppleScript 說出最終結果「{Result}」(如果您以前沒有使用過,請嘗試在 Mac 終端機中輸入「Hello World!」)。 我們製作了一個自訂工具,讓法學碩士使用 AppleScript 控制電腦。提示符是文件字串: ``` @tool def computer_applescript_action(apple_script): """ Use this when you want to execute a command on the computer. The command should be in AppleScript. Here are some examples of good AppleScript commands: Command: Create a new page in Notion AppleScript: tell application "Notion" activate delay 0.5 tell application "System Events" to keystroke "n" using {{command down}} end tell ... Write the AppleScript for the Command: Command: """ p = subprocess.Popen(['osascript', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate(applescript.encode('utf-8')) if p.returncode != 0: raise Exception(stderr) decoded_text = stdout.decode("utf-8") return decoded_text ``` 如果您想知道它是如何運作的,GPT Automator 使用 OpenAI 的 Whisper 將您的音訊輸入轉換為文字。然後,它使用LangChain Agent 選擇一組操作,包括使用OpenAI 的GPT-3(“text-davinci-003”)從提示符號產生AppleScript(用於桌面自動化)和JavaScript(用於瀏覽器自動化)命令,然後執行產生的腳本。 請記住,這不適用於生產用途。該專案執行從自然語言產生的程式碼,可能容易受到提示注入和類似的攻擊。這項工作是作為概念驗證而進行的。 您可以閱讀[安裝指南](https://github.com/chidiwilliams/GPT-Automator?tab=readme-ov-file#instructions)。 讓我們看看一些提示及其作用: ✅ 求計算結果。 > 提示:“2 + 2 是什麼?” 它將編寫 AppleScript 開啟計算器並輸入 5 \* 5。 ✅ 尋找附近的餐廳。 > 提示:“查找我附近的餐廳” 它將打開 Chrome,谷歌搜尋附近的餐廳,解析頁面,然後返回最上面的結果。有時它很厚顏無恥,反而會打開谷歌地圖結果並說「最好的餐廳是谷歌地圖頁面頂部的餐廳」。其他時候,它會打開 Google 上的頂部連結 - 並卡在 Google 可存取性頁面上... 以下是執行時列印到終端的內容: ``` Command: Find a great restaurant near Manchester. > Entering new AgentExecutor chain... I need to search for a restaurant near Manchester. Action: chrome_open_url Action Input: https://www.google.com/search?q=restaurant+near+Manchester Observation: Thought: I need to read the page Action: chrome_read_the_page Action Input: Observation: Accessibility links Skip to the main content ... # Shortned for brevity Dishoom Manchester 4.7 (3.3K) · £££ · Indian 32 Bridge St · Near John Rylands Library Closes soon ⋅ 11 pm Stylish eatery for modern Indian fare San Carlo 4.2 (2.8K) · £££ · Italian 42 King St W · Near John Rylands Library Closes soon ⋅ 11 pm Posh, sceney Italian restaurant Turtle Bay Manchester Northern Quarter 4.7 Thought: I now know the final answer Final Answer: The 15 best restaurants in Manchester include El Gato Negro, Albert's Schloss, The Refuge, Hawksmoor, On The Hush, Dishoom, Banyan, Zouk Tea Room & Grill, Edison Bar, MyLahore Manchester, Turtle Bay Manchester Northern Quarter, San Carlo, The Black Friar, Mana, and Tast Cuina Catalana. ``` 我不能保證這些餐廳值得,請自行承擔風險。哈哈! ✅ 如果您要求 GPT Automator 擦除您的計算機,它會的。 是的,如果您要求的話,它會擦除您的電腦! 我內心的自我尖叫著要這麼做:) 您可以在這裡查看完整的演示! https://www.loom.com/share/7bfa82c604f3412fbbb04191ce2ae12f --- 17. [RepoChat](https://github.com/pnkvalavala/repochat) - 支援 GitHub 儲存庫互動的聊天機器人助理。 ---------------------------------------------------------------------------------- ![重新聊天](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3gf9bjn2a47f1t43aiju.png) Repochat 是一個互動式聊天機器人專案,旨在使用大型語言模型 (LLM) 參與有關 GitHub 儲存庫的對話。 它允許用戶進行有意義的討論、提出問題並從 GitHub 儲存庫檢索相關資訊。本自述文件提供了在本機電腦上設定和使用 Repochat 的逐步說明。 他們建立了兩個具有不同功能的分支,這對我來說有點新鮮。 ✅ Repochat 的主要分支被設計為完全在您的本機電腦上執行。此版本的 Repochat 不依賴外部 API 呼叫,並且可以更好地控制您的資料和處理。如果您正在尋找獨立的解決方案,那麼主分支就是您的最佳選擇。 ✅ Repochat 的雲端分支主要依賴對外部服務的 API 呼叫來進行模型推理和儲存。它非常適合那些喜歡基於雲端的解決方案並且不想設定本地環境的人。 您可以閱讀[安裝說明](https://github.com/pnkvalavala/repochat?tab=readme-ov-file#installation)。 Repochat 讓您與聊天機器人進行對話。您可以提出問題或提供輸入,聊天機器人將從向量資料庫中檢索相關文件。 然後,它將您的輸入以及檢索到的文件傳送到語言模型以產生回應。 預設情況下,我已將模型設為`codellama-7b-instruct` ,但您可以根據計算機的速度更改它,甚至可以嘗試 13b 量化模型進行回應。 聊天機器人在對話過程中保留記憶以提供上下文相關的回應。 您可以查看[即時網站](https://repochat.streamlit.app/),您可以使用 API 金鑰進行檢查。 你可以觀看這個演示! ![示範](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o7ndxqpwkkww4f5qudiq.gif) 如果您想查看的話,我找到了另一種[選擇](https://github.com/peterw/Chat-with-Github-Repo)。 Repochat 擁有 200 多顆星,並部署在 Streamlit 上。 https://github.com/pnkvalavala/repochat 明星 RepoChat ⭐️ --- 18. [myGPTReader](https://github.com/madawei2699/myGPTReader) - 閱讀並與 AI 機器人聊天。 ------------------------------------------------------------------------------ ![我的GPT閱讀器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/58doii8daomf54te5eca.png) myGPTReader 是 Slack 上的機器人,可以閱讀和總結任何網頁、文件(包括電子書),甚至來自 YouTube 的影片。它可以透過語音與您交流。 一些有價值的功能是: ✅ 使用 myGPTReader 透過對話快速閱讀和理解任何網頁內容,甚至是影片(目前僅支援帶有字幕的 YouTube 影片)。 ![讀者](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x626mtnvqr5vw43938iw.gif) ✅ 使用 myGPTReader 快速閱讀任何文件的內容,支援電子書、PDF、DOCX、TXT 和 Markdown。 ![文件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5am7njxco7vhronuirgu.gif) ✅ 透過與 myGPTReader 語音對話來練習外語,它可以成為您的私人導師,支援中文、英語、德語和日語。 ![嗓音](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/40pzlgtuhcyxgwa1z2gs.gif) ✅ 內建大量提示模板,使用它們可以更好地與chatGPT對話。 ![問](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ehgn218hwewzeft98xkp.gif) ✅ myGPTReader 每天都會發出最新的熱門新聞,並自動產生摘要,讓您快速了解今日熱點。 您可以造訪[官方網站](https://www.myreader.io/)。 您可以加入擁有超過 5000 名會員的儲存庫上的 Slack 頻道,免費體驗所有這些功能。 它們在 GitHub 上有 4.4k 顆星,並且像此列表中的其他專案一樣使用 Python 建置。 https://github.com/madawei2699/myGPTReader 星 myGPTReader ⭐️ --- 19. [Marker](https://github.com/VikParuchuri/marker) - 將 PDF 快速且高精度地轉換為 Markdown。 --------------------------------------------------------------------------------- ![標記](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kpdu6jh9qmax5cikbah.png) Marker 將 PDF、EPUB 和 MOBI 轉換為 Markdown。它比牛軋糖快 10 倍,在大多數文件上更準確,並且產生幻覺的風險較低。 我們都知道這有多大幫助,尤其是對於研究論文來說。 ✅ 支援一系列 PDF 文件(針對書籍和科學論文進行了最佳化)。 ✅ 刪除頁首/頁尾/其他工件。 ✅ 將大多數方程式轉換為乳膠。 ✅ 設定程式碼區塊和表格的格式。 ✅ 支援多種語言(儘管大多數測驗是用英語完成的)。請參閱 settings.py 以取得語言列表,或新增您自己的語言列表。 ✅ 適用於 GPU、CPU 或 MPS。 他們也清楚地記錄了[範例](https://github.com/VikParuchuri/marker?tab=readme-ov-file#examples)以及 Marker 和 Nougat 的結果。 ![基準](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqtl447c9h0taisbj8hl.png) 性能結果採用標記和牛軋糖設置,因此它們在 A6000 上均佔用約 3GB 的 VRAM。 閱讀速度和準確性[基準測試](https://github.com/VikParuchuri/marker?tab=readme-ov-file#benchmarks)以及有關如何執行您自己的基準測試的說明。 例如,請參閱此 PDF: [Think Python](https://greenteapress.com/thinkpython/thinkpython.pdf)和[Marker](https://github.com/VikParuchuri/marker/blob/master/data/examples/marker/thinkpython.md) vs [Nougat](https://github.com/VikParuchuri/marker/blob/master/data/examples/nougat/thinkpython.md)的 markdown 檔案。 閱讀[安裝說明](https://github.com/VikParuchuri/marker?tab=readme-ov-file#installation)。 他們也記錄瞭如何正確使用它: - [轉換單一文件](https://github.com/VikParuchuri/marker?tab=readme-ov-file#convert-a-single-file) - [轉換多個文件](https://github.com/VikParuchuri/marker?tab=readme-ov-file#convert-multiple-files) - [在多個 GPU 上轉換多個文件](https://github.com/VikParuchuri/marker?tab=readme-ov-file#convert-multiple-files-on-multiple-gpus) 他們在 GitHub 上有 8k+ 星,我認為它不再被維護了。 https://github.com/VikParuchuri/marker 星標 ⭐️ --- 20. [Instrukt](https://github.com/blob42/Instrukt) - 終端機中整合人工智慧。 ---------------------------------------------------------------- ![指示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsk64pf5yuosui91tmz9.png) Instrukt是一個基於終端的AI整合環境。它提供了一個平台,用戶可以: - 建立並指導模組化人工智慧代理。 - 產生問答的文件索引。 - 建立工具並將其附加到任何代理程式。 用自然語言指導它們,並且為了安全起見,在安全容器(目前使用 Docker 實作)中執行它們,以在其專用的沙盒空間中執行任務。 使用`Langchain` 、 `Textual`和`Chroma`建構。 開始使用以下命令。 ``` pip install instrukt[all] ``` ![指示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r3aza7hnlji7hbi2o0js.gif) 有許多令人興奮的功能,例如: - 基於終端的介面,讓強力鍵盤使用者無需離開鍵盤即可指示 AI 代理。 - 對您的資料建立索引並讓代理程式檢索它以進行問答。您可以使用簡單的 UI 建立和組織索引。 - 索引建立將自動偵測程式語言並相應地優化拆分/分塊策略。 - 在安全的 Docker 容器內執行代理程式以確保安全和隱私。 - 整合的 REPL-Prompt 可實現與代理程式的快速交互,以及用於開發和測試的快速回饋循環。 - 您可以使用自訂命令自動執行重複任務。它還具有內建的提示/聊天歷史記錄。 您可以閱讀有關所有[功能的](https://github.com/blob42/Instrukt?tab=readme-ov-file#features)資訊。 您可以閱讀[安裝指南](https://blob42.github.io/Instrukt/install.html)。 您還可以使用內建的 IPython 控制台來除錯和內省代理,這是一個簡潔的小功能。 ![控制台除錯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qaan8np68e3fk1yueexm.png) Instrukt 已獲得 AGPL 許可證,這意味著任何人都可以將其用於任何目的。 可以肯定地說,Instrukt 是您觸手可及的終端人工智慧指揮官。 這是一個新專案,因此他們在 GitHub 上有大約 200 多顆星,但用例非常好。 https://github.com/blob42/Instrukt 舊指令 ⭐️ --- 21.[微代理](https://github.com/aymenfurter/microagents)- 能夠自我編輯提示的代理。 ------------------------------------------------------------------ ![微代理](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nuxv03dgb03s04dkmkm9.png) 它是一個實驗框架,用於動態建立自我改進的代理來回應任務。 微代理代表了一種建立自我改進代理的新方法。小型微服務大小(因此稱為微代理)代理是根據用戶分配給助手的任務動態生成的,評估其功能,並在成功驗證後存儲以供將來重用。 這使得跨聊天會話的學習成為可能,使系統能夠獨立推斷任務執行的方法。 這是使用`Python` 、 `OpenAI's GPT-4 Turbo`和`Text-Embedding-Ada-002`建構的。 您可以閱讀[安裝說明](https://github.com/aymenfurter/microagents?tab=readme-ov-file#installation)。他們提到您應該擁有一個可以存取 gpt-4-turbo 和 text-embedding-ada-002 的 OpenAI 帳戶。 讓我們看一個獲取天氣預報代理的範例。 ``` You are an adept weather informant. Fetch the weather forecast by accessing public API data using this Python code snippet: ``python import requests import json def fetch_weather_forecast(location, date): response = requests.get(f"https://api.met.no/weatherapi/locationforecast/2.0/compact?lat={location[0]}&lon={location[1]}") weather_data = response.json() for day_data in weather_data['properties']['timeseries']: if date in day_data['time']: print(day_data['data']['instant']['details']) break `` # Example usage: fetch_weather_forecast((47.3769, 8.5417), '2024-01-22T12:00:00Z') Note: Replace the (47.3769, 8.5417) with the actual latitude and longitude of the location and the date string accordingly. ``` 如果您想知道如何建立代理,那麼此架構圖將對此進行解釋。 ![圖表](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7oi4fbt6e5qauqo293qt.png) 您可以看到[工作演示](https://github.com/aymenfurter/microagents?tab=readme-ov-file#demo)。 他們在 GitHub 上有大約 700 顆星,值得一看。 https://github.com/aymenfurter/microagents 明星微代理 ⭐️ --- 22. [Resume Matcher](https://github.com/srbhr/Resume-Matcher) - 一個改進你的履歷的免費工具。 ------------------------------------------------------------------------------ ![履歷表匹配器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/av3u7dd3d3rm7k108w7i.png) Resume Matcher 是一款開源免費工具,可用於完善您的履歷。根據職位描述自訂您的履歷。找到匹配的關鍵字,提高可讀性,並深入了解您的履歷。 它是如何運作的? 履歷表匹配器使用 Python 讀取您的履歷和職位描述,就像 ATS 一樣。 它建議透過以下方式進行更改,使您的履歷適合 ATS: ✅ 解析:它使用 Python 分解你的履歷和工作描述。 ✅ 關鍵字提取:該工具從職位描述中尋找重要關鍵字,例如技能和資格。 ✅ 關鍵術語提取:辨識職位描述中的主題以了解其上下文。 ✅ 向量相似度:使用 FastEmbedd,它將您的履歷與職位描述進行比較,看看它們的匹配程度。配對得越好,通過 ATS 篩選的機會就越高。 ![使命](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kintryj2685slbya98zr.png) 您可以閱讀[安裝說明](https://github.com/srbhr/Resume-Matcher?tab=readme-ov-file#how-to-install)。 您可以查看[現場演示](https://resume-matcher.streamlit.app/)或自述文件中附帶的演示。 Resume Matcher 是由 Saurabh Rai 建立的一個令人驚嘆的專案,他還在 DEV 上寫了很棒的帖子! 它在 GitHub 上有 4.5k 顆星,並且仍然維護良好。 https://github.com/srbhr/Resume-Matcher 明星簡歷匹配器 ⭐️ --- 23.[背景移除器](https://github.com/nadermx/backgroundremover)- 讓您可以透過簡單的 CLI 使用 AI 從影像和影片中移除背景。 ------------------------------------------------------------------------------------------ ![背景去除劑](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8bppslk45ci383wpman.png) 這是一個使用 AI 從圖像和影片中刪除背景的命令列工具。 首先從 pypi 安裝 backgroundremover。 ``` pip install --upgrade pip pip install backgroundremover ``` 也可以在不透過 pip 安裝的情況下執行它,只需克隆 git 以在本地啟動虛擬環境安裝要求並執行。 您可以使用的一些命令: - 從本機檔案圖像中刪除背景 ``` backgroundremover -i "/path/to/image.jpeg" -o "output.png" ``` - 從本地影片中刪除背景並將其覆蓋在圖像上 ``` backgroundremover -i "/path/to/video.mp4" -toi "/path/to/videtobeoverlayed.mp4" -o "output.mov" ``` 您可以檢查可以透過 CLI 使用的所有[命令](https://github.com/nadermx/backgroundremover?tab=readme-ov-file#usage-as-a-cli)。 您甚至可以將它用作圖書館。 ``` from backgroundremover.bg import remove def remove_bg(src_img_path, out_img_path): model_choices = ["u2net", "u2net_human_seg", "u2netp"] f = open(src_img_path, "rb") data = f.read() img = remove(data, model_name=model_choices[0], alpha_matting=True, alpha_matting_foreground_threshold=240, alpha_matting_background_threshold=10, alpha_matting_erode_structure_size=10, alpha_matting_base_size=1000) f.close() f = open(out_img_path, "wb") f.write(img) f.close() ``` 您可以閱讀[安裝說明](https://github.com/nadermx/backgroundremover?tab=readme-ov-file#installation)並觀看[現場演示](https://www.backgroundremoverai.com/)。 > 輸入與輸出。 ![輸入影像](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b0rwjaxxw460lugle5z2.png) 他們在 GitHub 上有 6k star,我們絕對可以用它來學習一些重要的概念。 https://github.com/nadermx/backgroundremover 明星背景去除器 ⭐️ --- 24. [Tkinter Designer](https://github.com/ParthJadhav/Tkinter-Designer) - 建立 Python GUI 的簡單快速的方法。 ------------------------------------------------------------------------------------------------- ![Tkinter 設計師](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9dt5ij4fu948yz4fwnqc.png) Tkinter Designer 的建立是為了加快 Python 中的 GUI 開發過程。它使用著名的設計軟體Figma,讓用Python建立漂亮的Tkinter GUI變得輕而易舉。 Tkinter Designer 使用 Figma API 來分析設計檔案並建立 GUI 所需的對應程式碼和檔案。 如果您想知道它是如何工作的? 使用者唯一需要做的就是使用 Figma 設計一個介面,然後將 Figma 檔案 URL 和 API 令牌貼到 Tkinter Designer 中。 Tkinter Designer 將自動產生在 Tkinter 中建立 GUI 所需的所有程式碼和映像。 ![怎麼運作的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lb2pjsige0b9w5rynipm.png) 您可以閱讀逐步指南\](https://github.com/ParthJadhav/Tkinter-Designer/blob/master/docs/instructions.md),了解如何正確使用它,該指南有多種語言版本。 您可以在這裡觀看演示! https://www.youtube.com/watch?v=Qd-jJjduWeQ 他們還展示了您可以使用它輕鬆複製的[網站範例](https://github.com/ParthJadhav/Tkinter-Designer?tab=readme-ov-file#-examples)。 ![網站範例](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vdiyhj08bwatasonpekm.png) 它們在 GitHub 上有 8,300 顆星,並被大約 100 名開發人員使用。 https://github.com/ParthJadhav/Tkinter-Designer Tkinter 明星設計師 ⭐️ --- 25. [Open Interpreter](https://github.com/OpenInterpreter/open-interpreter) - 電腦自然語言介面。 --------------------------------------------------------------------------------------- ![打開解釋器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/av7udc5fibj1wz88w0u8.png) Open Interpreter 允許法學碩士在本地執行程式碼(Python、Javascript、Shell 等)。您可以在安裝後執行 $terpreter,透過終端機中類似 ChatGPT 的介面與 Open Interpreter 聊天。 這為電腦的通用功能提供了自然語言介面: ✅ 建立和編輯照片、影片、PDF 等。 ✅ 控制 Chrome 瀏覽器執行研究、繪製、清理和分析大型資料集。 我不了解你,但他們的[網站](https://www.openinterpreter.com/)讓我驚嘆不已! 使用此命令快速啟動。 ``` pip install open-interpreter // After installation, simply run: interpreter ``` 您可以閱讀[快速入門指南](https://docs.openinterpreter.com/getting-started/introduction)。 您應該閱讀[與 ChatGPT 程式碼解釋器的比較](https://github.com/OpenInterpreter/open-interpreter?tab=readme-ov-file#comparison-to-chatgpts-code-interpreter)以及可以使用的[命令](https://github.com/OpenInterpreter/open-interpreter?tab=readme-ov-file#commands)。 您可以閱讀[文件](https://docs.openinterpreter.com/getting-started/introduction)。 Open Interpreter 可與託管語言模型和本機語言模型搭配使用。託管模型速度更快、功能更強大,但需要付費。本地模型是私有且免費的,但能力往往較差。 它們在 GitHub 上擁有超過 48k 顆星,並被 300 多名開發人員使用。 https://github.com/OpenInterpreter/open-interpreter Star 開放式解釋器 ⭐️ --- 獲得經驗並提高編碼水平的最佳方法是建立業餘專案。 我希望您能夠建立其中一些專案,或至少獲得靈感。 評論下來告訴其他人任何其他很酷的 Python 專案:) 祝你有美好的一天! 關注 Taipy 以了解更多此類內容。 https://dev.to/taipy --- 原文出處:https://dev.to/taipy/25-projects-that-you-can-build-with-python-and-ai-12i9

使用 matcha.css 讓你的新網站瞬間變漂亮!

您是否曾經想過在開始一個新的網路專案時從「空白頁」開始是多麼的簡單? ![空白頁](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/syhnfxnz7i2cs3exqhf4.png) *請注意缺少任何樣式或自訂屬性*。 ``` <html> <body> <h1>Hello world!</h1> <p> This is my new project, and it's still under construction. Please be indulgent 😊 </p> <p> Also, check out my work on <a href="https://github.com/octocat">GitHub</a>! </p> <blockquote> <p> Imagination is more important than knowledge </p> <cite>Albert Einstein</cite> </blockquote> <menu> <li>Home</li> <li> About me <menu> <li>My works</li> <li>My passions</li> </menu> </li> <li>Contact</li> </menu> <form> <h2>Contact me</h2> <label> Your email: <input type="email" name="email" placeholder="Your email" required> </label> <label> Your message: <small>255 characters max</small> <textarea name="message" placeholder="Your message" required></textarea> </label> <button type="submit">Send</button> </form> </body> </html> ``` 哎喲!如果你向你的朋友展示這一點,同時聲稱你是網頁開發人員,他們會開始質疑你到底在做什麼... 預設瀏覽器樣式表通常非常簡單,當您製作應用程式原型、生成靜態 HTML 頁面、Markdown 生成的文件等並且不想深入研究時,如果沒有“視覺上不錯”的東西,可能會令人沮喪過早地接觸CSS 的複雜性。 好訊息!我有一些適合你的東西: [matcha.css](https://matcha.mizu.sh) ! 只需將以下內容加入到您的文件中即可看到奇蹟發生: ``` <link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css"> ``` ![抹茶頁面](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2duw5mfvuxcf0s56w7f.png) 沒有真正做任何事情,我們就得到了一個尊重用戶對淺色/深色模式的偏好、漂亮的字體和適當的間距的頁面,我們的`<menu>`實際上看起來像一個菜單,而且我們的`<form>`甚至還有「必填欄位」也相當不錯所需投入的指標。 所有這些都無需任何建置步驟、JavaScript、配置或重構。 這是因為[matcha.css](https://matcha.mizu.sh)使用語意樣式。例如,它假設嵌套在另一個`<menu>`中的`<menu>`應產生一個子選單,而`<label><input required></label>`應向使用者澄清輸入是強制性的。 還有一些「嵌入式」CSS 庫,但我相信這是最完整的一個,因為它提供了額外的開箱即用的現代樣式,如語法突出顯示、簡單佈局、實用程式類別等。 ![抹茶](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cuq2b9axcybs26lbkple.png) [matcha.css](https://matcha.mizu.sh)也很容易自訂(它沒有任何`!important`規則,甚至提供了建立自訂建置的幫助器),同時也是可逆的(如果您決定遷移出去,只需刪除樣式表)。 最後但並非最不重要的一點是,它是完全免費和開源的! https://github.com/lowlighter/matcha 請參閱[matcha.mizu.sh](https://matcha.mizu.sh)了解完整概述! --- 原文出處:https://dev.to/lowlighter/make-naked-websites-look-great-with-matchacss-4ng7

ChatGPT - 給開發人員的提示

了解 ChatGPT: ----------- ChatGPT 是一種人工智慧 (AI) 聊天機器人,它使用自然語言處理來建立類人對話。這個語言模型可以回答問題並撰寫各種書面內容,包括文章、社交媒體貼文、論文、程式碼和電子郵件,這使其成為各個層級的程式設計師都興奮的工具。 > OpenAI(一家人工智慧研究公司)建立了ChatGPT,並於2022 年11 月推出了該工具。 什麼是即時工程以及為什麼它很重要? ----------------- 及時的工程設計使用戶可以輕鬆獲得相關結果。它還有助於減輕大型語言模型訓練資料中現有的人類偏見可能存在的偏見。此外,它還增強了用戶與人工智慧的交互,因此即使輸入很少,人工智慧也能理解用戶的意圖。 在製作提示時, - 記住要清晰簡潔。 - 具體:指定程式語言選擇並清楚描述您需要的功能。例如,提示可以是“編寫一個 JavaScript 函數來計算給定數字的總和”,而不是模糊的“編寫一個函數來計算總和”。 - 包括必要的背景和細節,但避免任何含糊或不必要的資訊。 - 定義輸入和輸出:如果您需要的函數或程式碼段需要特定的輸入或輸出格式,請在提示中包含此資訊。 ChatGPT 如何幫助開發者: ---------------- ChatGPT 是一種高階語言模型,可以透過多種方式幫助開發人員完成編碼之旅。讓我們來探討其中的一些。 **1. 編寫程式碼:**使用ChatGPT,您可以根據具體描述產生程式碼。例如,如果您需要 C# 函數來計算 2 個數字中的某些數字。您可以如下所示提示 ChatGPT,它將返回相應的程式碼。 提示範例: ``` "Write a C# function to calculate the sum of the 2 given numbers." ``` **2.重構程式碼:**借助ChatGPT的幫助,您可以重構程式碼,以提高程式碼效率,減少錯誤,並使其更易於將來修改或擴展。 提示範例: ``` I have a piece of code and I need you to refactor it: INSERT YOUR CODE HERE ``` **3. 程式碼審查和偵錯:**您可以使用 ChatGPT 審查程式碼片段並分享潛在的問題或錯誤。 提示範例: ``` "Here's a C# code snippet. The function is supposed to return the maximum value from the given list, but it's not returning the expected output. Can you identify the problem?". INSERT YOUR CODE HERE ``` **4. 新增編碼最佳實務或原則:** ChatGPT 可協助您根據風格指南重寫程式碼。 提示範例: ``` Rewrite the code below following the Google style guidelines for JavaScript. INSERT YOUR CODE HERE ``` **5. 解釋程式碼:** ChatGPT 可以幫助解釋舊的和複雜的程式碼片段的工作原理。要獲得特定程式碼段的解釋,請提供程式碼片段並詢問。 提示範例: ``` "Could you please explain how this C# function works?". INSERT YOUR CODE HERE ``` **6. 最佳化程式碼:** ChatGPT 可以幫助優化程式碼,以增強效能或可讀性,使您的程式碼精簡且有效率。 提示範例: ``` "Here’s a function I wrote in JavaScript that prints first n Fibonacci Numbers. Could you suggest any optimizations for better performance?" INSERT YOUR CODE HERE ``` **7. 建立單元測試:**您可以使用 ChatGPT 透過為您編寫測試案例來自動化單元測試。 提示範例: ``` Please write unit tests for the following code. INSERT YOUR CODE HERE ``` **8. 新增程式碼註釋:**如果您的程式碼不言自明但需要註釋,ChatGPT 可以立即為您完成。 提示範例: ``` Add comments to the following code: INSERT YOUR CODE HERE ``` **9. 建立樣板程式碼:** ChatGPT 可以幫助您產生樣板程式碼。 提示範例: ``` Write a boilerplate JavaScript function that will take a variable of type User, and validate whether the user has the right permissions or not. ``` **10. 建立正規表示式:**正規表示式幫助我們匹配、定位和管理文本,提供了一種快速且相對簡單的方法來操作資料,特別是在大型複雜程式中,ChatGPT 可以幫助我們編寫這些正則表達式。 提示範例: ``` Write a regular expression that matches: REQUEST ``` 這些是 ChatGPT 如何讓開發人員的生活變得輕鬆的一些例子。除此之外,ChatGPT 還可以幫助學習新概念、理解設計模式、程式碼重構、集思廣益、面試準備等等。 ChatGPT 提示編寫程式碼: ---------------- 我收集了 ChatGPT 提示,這些提示可以讓開發人員的生活變得輕鬆,因為他們可以更有效地利用強大的 AI 支援的 ChatGPT。 - [編寫和生成程式碼的提示](https://dev.to/techiesdiary/chatgpt-prompts-for-writing-and-generating-codes-59kf) --- 原文出處:https://dev.to/techiesdiary/chatgpt-prompts-for-developers-216d

2024 年 7 個最適合開發者的圖表庫 🤯

許多應用程式使用圖表或圖形進行資料視覺化,這可以使用庫或底層技術來實現。庫提供時間效率、各種圖表類型和自訂選項。 作為開發人員,了解這些選項至關重要。雖然有些專案可能選擇手動實施,但許多專案都受益於圖表庫的效率。使用這些庫可以節省時間,並可以存取各種圖表類型和樣式選項來滿足您的需求。 在本文中,我們將踏上旅程,了解七個令人驚嘆的圖表庫、它們的功能以及如何使用它們。讓我們來看看! ![https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3 .amazonaws.com%2Fuploads%2Farticles%2Fqk7c7favj05g2qjice9m.gif](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqk7c7favj05g2qjice9m.gif) --- 1. Latitude for React:將圖表整合到前端應用程式的完美伴侶 --------------------------------------- **網址: <https://docs.latitude.so/react/getting-started/introduction>** ![https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3 .amazonaws.com%2Fuploads%2Farticles%2Fy7z7ks2yp21vj6fah42o.png](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7z7ks2yp21vj6fah42o.png) *是的,那就是我們!* Latitude 是用於嵌入式分析的開源框架,可讓您快速將 SQL 查詢公開為 API 端點。他們的產品中包括`@latitude-data/react` ,這是一組原生 React 元件,用於輕鬆繪製來自 Latitude API 的資料。如果您選擇攜帶自己的資料,它還可以用作獨立的圖表庫。 ### Latitude for React 的主要特性 - **多種圖表類型**:提供多種圖表類型顯示。例如長條圖、圓餅圖、面積圖、分散圖、混合圖等。 - **高度可自訂的元件**:元件預先捆綁了一組可用主題,或者您可以選擇輕鬆建立自己的自訂主題。最重要的是,大多數元件都可以使用自訂 html 類別進行擴充。 - **自動執行查詢或提供您自己的資料**:Latitude 為每個圖表元件提供兩個版本。其中一個版本會自動執行您的緯度查詢。另一個版本期望接收資料作為道具,讓使用者負責取得它。 ### 如何使用 Latitude for React 👀 首先,在您的 React 專案中安裝 Latitude 的 React 套件: ``` npm install --save @latitude-data/react ``` 之後,匯入 Latitude 元件所使用的核心樣式: ``` import '@latitude-data/react/dist/index.css'; ``` **帶有緯度後端** 如果您要從 Latitude 後端取得資料,**請**在專案根目錄下使用 LatitudeProvider 包裝您的應用程式: ``` import { LatitudeProvider } from '@latitude-data/react'; function App() { return ( <LatitudeProviderapiConfig={{ host: <YOUR_LATITUDE_API_HOST> }}> {/* Your app content */} </LatitudeProvider>); } ``` 並使用 Latitude 的任何帶有`Query`前綴的圖表元件: ``` import { QueryLineChart } from '@latitude-data/react'; function MyComponent() { return ( <QueryLineChart queryPath='titles' params={{ start_year: 2012, end_year: 2014 }} x='release_year'y={[ { name: 'count_shows' }, { name: 'count_movies' } ]} xTitle='Year' yTitle='Titles'/> ); } ``` 在此範例中,queryPath 對應於 Latitude 後端中定義的查詢的路徑。 **作為獨立的圖表庫** 只需使用獨立元件,例如: ``` import { LineChart } from '@latitude-data/react'; function MyComponent() { const data = [ { release_year: 2010, count_shows: 10, count_movies: 2 } ] return ( <LineChart data={data} x='release_year' y={[ { name: 'count_shows' }, { name: 'count_movies' } ]} /> ); } ``` 請閱讀[文件](https://docs.latitude.so/react/getting-started/introduction),以取得有關如何使用緯度動態顯示資料的更深入指南。 您可以隨時在 GitHub 上為我們的專案做出貢獻,如果您能為我們的專案給我們一顆星,我們將不勝感激! **[🌟 GitHub 上 React 的 Star Latitude](https://github.com/latitude-dev/latitude)** --- 2. D3.js:用於資料視覺化的JavaScript函式庫 ------------------------------ **D3 的網站: [https://d3js.org](https://d3js.org/)** ![https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3 .amazonaws.com%2Fuploads%2Farticles%2F1xhnyf40jvg3v50c2ba8.jpeg](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xhnyf40jvg3v50c2ba8.jpeg) D3 是一個低階圖表庫,提供無與倫比的客製化和靈活性。代價是學習曲線陡峭,並且與 React 或 Svelte 等常見前端框架的整合更加困難。如果您有一些非常具體的圖表需求,d3.js 可能是您唯一的選擇,但是,如果您希望在應用程式中快速整合一些簡單的圖表,那麼其他地方還有更好的選擇。 ### D3.js 的主要特性 - **自訂和靈活性:** D3.js 提供對 SVG、HTML 和 CSS 的低階存取,允許對視覺元素進行細粒度控制。這使得它具有高度的靈活性和可自訂性。 - **模組化:** D3.js 高度模組化,各種模組可以單獨使用,也可以一起使用。這允許對捆綁包大小和效能最佳化進行更多控制。 - **強大的轉換和動畫:** D3.js 為轉換和動畫提供強大的支持,為資料更新提供流暢而複雜的動畫。 - **社區和生態系統:** D3.js 擁有一個龐大且活躍的社區,提供大量文件、範例和插件。這使得您可以更輕鬆地找到支援和資源。 ### 如何使用 D3.js 👀 在您的專案中安裝 d3 的 npm 套件: ``` npm install d3 ``` 以下是有關如何將圖表新增至 id 為`#chart`的 html 元件的範例程式碼: ``` import * as d3 from 'd3'; // Data for the bar chart const data = [ { name: 'A', value: 30 }, { name: 'B', value: 80 }, { name: 'C', value: 45 }, { name: 'D', value: 60 }, { name: 'E', value: 20 }, { name: 'F', value: 90 }, { name: 'G', value: 55 } ]; // Set the dimensions and margins of the graph const margin = { top: 20, right: 30, bottom: 40, left: 40 }; const width = 500 - margin.left - margin.right; const height = 300 - margin.top - margin.bottom; // Append the svg object to the body of the page const svg = d3.select("#chart") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", `translate(${margin.left},${margin.top})`); // X axis const x = d3.scaleBand() .range([0, width]) .domain(data.map(d => d.name)) .padding(0.1); svg.append("g") .attr("transform", `translate(0,${height})`) .call(d3.axisBottom(x)) .selectAll("text") .attr("class", "axis-label") .attr("transform", "translate(-10,0)rotate(-45)") .style("text-anchor", "end"); // Y axis const y = d3.scaleLinear() .domain([0, d3.max(data, d => d.value)]) .nice() .range([height, 0]); svg.append("g") .call(d3.axisLeft(y)) .selectAll("text") .attr("class", "axis-label"); // Bars svg.selectAll(".bar") .data(data) .enter() .append("rect") .attr("class", "bar") .attr("x", d => x(d.name)) .attr("y", d => y(d.value)) .attr("width", x.bandwidth()) .attr("height", d => height - y(d.value)); ``` 正如您所看到的,D3.js 通常比其他替代方案更冗長,但它使您可以最大程度地控制可視化的各個方面。 D3 是免費且開源的。如果您覺得該專案很有趣,請在 GitHub 上給他們一個 Star ⭐️!他們目前的星數超過 108k! **[在 GitHub 上關注 D3.js ⭐️](https://github.com/d3/d3)** --- 3. Chart.js:用於基於 HTML 的圖表的靈活 JavaScript 程式庫 ------------------------------------------- **網址: [https://www.chartjs.org](https://www.chartjs.org/)** ![https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3 .amazonaws.com%2Fuploads%2Farticles%2F0m8eb9o6t93wwf7cvq7x.png](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0m8eb9o6t93wwf7cvq7x.png) 目前是業界最受歡迎的圖表庫之一,也是最容易使用的圖表庫之一。主要因其透過使用 Canvas 進行呈現而聞名,這與某些僅將資料呈現為 SVG 的圖表庫不同。 ### Chart.js 的主要特性 - **效能**:Chart.js 可以接受內部資料結構,從而減少解析和規範化的需要,從而提高效能。您還可以配置資料抽取,以在渲染資料集之前減少資料集的大小,從而加快渲染速度。 canvas的使用壓縮了DOM樹上的開銷;這有助於最大限度地減少捆綁包中 Chart.js 程式碼的大小,從而加快載入時間。 - **可存取性**:與大多數圖表庫相比,Chart.js 具有非常直接的方法,充分了解您所做的一切都在畫布上執行。您不需要複雜的自訂,因為它允許您使用其任何自訂選項來設定樣式、主題等。 - **出色的開發人員體驗**:除了擁有非常出色的社群影響力之外,Chart.js 還擁有簡單明了的文件,當出現新內容時,這些文件會經常更新。它還提供與您最喜歡的 JavaScript 框架的集成,例如 React、Svelte 等。 - **圖表響應能力**:預設情況下,Chart.js 提供響應式圖表。您可以自動將螢幕調整為不同的尺寸,並且它為圖表提供了可調整的尺寸。它確保您在所有裝置上都能獲得良好的資料視覺化效果。 ### 如何使用 Chart.js 👀 Chartjs 可以透過 npm 安裝或在執行時透過 CDN 直接下載: ``` <div> <canvas id="myChart"></canvas> </div> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script> const ctx = document.getElementById('myChart'); new Chart(ctx, { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true } } } }); </script> ``` 如果你覺得這個專案很酷,你可以在GitHub上給它一個Star⭐️!他們目前的星數超過 63k。 **[GitHub 上的 Star Chart.js ⭐️](https://github.com/chartjs/Chart.js)** --- 4. Apache ECharts:用於快速建立圖表的JavaScript視覺化工具 ------------------------------------------ **網址: [https://echarts.apache.org](https://echarts.apache.org/)** ![https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3 .amazonaws.com%2Fuploads%2Farticles%2Fce12dq55x4le8e4ezhvm.png](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fce12dq55x4le8e4ezhvm.png) ECharts 是一個開源資料視覺化函式庫,最近越來越受歡迎。它由流行的[Apache](https://apache.org/)基金會建置,並依賴[ZRender](https://github.com/ecomfe/zrender)來呈現其圖形。與其他相比,它更複雜;它僅呈現動態資料並具有不同的顯示方式。 ![https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3 .amazonaws.com%2Fuploads%2Farticles%2Fnhnpwl5uuhhu7xxdp954.gif](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhnpwl5uuhhu7xxdp954.gif) ### ECharts的主要特點 - **廣泛的圖表類型**:ECharts 支援大量的圖表類型,實際上比大多數其他競爭對手更支援更多。其中包括長條圖、折線圖、圓餅圖、散佈圖、地圖、雷達圖、箱線圖、熱圖、平行座標、桑基圖等。這種多功能性允許用戶以多種格式視覺化資料。 - **互動性:** ECharts的突出特點之一是其豐富的互動性。它包括對互動式元素的內建支持,例如工具提示、縮放、平移和資料突出顯示。用戶可以與視覺化進行交互,以更深入地了解資料。 - **效能:** ECharts 專為高效能而設計,能夠有效處理大型資料集。它利用 Canvas 和 WebGL 進行渲染,這比傳統的基於 SVG 的渲染效能更高,適用於複雜的視覺化和大資料量。 ### 如何開始使用 Apache ECharts 👀 使用 npm 安裝 echarts: ``` npm install echarts ``` 以下程式碼片段在 id 為`#chart`的 DOM 元素中建立了一個簡單的長條圖: ``` // Import ECharts import * as echarts from 'echarts'; // Initialize the chart var chartDom = document.getElementById('chart'); var myChart = echarts.init(chartDom); var option; // Specify the chart configuration option = { title: { text: 'Simple Bar Chart' }, tooltip: {}, xAxis: { data: ['A', 'B', 'C', 'D', 'E', 'F'] }, yAxis: {}, series: [ { name: 'Value', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] }; // Use the specified chart configuration option && myChart.setOption(option); ``` 如果你覺得這個專案很有趣,可以在GitHub上給它一個Star⭐️,目前他們的Star數已經接近60k了! **[GitHub 上的 Star ECharts ⭐️](https://github.com/apache/echarts)** --- 5. Nivo:用於在 React 中建立圖表應用程式的庫 ----------------------------- **網址: [https://nivo.rocks](https://nivo.rocks/)** ![https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3 .amazonaws.com%2Fuploads%2Farticles%2F2k97ihdlfubm0zs5q1rm.png](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2k97ihdlfubm0zs5q1rm.png) Nivo 是一個高階開源 JavaScript 函式庫,用於建立資料視覺化,專門設計用於與 React 搭配使用。它建置在 D3 之上,提供廣泛的圖表類型,並具有內建主題、互動性和響應式設計。以下是一些關鍵功能和方面,使 Nivo 成為 React 應用程式中資料視覺化的熱門選擇: ### Nivo 的主要特點 - **易於使用:** Nivo 的設計比 D3.js 等替代方案更用戶友好且更易於使用。它提供了更高層次的抽象,使得無需深入了解 SVG 或 DOM 操作即可輕鬆建立複雜的圖表。 - **React 整合:** Nivo 專為 React 建置,使其成為在 React 生態系統中工作的開發人員的絕佳選擇。它利用 React 基於元件的架構來輕鬆整合和重複使用。 - **主題和響應性:** Nivo 包含對主題和響應式設計的內建支持,使您可以更輕鬆地建立在不同設備上看起來不錯並與應用程式的設計相匹配的圖表。 ### 如何開始使用 Nivo 👀 如果您是 React 開發人員,開始使用 Nivo 會很容易。安裝 nivo 核心套件以及您選擇的相關圖表特定庫。在本例中,我們正在實作一個長條圖: ``` yarn add @nivo/core @nivo/bar ``` 完成後,匯入相關圖表元件並在您的 React 環境中使用它: ``` import { Bar } from '@nivo/bar'; const MyBarChart = () => { const salesData = [ { "category": "Electronics", "value": 5000 }, { "category": "Clothing", "value": 3000 }, { "category": "Furniture", "value": 2500 } ]; return ( <Bar data={salesData} indexBy="category" maxValue={6000} keyBy="id"/> ); }; export default App; ``` Nivo 是開源的,您可以在 GitHub 上為他們的專案加註星標 - 目前它們的星標數量已超過 12k! **[⭐️ GitHub 上的 Star Nivo](https://github.com/plouc/nivo)** --- 6. Plotly:適用於不同技術堆疊的開源圖表庫 ------------------------- **網址: [https://plotly.com](https://plotly.com/)** ![https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3 .amazonaws.com%2Fuploads%2Farticles%2Fdxm6bnd8u9e4wxxjv3hh.png](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdxm6bnd8u9e4wxxjv3hh.png) **Plotly**是一個開源資料視覺化函式庫,支援多種圖表類型和互動功能。它可用於多種程式語言,包括 Python、R 和 JavaScript。 Plotly.js 是該函式庫的 JavaScript 版本,建構在 D3 之上,廣泛用於建立基於 Web 的互動式視覺化。 ### Plotly 的主要特點 - **支援不同的程式語言**:Plotly 支援不同的語言,這與許多其他支援一種語言的圖表庫不同。它允許您使用任何您熟悉的語言將資料視覺化為圖表。這是[完整的清單](https://plotly.com/graphing-libraries/)。 - **複雜圖表類型:** Plotly 抽象化了 matplotlib、ggplot2 或 MATLAB 等軟體包中的統計和科學圖表類型。 - **可移植:** Plotly 圖表以 JSON 物件的形式進行聲明性描述。圖表的每個面向(例如顏色、網格線和圖例)都有一組對應的 JSON 屬性。這允許在所有不同的語言實作中使用相同的配置。 - **效能:** Plotly 的圖表主要使用 SVG,但它也可以利用 webGL 來渲染高效能視覺化。 ### 如何開始使用 Plotly 👀 如前所述,Plotly 可以與多種程式語言一起使用,但在本例中我們將專注於 Javascript。 首先,安裝相關的npm套件: ``` npm install plotly.js-dist ``` 然後,在 html 中建立一個空的 div 元素來繪製圖形: ``` <div id="tester" style="width:600px;height:250px;"></div> ``` 最後,編寫以下內容來繪製簡單的折線圖: ``` const TESTER = document.getElementById('tester'); Plotly.newPlot( TESTER, [{ x: [1, 2, 3, 4, 5], y: [1, 2, 4, 8, 16] }], { margin: { t: 0 } } ); ``` 如果您發現 Plotly 是一個很好的工具,您可以給它一顆星,並為他們在 GitHub 上的專案做出貢獻。 - **[GitHub 上的 Star Plotly Python 專案⭐️](https://github.com/plotly/plotly.py/)** --- 7.勝利:用於圖表和資料可視化的React元件 ----------------------- **網址: [https://commerce.nearform.com/open-source/victory](https://commerce.nearform.com/open-source/victory/)** ![https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3 .amazonaws.com%2Fuploads%2Farticles%2Fy1hhhtiq4cbkwnlzusin.png](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1hhhtiq4cbkwnlzusin.png) **Victory**是一個適用於 React 和 React Native 的開源模組化圖表庫。它提供了一個簡單而優雅的 API,用於建立各種資料視覺化。與 Nivo 類似,Victory 利用了 React 的優勢,使其成為已經熟悉 React 生態系統的開發人員的自然選擇。 ### Victory JS 的主要特點 - **React 和 React Native 具有相同的 API** :Victory 專為 React 和 React Native 建置,允許無縫整合到 Web 和行動應用程式中。 - 易於使用:Victory 的聲明式、基於元件的 API 使得向 React 應用程式加入視覺化變得簡單,特別是與 D3 等其他命令式方法相比。 - **互動性**:Victory 提供開箱即用的工具提示、對事件和複雜動畫的支持,以使視覺化感覺更加生動。 ### 如何開始勝利 首先,安裝 npm 套件: ``` npm install victory ``` 然後,根據您的需求匯入您想要使用的相關元件。例如: ``` import React from 'react'; import { VictoryBar } from 'victory'; const data = [ {quarter: 1, earnings: 13000}, {quarter: 2, earnings: 16500}, {quarter: 3, earnings: 14250}, {quarter: 4, earnings: 19000} ] function App() { return ( <VictoryBar data={data} // data accessor for x values x="quarter" // data accessor for y values y="earnings" /> } ``` 如果您覺得 Victory 很酷,您可以繼續在 GitHub 上給該專案一顆星。目前他們的星數超過 10,000 **[GitHub 上的明星勝利 ⭐️](https://github.com/FormidableLabs/victory)** --- 結論 -- 恭喜您已經走到這一步了! 在本文中,我們介紹了今年要探索的 7 個圖表庫。我們已經超越了簡單的概述,而是發現了每個庫的工作原理、其底層架構以及用於建置它的技術。此外,我們還學習如何開始將這些庫合併到您的專案中。 在我們分道揚鑣之前,如果您認為本文有幫助,請考慮在[GitHub](https://github.com/latitude-dev/latitude)上給我們一顆星來表達您的支持。感謝您的閱讀,我期待您參與下一篇文章! 👋 --- 原文出處:https://dev.to/latitude/7-best-chart-libraries-for-developers-in-2024-25he

JavaScript 安全性:保護前端安全的簡單實踐

我不了解你,但我的職業生涯始於在小型機構擔任前端開發人員,那裡沒有人關心安全性。當我轉而在更大的公司從事更大的專案時,我一直不關心安全性,因為沒有人更好地教我,**這給我帶來了麻煩**。 了解如何保護您的 JavaScript 程式碼可以改變這種狀況,並幫助我們保護我們的應用程式和使用者。 --- 本文將探討一些不會傷害 JavaScript 開發人員的安全實踐,只要它們有意義,就可以實施。 --- **上面的一些主題是我在研究該主題時學到的,但是還有更多方法可以使您的程式碼安全。我只是分享一些簡單的方法來幫助您入門。** \*PS 是的,我向人工智慧提出了問題,並要求它幫助我舉例。 PS2 是的,IA 建立了封面圖片,因為我知道自己的弱點 LOL\* --- 1. 保持你的依賴項是最新的 -------------- 過時的庫可能會使您的應用程式面臨安全漏洞。保持所有內容都是最新的可以幫助您避免已經修復的已知問題。 - 使用套件管理器: **npm(節點套件管理器)**是一個很棒的工具,可以幫助您管理和更新庫。 - 定期檢查:執行 npm outdated 以查看哪些軟體包已過時。 - 定期更新:使用 npm update 將軟體套件升級到最新版本。 ``` - Automate Security Updates: Tools like npm audit identify and suggest fixes for security vulnerabilities. ``` --- {% cta https://github.com/webcrumbs-community/webcrumbs %} ⭐ 您可以考慮在 GitHub 上給我們一個 Star 嗎? {% 結束%} --- 2.使用簡單的安全標頭 ----------- 安全標頭告訴瀏覽器在處理網站內容時的行為方式,這有助於防止某些類型的攻擊,例如跨網站腳本和資料注入。 我們可以使用**內容安全策略 (CSP)** ,這是一種安全標頭,有助於阻止未經授權的腳本在您的網站上執行,從而防止許多攻擊。 從簡單開始:新增一個基本的 CSP 標頭,僅允許來自您網站的腳本。 ``` <!-- Add to the <head> section of your HTML --> <meta http-equiv="Content-Security-Policy" content="script-src 'self';"> ``` 此行意味著只能執行屬於您網站的腳本,而不能執行其他地方的腳本。 --- 3. 清理使用者輸入 ---------- 如果處理不當,用戶輸入可能會很危險。惡意使用者可能會嘗試輸入可能損害其他使用者或您的網站的資料。 **我們應該始終將輸入視為不可信的**,清理來自用戶的資料以確保其安全,然後再在應用程式中使用它。 當使用使用者輸入更新網頁時,請使用textContent 而不是innerHTML 以避免執行有害腳本。 ``` const userInput = document.querySelector('#user-input').value; document.getElementById('output').textContent = userInput; // Safely add user content to your page ``` --- 現在我們更安全了朋友們… ------------ 這三個步驟是保護 JavaScript 應用程式的一個很好的起點。 我希望您今天能花點時間回顧一下您的 JavaScript 專案。檢查是否有過時的庫,確保您使用安全標頭,並驗證所有使用者輸入是否已清理。 小步驟可以對您的 Web 應用程式的安全性產生很大影響。 說到前端... ------- 我們正在建立這個超酷的專案,它將改變您進行 Web 開發的方式😯 {% cta https://github.com/webcrumbs-community/webcrumbs %} ⭐ 您可以考慮在 GitHub 上給我們一個 Star 嗎? {% 結束%} **謝謝閱讀,** 帕奇💚 --- 原文出處:https://dev.to/buildwebcrumbs/javascript-security-simple-practices-to-secure-your-frontend-18ii

我正在建立一個人工智慧驅動的部落格:具體方法如下...

人工智慧時代已經來臨。身為開發者,要想取得成功,在你的投資組合中加入一些人工智慧驅動的專案是很棒的。 今天,我們將建立一個由人工智慧驅動的部落格平台,該平台具有一些很棒的功能,例如研究、自動完成和 Copilot。 我[在這裡](https://dev.to/copilotkit/how-to-build-an-ai-powered-blogging-platform-nextjs-langchain-supabase-1hdp)建立了該專案的初始版本。一位評論者提出了一些非常酷的建議,可以將其提升到一個新的水平。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2pbxvo6rff8xz8a0h3b.png) 所以我們決定建造它! **長話短說** -------- 我們正在建立一個由人工智慧驅動的部落格平台 Pt。二 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bi1j9iq1jkll1r21f1e8.gif) --- CopilotKit:建構應用內人工智慧副駕駛的框架 ========================== CopilotKit是一個[開源的AI副駕駛平台](https://github.com/CopilotKit/CopilotKit)。我們可以輕鬆地將強大的人工智慧整合到您的 React 應用程式中。 建造: - ChatBot:上下文感知的應用內聊天機器人,可以在應用程式內執行操作 💬 - CopilotTextArea:人工智慧驅動的文字字段,具有上下文感知自動完成和插入功能📝 - 聯合代理:應用程式內人工智慧代理,可以與您的應用程式和使用者互動🤖 ![上傳圖片](...) {% cta https://github.com/CopilotKit/CopilotKit %} Star CopilotKit ⭐️ {% endcta %} 現在回到文章! --- 先決條件 ---- 要完全理解本教程,您需要對 React 或 Next.js 有基本的了解。 以下是建立人工智慧部落格所需的工具: - [Quill 富文本編輯器](https://quilljs.com/)- 一個文字編輯器,可讓您輕鬆設定文字格式、新增圖片、新增程式碼以及在 Web 應用程式中建立自訂互動式內容。 - [Supabase](https://supabase.com/) - 一項 PostgreSQL 託管服務,為您提供專案所需的所有後端功能。 - [Langchain](https://www.langchain.com/) - 提供了一個框架,使人工智慧代理能夠搜尋網路並研究任何主題。 - [OpenAI API](https://platform.openai.com/api-keys) - 提供 API 金鑰,讓您能夠使用 ChatGPT 模型執行各種任務。 - [Tavily AI](https://tavily.com/) - 一個搜尋引擎,使人工智慧代理能夠在應用程式中進行研究並存取即時知識。 - [CopilotKit](https://github.com/CopilotKit) - 一個開源副駕駛框架,用於建立自訂 AI 聊天機器人、應用程式內 AI 代理程式和文字區域。 專案設定和套件安裝 --------- 首先,透過在終端機中執行以下程式碼片段來建立 Next.js 應用程式: ``` npx create-next-app@latest aiblogapp ``` 選擇您首選的配置設定。在本教學中,我們將使用 TypeScript 和 Next.js App Router。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pae912scgh9tjfa75l8t.png) 接下來,安裝 Quill 富文本編輯器、Supabase 和 Langchain 軟體包及其相依性。 ``` npm install quill react-quill @supabase/supabase-js @supabase/ssr @supabase/auth-helpers-nextjs @langchain/langgraph ``` 最後,安裝 CopilotKit 軟體套件。這些套件使我們能夠從 React 狀態檢索資料並將 AI copilot 新增至應用程式。 ``` npm install @copilotkit/react-ui @copilotkit/react-textarea @copilotkit/react-core @copilotkit/backend ``` 恭喜!您現在已準備好建立由人工智慧驅動的部落格。 **建構部落格前端** ----------- 在本節中,我將引導您完成使用靜態內容建立部落格前端以定義部落格使用者介面的過程。 部落格的前端將由四個頁面組成:主頁、貼文頁面、建立貼文頁面和登入/註冊頁面。 首先,請在程式碼編輯器中前往`/[root]/src/app`並建立一個名為`components`的資料夾。在 Components 資料夾中,建立五個名為`Header.tsx` 、 `Posts.tsx` 、 `Post.tsx` 、 `Comment.tsx`和`QuillEditor.tsx`的文件 在`Header.tsx`檔案中,新增以下程式碼,定義一個名為`Header`的功能元件,該元件將呈現部落格的導覽列。 ``` "use client"; import Link from "next/link"; export default function Header() { return ( <> <header className="flex flex-wrap sm:justify-start sm:flex-nowrap z-50 w-full bg-gray-800 border-b border-gray-200 text-sm py-3 sm:py-0 "> <nav className="relative max-w-7xl w-full mx-auto px-4 sm:flex sm:items-center sm:justify-between sm:px-6 lg:px-8" aria-label="Global"> <div className="flex items-center justify-between"> <Link className="flex-none text-xl text-white font-semibold " href="/" aria-label="Brand"> AIBlog </Link> </div> <div id="navbar-collapse-with-animation" className=""> <div className="flex flex-col gap-y-4 gap-x-0 mt-5 sm:flex-row sm:items-center sm:justify-end sm:gap-y-0 sm:gap-x-7 sm:mt-0 sm:ps-7"> <Link className="flex items-center font-medium text-gray-500 border-2 border-indigo-600 text-center p-2 rounded-md hover:text-blue-600 sm:border-s sm:my-6 " href="/createpost"> Create Post </Link> <form action={""}> <button className="flex items-center font-medium text-gray-500 border-2 border-indigo-600 text-center p-2 rounded-md hover:text-blue-600 sm:border-s sm:my-6 " type="submit"> Logout </button> </form> <Link className="flex items-center font-medium text-gray-500 border-2 border-indigo-600 text-center p-2 rounded-md hover:text-blue-600 sm:border-s sm:my-6 " href="/login"> Login </Link> </div> </div> </nav> </header> </> ); } ``` 在`Posts.tsx`檔案中,新增以下程式碼,定義一個名為`Posts`的功能元件,該元件呈現部落格平台主頁,該首頁將顯示已發佈文章的清單。 ``` "use client"; import React, { useEffect, useState } from "react"; import Image from "next/image"; import Link from "next/link"; export default function Posts() { const [articles, setArticles] = useState<any[]>([]); return ( <div className="max-w-[85rem] h-full px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto"> <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-6"> <Link key={""} className="group flex flex-col h-full bg-gray-800 border border-gray-200 hover:border-transparent hover:shadow-lg transition-all duration-300 rounded-xl p-5 " href=""> <div className="aspect-w-16 aspect-h-11"> <Image className="object-cover h-48 w-96 rounded-xl" src={`https://source.unsplash.com/featured/?${encodeURIComponent( "Hello World" )}`} width={500} height={500} alt="Image Description" /> </div> <div className="my-6"> <h3 className="text-xl font-semibold text-white ">Hello World</h3> </div> </Link> </div> </div> ); } ``` 在`QuillEditor.tsx`檔案中,新增以下程式碼,用於動態匯入 QuillEditor 元件、定義 Quill 編輯器工具列的模組配置以及定義 Quill 編輯器的文字格式。 ``` // Import the dynamic function from the "next/dynamic" package import dynamic from "next/dynamic"; // Import the CSS styles for the Quill editor's "snow" theme import "react-quill/dist/quill.snow.css"; // Export a dynamically imported QuillEditor component export const QuillEditor = dynamic(() => import("react-quill"), { ssr: false }); // Define modules configuration for the Quill editor toolbar export const quillModules = { toolbar: [ // Specify headers with different levels [{ header: [1, 2, 3, false] }], // Specify formatting options like bold, italic, etc. ["bold", "italic", "underline", "strike", "blockquote"], // Specify list options: ordered and bullet [{ list: "ordered" }, { list: "bullet" }], // Specify options for links and images ["link", "image"], // Specify alignment options [{ align: [] }], // Specify color options [{ color: [] }], // Specify code block option ["code-block"], // Specify clean option for removing formatting ["clean"], ], }; // Define supported formats for the Quill editor export const quillFormats = [ "header", "bold", "italic", "underline", "strike", "blockquote", "list", "bullet", "link", "image", "align", "color", "code-block", ]; ``` 在`Post.tsx`檔案中,新增以下程式碼,定義一個名為`CreatePost`功能元件,該元件將用於呈現文章建立表單。 ``` "use client"; // Importing React hooks and components import { useRef, useState } from "react"; import { QuillEditor } from "./QuillEditor"; import { quillModules } from "./QuillEditor"; import { quillFormats } from "./QuillEditor"; import "react-quill/dist/quill.snow.css"; // Define the CreatePost component export default function CreatePost() { // Initialize state variables for article outline, copilot text, and article title const [articleOutline, setArticleOutline] = useState(""); const [copilotText, setCopilotText] = useState(""); const [articleTitle, setArticleTitle] = useState(""); // State variable to track if research task is running const [publishTaskRunning, setPublishTaskRunning] = useState(false); // Handle changes to the editor content const handleEditorChange = (newContent: any) => { setCopilotText(newContent); }; return ( <> {/* Main */} <div className="p-3 max-w-3xl mx-auto min-h-screen"> <h1 className="text-center text-white text-3xl my-7 font-semibold"> Create a post </h1> {/* Form for creating a post */} <form action={""} className="flex flex-col gap-4 mb-2 mt-2"> <div className="flex flex-col gap-4 sm:flex-row justify-between mb-2"> {/* Input field for article title */} <input type="text" id="title" name="title" placeholder="Title" value={articleTitle} onChange={(event) => setArticleTitle(event.target.value)} className="flex-1 block w-full rounded-lg border text-sm border-gray-600 bg-gray-700 text-white placeholder-gray-400 focus:border-cyan-500 focus:ring-cyan-500" /> </div> {/* Hidden textarea for article content */} <textarea className="p-4 w-full aspect-square font-bold text-xl bg-slate-800 text-white rounded-lg resize-none hidden" id="content" name="content" value={copilotText} placeholder="Write your article content here" onChange={(event) => setCopilotText(event.target.value)} /> {/* Quill editor component */} <QuillEditor onChange={handleEditorChange} modules={quillModules} formats={quillFormats} className="h-80 mb-12 text-white" /> {/* Submit button for publishing the post */} <button type="submit" disabled={publishTaskRunning} className={`bg-blue-500 text-white font-bold py-2 px-4 rounded ${ publishTaskRunning ? "opacity-50 cursor-not-allowed" : "hover:bg-blue-700" }`} onClick={async () => { try { setPublishTaskRunning(true); } finally { setPublishTaskRunning(false); } }}> {publishTaskRunning ? "Publishing..." : "Publish"} </button> </form> </div> </> ); } ``` 在`Comment.tsx`檔案中,新增以下程式碼,定義一個名為 Comment 的功能元件,該元件呈現貼文評論表單和貼文評論。 ``` // Client-side rendering "use client"; // Importing React and Next.js components import React, { useEffect, useRef, useState } from "react"; import Image from "next/image"; // Define the Comment component export default function Comment() { // State variables for comment, comments, and article content const [comment, setComment] = useState(""); const [comments, setComments] = useState<any[]>([]); const [articleContent, setArticleContent] = useState(""); return ( <div className="max-w-2xl mx-auto w-full p-3"> {/* Form for submitting a comment */} <form action={""} className="border border-teal-500 rounded-md p-3 mb-4"> {/* Textarea for entering a comment */} <textarea id="content" name="content" placeholder="Add a comment..." rows={3} onChange={(e) => setComment(e.target.value)} value={comment} className="hidden" /> {/* Submit button */} <div className="flex justify-between items-center mt-5"> <button type="submit" className="bg-blue-500 text-white font-bold py-2 px-4 rounded"> Submit </button> </div> </form> {/* Comments section */} <p className="text-white mb-2">Comments:</p> {/* Comment item (currently hardcoded) */} <div key={""} className="flex p-4 border-b dark:border-gray-600 text-sm"> <div className="flex-shrink-0 mr-3"> {/* Profile picture */} <Image className="w-10 h-10 rounded-full bg-gray-200" src={`(link unavailable){encodeURIComponent( "Silhouette" )}`} width={500} height={500} alt="Profile Picture" /> </div> <div className="flex-1"> <div className="flex items-center mb-1"> {/* Username (currently hardcoded as "Anonymous") */} <span className="font-bold text-white mr-1 text-xs truncate"> Anonymous </span> </div> {/* Comment text (currently hardcoded as "No Comments") */} <p className="text-gray-500 pb-2">No Comments</p> </div> </div> </div> ); } ``` 接下來,前往`/[root]/src/app`並建立一個名為`[slug]`的資料夾。在 \[slug\] 資料夾中,建立一個`page.tsx`檔案。 然後將以下程式碼新增至匯入`Comment`和`Header`元件的檔案中,並定義一個名為`Post`功能元件,該元件將呈現導覽列、貼文內容、評論表單和貼文評論。 ``` import Header from "../components/Header"; import Comment from "../components/Comment"; export default async function Post() { return ( <> <Header /> <main className="p-3 flex flex-col max-w-6xl mx-auto min-h-screen"> <h1 className="text-3xl text-white mt-10 p-3 text-center font-serif max-w-2xl mx-auto lg:text-4xl"> Hello World </h1> <div className="flex justify-between text-white p-3 border-b border-slate-500 mx-auto w-full max-w-2xl text-xs"> <span></span> <span className="italic">0 mins read</span> </div> <div className="p-3 max-w-2xl text-white mx-auto w-full post-content border-b border-slate-500 mb-2"> No Post Content </div> <Comment /> </main> </> ); } ``` 之後,轉到`/[root]/src/app`並建立一個名為`createpost`的資料夾。在`createpost`資料夾中,建立一個名為`page.tsx`檔案。 然後將以下程式碼新增至匯入`CreatePost`和`Header`元件的檔案中,並定義一個名為`WriteArticle`的功能元件,該元件將呈現導覽列和貼文建立表單。 ``` import CreatePost from "../components/Post"; import Header from "../components/Header"; import { redirect } from "next/navigation"; export default async function WriteArticle() { return ( <> <Header /> <CreatePost /> </> ); } ``` 接下來,前往`/[root]/src/page.tsx`文件,新增以下程式碼,導入`Posts`和`Header`元件並定義名為`Home`功能元件。 ``` import Header from "./components/Header"; import Posts from "./components/Posts"; export default async function Home() { return ( <> <Header /> <Posts /> </> ); } ``` 之後,請轉到`next.config.mjs`檔案並將其重新命名為`next.config.js` 。然後加入以下程式碼,允許您使用 Unsplash 中的圖像作為已發布文章的封面圖像。 ``` module.exports = { images: { remotePatterns: [ { protocol: "https", hostname: "source.unsplash.com", }, ], }, }; ``` 接下來,刪除 globals.css 檔案中的 CSS 程式碼並新增以下 CSS 程式碼。 ``` @tailwind base; @tailwind components; @tailwind utilities; body { height: 100vh; background-color: rgb(16, 23, 42); } .ql-editor { font-size: 1.25rem; } .post-content p { margin-bottom: 0.5rem; } .post-content h1 { font-size: 1.5rem; font-weight: 600; font-family: sans-serif; margin: 1.5rem 0; } .post-content h2 { font-size: 1.4rem; font-family: sans-serif; margin: 1.5rem 0; } .post-content a { color: rgb(73, 149, 199); text-decoration: none; } .post-content a:hover { text-decoration: underline; } ``` 最後,在命令列上執行命令`npm run dev` ,然後導航到 http://localhost:3000/。 現在您應該在瀏覽器上查看部落格平台前端,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mz1qewlt9gkf2vbp5jqq.png) **使用 CopilotKit 將 AI 功能整合到部落格中** -------------------------------- 在本節中,您將學習如何為部落格加入 AI 副駕駛,以使用 CopilotKit 執行部落格主題研究和內容自動建議。 CopilotKit 提供前端和[後端](https://docs.copilotkit.ai/getting-started/quickstart-backend)套件。它們使您能夠插入 React 狀態並使用 AI 代理在後端處理應用程式資料。 首先,讓我們將 CopilotKit React 元件加入到部落格前端。 ### **將 CopilotKit 新增至部落格前端** 在這裡,我將引導您完成將部落格與 CopilotKit 前端整合的過程,以方便部落格文章研究和文章大綱生成。 首先,使用下面的程式碼片段在`/[root]/src/app/components/Post.tsx`檔案頂部匯入`useMakeCopilotReadable` 、 `useCopilotAction` 、 `CopilotTextarea`和`HTMLCopilotTextAreaElement`自訂掛鉤。 ``` import { useMakeCopilotReadable, useCopilotAction, } from "@copilotkit/react-core"; import { CopilotTextarea, HTMLCopilotTextAreaElement, } from "@copilotkit/react-textarea"; ``` 在 CreatePost 函數內的狀態變數下方,加入以下程式碼,該程式碼使用`useMakeCopilotReadable`掛鉤來新增將作為應用程式內聊天機器人的上下文產生的文章大綱。鉤子使副駕駛可以閱讀文章大綱。 ``` useMakeCopilotReadable( "Blog article outline: " + JSON.stringify(articleOutline) ); ``` 在`useMakeCopilotReadable`掛鉤下方,使用以下程式碼建立一個名為`copilotTextareaRef`的引用,該引用指向名為`HTMLCopilotTextAreaElement`的文字區域元素。 ``` const copilotTextareaRef = useRef<HTMLCopilotTextAreaElement>(null); ``` 在上面的程式碼下方,加入以下程式碼,該程式碼使用`useCopilotAction`掛鉤來設定名為`researchBlogArticleTopic`的操作,該操作將啟用對部落格文章的給定主題的研究。 此操作採用兩個參數,稱為`articleTitle`和`articleOutline` ,這兩個參數可以產生文章標題和大綱。 該操作包含一個處理程序函數,該函數根據給定主題生成文章標題和大綱。 在處理函數內部, `articleOutline`狀態會使用新產生的大綱進行更新,而`articleTitle`狀態會使用新產生的標題進行更新,如下所示。 ``` // Define a Copilot action useCopilotAction( { // Action name and description name: "researchBlogArticleTopic", description: "Research a given topic for a blog article.", // Parameters for the action parameters: [ { // Parameter 1: articleTitle name: "articleTitle", type: "string", description: "Title for a blog article.", required: true, // This parameter is required }, { // Parameter 2: articleOutline name: "articleOutline", type: "string", description: "Outline for a blog article that shows what the article covers.", required: true, // This parameter is required }, ], // Handler function for the action handler: async ({ articleOutline, articleTitle }) => { // Set the article outline and title using state setters setArticleOutline(articleOutline); setArticleTitle(articleTitle); }, }, [] // Dependencies (empty array means no dependencies) ); ``` 在上面的程式碼下方,前往表單元件並新增以下`CopilotTextarea`元件,該元件可讓您為文章內容新增文字完成、插入和編輯。 ``` <CopilotTextarea className="p-4 h-72 w-full rounded-lg mb-2 border text-sm border-gray-600 bg-gray-700 text-white placeholder-gray-400 focus:border-cyan-500 focus:ring-cyan-500 resize-none" ref={copilotTextareaRef} placeholder="Start typing for content autosuggestion." value={articleOutline} rows={5} autosuggestionsConfig={{ textareaPurpose: articleTitle, chatApiConfigs: { suggestionsApiConfig: { forwardedParams: { max_tokens: 5, stop: ["\n", ".", ","], }, }, insertionApiConfig: {}, }, debounceTime: 250, }} /> ``` 之後,請前往`/[root]/src/app/createpost/page.tsx`檔案並使用下面的程式碼匯入頂部的 CopilotKit 前端套件和樣式。 ``` import { CopilotKit } from "@copilotkit/react-core"; import { CopilotPopup } from "@copilotkit/react-ui"; import "@copilotkit/react-ui/styles.css"; ``` 然後使用`CopilotKit`包裝`CopilPopup`和`CreatePost`元件,如下圖所示。 `CopilotKit`元件指定 CopilotKit 後端端點 ( `/api/copilotkit/` ) 的 URL,而`CopilotPopup`則呈現應用程式內聊天機器人,您可以提示您研究文章的任何主題。 ``` export default async function WriteArticle() { return ( <> <Header /> <CopilotKit url="/api/copilotkit"> <CopilotPopup instructions="Help the user research a blog article topic." defaultOpen={true} labels={{ title: "Blog Article Research AI Assistant", initial: "Hi! 👋 I can help you research any topic for a blog article.", }} /> <CreatePost /> </CopilotKit> </> ); } ``` 之後,使用下面的程式碼片段在`/[root]/src/app/components/Comment.tsx`檔案頂部導入`useMakeCopilotReadable` 、 `CopilotKit` 、 `CopilotTextarea`和`HTMLCopilotTextAreaElement`自訂掛鉤。 ``` import { useMakeCopilotReadable, CopilotKit } from "@copilotkit/react-core"; import { CopilotTextarea, HTMLCopilotTextAreaElement, } from "@copilotkit/react-textarea"; ``` 在 Comment 函數內的狀態變數下方,新增以下程式碼,程式碼使用`useMakeCopilotReadable`掛鉤將貼文內容新增為評論內容自動建議的上下文。 ``` useMakeCopilotReadable( "Blog article content: " + JSON.stringify(articleContent) ); const copilotTextareaRef = useRef<HTMLCopilotTextAreaElement>(null); ``` 然後將CopilotTextarea元件加入評論表單中,並使用`CopilotKit`包裹表單,如下所示。 ``` <CopilotKit url="/api/copilotkit"> <form action={""} className="border border-teal-500 rounded-md p-3 mb-4"> <textarea id="content" name="content" placeholder="Add a comment..." rows={3} onChange={(e) => setComment(e.target.value)} value={comment} className="hidden" /> <CopilotTextarea className="p-4 w-full rounded-lg mb-2 border text-sm border-gray-600 bg-gray-700 text-white placeholder-gray-400 focus:border-cyan-500 focus:ring-cyan-500 resize-none" ref={copilotTextareaRef} placeholder="Start typing for content autosuggestion." onChange={(event) => setComment(event.target.value)} rows={5} autosuggestionsConfig={{ textareaPurpose: articleContent, chatApiConfigs: { suggestionsApiConfig: { forwardedParams: { max_tokens: 5, stop: ["\n", ".", ","], }, }, insertionApiConfig: {}, }, debounceTime: 250, }} /> <div className="flex justify-between items-center mt-5"> <button type="submit" className="bg-blue-500 text-white font-bold py-2 px-4 rounded"> Submit </button> </div> </form> </CopilotKit> ``` 之後,執行開發伺服器並導航到 http://localhost:3000/createpost。您應該會看到彈出的應用程式內聊天機器人和 CopilotTextarea 已整合到部落格中。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0j5ly5l5cf0ldaf3hwgx.png) 恭喜!您已成功將 CopilotKit 新增至部落格前端**。** ### **將 CopilotKit 後端加入博客** 在這裡,我將引導您完成部落格與 CopilotKit 後端的整合過程,CopilotKit 後端處理來自前端的請求,並提供函數呼叫和各種 LLM 後端(例如 GPT)。 此外,我們將整合一個名為 Tavily 的人工智慧代理,它可以研究網路上的任何主題。 首先,在根目錄中建立一個名為`.env.local`的檔案。然後在保存`ChatGPT`和`Tavily` Search API 金鑰的檔案中加入下面的環境變數。 ``` OPENAI_API_KEY="Your ChatGPT API key" TAVILY_API_KEY="Your Tavily Search API key" ``` 若要取得 ChatGPT API 金鑰,請導覽至 https://platform.openai.com/api-keys。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ei04w6fadsmalbjaocun.png) 若要取得 Tavilly Search API 金鑰,請導覽至 https://app.tavily.com/home ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qqbqb5wvrnkv1vc8z7hf.png) 之後,轉到`/[root]/src/app`並建立一個名為`api`的資料夾。在`api`資料夾中,建立一個名為`copilotkit`的資料夾。 在`copilotkit`資料夾中,建立一個名為`research.ts`的檔案。然後導航到[該 Research.ts gist 文件](https://gist.github.com/TheGreatBonnie/58dc21ebbeeb8cbb08df665db762738c),複製程式碼,並將其新增至**`research.ts`**檔案中 接下來,在`/[root]/src/app/api/copilotkit`資料夾中建立一個名為`route.ts`的檔案。該文件將包含設定後端功能來處理 POST 請求的程式碼。它有條件地包括對給定主題進行研究的“研究”操作。 現在在文件頂部導入以下模組。 ``` import { CopilotBackend, OpenAIAdapter } from "@copilotkit/backend"; // For backend functionality with CopilotKit. import { researchWithLangGraph } from "./research"; // Import a custom function for conducting research. import { AnnotatedFunction } from "@copilotkit/shared"; // For annotating functions with metadata. ``` 在上面的程式碼下面,定義一個執行時間環境變數和一個名為`researchAction`的函數,該函數使用下面的程式碼研究某個主題。 ``` // Define a runtime environment variable, indicating the environment where the code is expected to run. export const runtime = "edge"; // Define an annotated function for research. This object includes metadata and an implementation for the function. const researchAction: AnnotatedFunction<any> = { name: "research", // Function name. description: "Call this function to conduct research on a certain topic. Respect other notes about when to call this function", // Function description. argumentAnnotations: [ // Annotations for arguments that the function accepts. { name: "topic", // Argument name. type: "string", // Argument type. description: "The topic to research. 5 characters or longer.", // Argument description. required: true, // Indicates that the argument is required. }, ], implementation: async (topic) => { // The actual function implementation. console.log("Researching topic: ", topic); // Log the research topic. return await researchWithLangGraph(topic); // Call the research function and return its result. }, }; ``` 然後在上面的程式碼下加入下面的程式碼來定義處理POST請求的非同步函數。 ``` // Define an asynchronous function that handles POST requests. export async function POST(req: Request): Promise<Response> { const actions: AnnotatedFunction<any>[] = []; // Initialize an array to hold actions. // Check if a specific environment variable is set, indicating access to certain functionality. if (process.env["TAVILY_API_KEY"]) { actions.push(researchAction); // Add the research action to the actions array if the condition is true. } // Instantiate CopilotBackend with the actions defined above. const copilotKit = new CopilotBackend({ actions: actions, }); // Use the CopilotBackend instance to generate a response for the incoming request using an OpenAIAdapter. return copilotKit.response(req, new OpenAIAdapter()); } ``` 恭喜!您已成功將 CopilotKit 後端新增至 Blog **。** **使用 Supabase 將資料庫整合到博客** ------------------------- 在本節中,我將引導您完成將部落格與 Supabase 資料庫整合以插入和獲取部落格文章和評論資料的過程。 首先,導覽至[supabase.com](http://supabase.com/)並點擊主頁上的「啟動您的專案」按鈕。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu4h1xuhvkbtttqvry1o.png) 然後新建一個專案,名為AiBloggingPlatform,如下圖所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01uq8s2l9yoa6cvpmocl.png) 建立專案後,將 Supabase URL 和 API 金鑰新增至`env.local`檔案中的環境變數中,如下所示。 ``` NEXT_PUBLIC_SUPABASE_URL=”Your Supabase URL” NEXT_PUBLIC_SUPABASE_ANON_KEY=”Your Supabase API Key” ``` ### **為部落格設定 Supabase 身份驗證** 在這裡,我將引導您完成為部落格設定身份驗證的過程,使用戶能夠註冊、登入或登出。 首先,前往`/[root]/src/`並建立一個名為`utils`資料夾。在`utils`資料夾中,建立一個名為`supabase`的資料夾。 然後在`supabase`資料夾中建立兩個名為`client.ts`和`server.ts`檔案。 之後,導航到此[supabase 文件連結](https://supabase.com/docs/guides/auth/server-side/nextjs#:~:text=Write%20utility%20functions%20to%20create%20Supabase%20clients),複製此處提供的程式碼,並將其貼上到您在`supabase`資料夾中建立的相應文件中。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d99g065wf471fag7rbjs.png) 接下來,在專案根目錄中建立一個名為`middleware.ts`的文件,並在`/[root]/src/utils/supabase`資料夾中建立另一個同名文件。 之後,導航到此[supabase 文件連結](https://supabase.com/docs/guides/auth/server-side/nextjs#:~:text=4-,Hook%20up%20middleware,-Create%20a%20middleware),複製此處提供的程式碼,並將其貼上到相應的`middleware.ts`文件中。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qo21y007yjpw6w50xb9l.png) 接下來,前往`/[root]/src/app/login`資料夾並建立一個名為`actions.ts`的檔案。之後,導航到此[supabase 文件連結](https://supabase.com/docs/guides/auth/server-side/nextjs#:~:text=5-,Create%20a%20login%20page,-Create%20a%20login),複製此處提供的程式碼,並將其貼上到`actions.ts` 。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1ql5mf0dhqyyli9dipm.png) 之後,更改電子郵件範本以支援身份驗證流程。為此,請前往 Supabase 儀表板中的[驗證範本](https://supabase.com/dashboard/project/_/auth/templates)頁面。 在`Confirm signup`模板中,將`{{ .ConfirmationURL }}`更改為`{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=signup`如下所示,然後按一下儲存按鈕。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9n8n4wdycoqnx3l41rn.png) 之後,建立路由處理程序以使用電子郵件進行身份驗證確認**。**為此\*\*,請前往\*\* `/[root]/src/app/`並建立一個名為`auth`的資料夾。然後在`auth`資料夾中建立一個名為`confirm`資料夾。 在`confirm`資料夾中,建立一個名為`route.ts`檔案並導航到此[supabase文件連結](https://supabase.com/docs/guides/auth/server-side/nextjs#:~:text=Create%20a%20route%20handler%20for%20Auth%20confirmation),複製那裡提供的程式碼,並將其貼到`route.ts`檔案中。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mws1datksq4dml3a8z8n.png) 之後,請前往`/[root]/src/app/login/page.tsx`檔案並使用下面的程式碼片段匯入 Supabase `signup`和`login`功能。 ``` import { login, signup } from "./actions"; ``` 在註冊/登入表單中,按一下登入和註冊按鈕時,使用 formAction 呼叫 Supabase `signup`和`login`函數,如下所示。 ``` <button className="bg-blue-500 text-white font-bold py-2 px-4 rounded" formAction={login}> Log in </button> <button className="bg-blue-500 text-white font-bold py-2 px-4 rounded" formAction={signup}> Sign up </button> ``` 之後,執行開發伺服器並導航至[http://localhost:3000/login](http://localhost:3000/createpost) 。如下所示新增電子郵件和密碼,然後按一下「註冊」按鈕。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/37ee0ii966uhhpi8lqz8.png) 然後轉到您用於註冊的電子郵件的收件匣,然後按一下確認您的電子郵件按鈕,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ekukm36uhh833uuhg1k3.png) 之後,請前往 Supabase 儀表板中的[「身份驗證用戶」](https://supabase.com/dashboard/project/_/auth/users)頁面,您應該會看到新建立的用戶,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmv02jptpsn9k06ytkri.png) 接下來,設定註銷功能。為此,請前往`/[root]/src/app`並建立一個名為`logout`的資料夾。然後建立一個名為`route.ts`的檔案並將以下程式碼加入該檔案。 ``` // Server-side code "use server"; // Importing Next.js functions import { revalidatePath } from "next/cache"; import { redirect } from "next/navigation"; // Importing Supabase client creation function from utils import { createClient } from "@/utils/supabase/server"; // Exporting the logout function export async function logout() { // Creating a Supabase client instance const supabase = createClient(); // Signing out of Supabase auth const { error } = await supabase.auth.signOut(); // If there's an error, redirect to the error page if (error) { redirect("/error"); } // Revalidate the "/" path for the "layout" cache revalidatePath("/", "layout"); // Redirect to the homepage redirect("/"); } ``` 之後,請前往`/[root]/src/app/components/Header.tsx`檔案並使用下面的程式碼片段匯入 Supabase 登出功能。 ``` import { logout } from "../logout/actions"; ``` 然後在action參數中加入註銷功能,如下所示。 ``` <form action={logout}> <button className="flex items-center font-medium text-gray-500 border-2 border-indigo-600 text-center p-2 rounded-md hover:text-blue-600 sm:border-s sm:my-6 " type="submit"> Logout </button> </form> ``` 如果按一下「登出」按鈕,已登入的使用者將被登出。 ### **設定部落格的使用者角色和權限** 在這裡,我將引導您完成設定使用者角色和權限的過程,以控制不同使用者可以在部落格上執行的操作。 首先,前往`/[root]/src/app/components/Header.tsx`檔案並導入 Supabase createClient 函數。 ``` import { createClient } from "@/utils/supabase/client"; ``` 然後導入`useState`和`useEffect`掛鉤,並使用下面的程式碼片段定義一個名為 user 的類型。 ``` import { useEffect, useState } from "react"; type User = {}; ``` 在 Header 功能元件內,新增以下程式碼,程式碼使用`useState`掛鉤來儲存`user`和`admin`資料,並使用`useEffect`掛鉤在元件安裝時從 Supabase auth 取得使用者資料。 `getUser`函數檢查錯誤並相應地設定使用者和管理員狀態。 ``` // State variables for user and admin const [user, setUser] = useState<User | null>(null); const [admin, setAdmin] = useState<User | null>(null); // useEffect hook to fetch user data on mount useEffect(() => { // Define an async function to get the user async function getUser() { // Create a Supabase client instance const supabase = createClient(); // Get the user data from Supabase auth const { data, error } = await supabase.auth.getUser(); // If there's an error or no user data, log a message if (error || !data?.user) { console.log("No User"); } // If user data is available, set the user state else { setUser(data.user); } // Define the email of the signed-up user const userEmail = "email of signed-up user"; // Check if the user is an admin (email matches) if (!data?.user || data.user?.email !== userEmail) { console.log("No Admin"); } // If the user is an admin, set the admin state else { setAdmin(data.user); } } // Call the getUser function getUser(); }, []); // Dependency array is empty, so the effect runs only once on mount ``` 之後,更新導覽列程式碼,如下所示。更新後的程式碼會根據是否有登入使用者或登入使用者是管理員來控制將呈現哪些按鈕。 ``` <div id="navbar-collapse-with-animation" className=""> {/* Navbar content container */} <div className="flex flex-col gap-y-4 gap-x-0 mt-5 sm:flex-row sm:items-center sm:justify-end sm:gap-y-0 sm:gap-x-7 sm:mt-0 sm:ps-7"> {/* Conditional rendering for admin link */} {admin ? ( // If admin is true, show the "Create Post" link <Link className="flex items-center font-medium text-gray-500 border-2 border-indigo-600 text-center p-2 rounded-md hover:text-blue-600 sm:border-s sm:my-6 " href="/createpost"> Create Post </Link> ) : ( // If admin is false, render an empty div <div></div> )} {/* Conditional rendering for user link/logout button */} {user ? ( // If user is true, show the logout button <form action={logout}> <button className="flex items-center font-medium text-gray-500 border-2 border-indigo-600 text-center p-2 rounded-md hover:text-blue-600 sm:border-s sm:my-6 " type="submit"> Logout </button> </form> ) : ( // If user is false, show the "Login" link <Link className="flex items-center font-medium text-gray-500 border-2 border-indigo-600 text-center p-2 rounded-md hover:text-blue-600 sm:border-s sm:my-6 " href="/login"> Login </Link> )} </div> </div> ``` 如果導航到[http://localhost:3000,](http://localhost:3000/)您應該會看到僅呈現「建立貼文」和「登出」按鈕,因為使用者已登入並設定為管理員。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdhh0x1ln8xl9y1tq7ua.png) 之後,請前往`/[root]/src/app/createpost/page.tsx`檔案並匯入 Supabase createClient 函數。 ``` import { createClient } from "@/utils/supabase/client"; ``` 在 WriteArticle 功能元件中,新增以下程式碼,使用 Supabase createClient 函數取得登入用戶,並驗證用戶的電子郵件是否與設定為管理員的用戶的電子郵件相同。 ``` // Define the email of the user you want to make admin const userEmail = "email of admin user"; // Create a Supabase client instance const supabase = createClient(); // Get the user data from Supabase auth const { data, error } = await supabase.auth.getUser(); // Check for errors or if the user data doesn't match the expected email if (error || !data?.user || data?.user.email !== userEmail) { // If any of the conditions are true, redirect to the homepage redirect("/"); } ``` 現在只有設定為admin的使用者才能存取http://localhost:3000/createpost頁面,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4vrnvib7ikzsgt8webrz.png) ### **使用 Supabase 功能設定插入和取得發布資料** 在這裡,我將引導您完成使用 Supabase 資料庫向部落格設定插入和取得資料功能的過程。 首先,請前往 Supabase 儀表板中的[SQL 編輯器](https://supabase.com/dashboard/project/_/sql/new)頁面。然後將下列 SQL 程式碼新增至編輯器中,然後按一下 CTRL + Enter 鍵建立一個名為articles 的表。 articles 表包含 id、title、slug、content 和created\_at 欄位。 ``` create table if not exists articles ( id bigint primary key generated always as identity, title text, slug text, content text, created_at timestamp ); ``` 建立表格後,您應該會收到一條成功訊息,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dd3xgg0o8ygztkab3cir.png) 之後,請前往`/[root]/src/utils/supabase`資料夾並建立一個名為`AddArticle.ts`的檔案。然後將以下程式碼新增至該檔案中,將部落格文章資料插入 Supabase 資料庫。 ``` // Server-side code "use server"; // Importing Supabase auth helpers and Next.js functions import { createServerComponentClient } from "@supabase/auth-helpers-nextjs"; import { cookies } from "next/headers"; import { redirect } from "next/navigation"; // Exporting the addArticle function export async function addArticle(formData: any) { // Extracting form data const title = formData.get("title"); const content = formData.get("content"); const slug = formData .get("title") .split(" ") .join("-") .toLowerCase() .replace(/[^a-zA-Z0-9-]/g, ""); // Generating a slug from the title const created_at = formData.get(new Date().toDateString()); // Getting the current date // Creating a cookie store const cookieStore = cookies(); // Creating a Supabase client instance with cookie store const supabase = createServerComponentClient({ cookies: () => cookieStore }); // Inserting data into the "articles" table const { data, error } = await supabase.from("articles").insert([ { title, content, slug, created_at, }, ]); // Handling errors if (error) { console.error("Error inserting data", error); return; } // Redirecting to the homepage redirect("/"); // Returning a success message return { message: "Success" }; } ``` 接下來,前往`/[root]/src/app/components/Post.tsx`檔案並導入 addArticle 函數。 ``` import { addArticle } from "@/utils/supabase/AddArticle"; ``` 然後加入`addArticle`函數作為表單動作參數,如下所示。 ``` <form action={addArticle} className="w-full h-full gap-10 flex flex-col items-center p-10"> </form> ``` 之後,導覽至 http://localhost:3000/createpost 並向右側的聊天機器人提供類似「研究有關 JavaScript 框架的部落格文章主題」的提示。 聊天機器人將開始研究該主題,然後產生部落格標題和大綱,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3i5ndwct44094iczrpo.png) 當您開始在 CopilotKitTextarea 上書寫時,您應該會看到內容自動建議,如下所示。 {% 嵌入 https://youtu.be/2oMNV1acKIs %} 如果內容符合您的喜好,請將其複製並貼上到 Quill 富文本編輯器。然後開始編輯它,如下所示。 {% 嵌入 https://youtu.be/-r3woCeq4vs %} 然後點擊底部的發布按鈕即可發布文章。前往 Supabase 上專案的儀表板並導航至「表格編輯器」部分。點擊文章表,您應該會看到您的文章資料已插入到 Supabase 資料庫中,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v4umd2qijpdt9z3evfkj.png) 接下來,前往`/[root]/src/app/components/Posts.tsx`檔案並導入 createClient 函數。 ``` import { createClient } from "@/utils/supabase/client"; ``` 在 Posts 功能元件內,加入以下程式碼,該程式碼使用 useState 掛鉤來儲存文章資料,並使用 useEffect 掛鉤在元件安裝時從 Supabase 取得文章。 fetchArticles 函數建立一個 Supabase 用戶端實例,取得文章,並在資料可用時更新狀態。 ``` // State variable for articles const [articles, setArticles] = useState<any[]>([]); // useEffect hook to fetch articles on mount useEffect(() => { // Define an async function to fetch articles const fetchArticles = async () => { // Create a Supabase client instance const supabase = createClient(); // Fetch articles from the "articles" table const { data, error } = await supabase.from("articles").select("*"); // If data is available, update the articles state if (data) { setArticles(data); } }; // Call the fetchArticles function fetchArticles(); }, []); // Dependency array is empty, so the effect runs only once on mount ``` 之後,如下所示更新元素程式碼,以在部落格主頁上呈現已發佈的文章。 ``` // Return a div element with a max width, full height, padding, and horizontal margin return ( <div className="max-w-[85rem] h-full px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto"> // Create a grid container with dynamic number of columns based on screen size <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-6"> // Map over the articles array and render a Link component for each item {articles?.map((post) => ( <Link // Assign a unique key prop to each Link component key={post.id} // Apply styles for the Link component className="group flex flex-col h-full bg-gray-800 border border-gray-200 hover:border-transparent hover:shadow-lg transition-all duration-300 rounded-xl p-5 " // Set the href prop to the post slug href={`/${post.slug}`}> // Create a container for the image <div className="aspect-w-16 aspect-h-11"> // Render an Image component with a dynamic src based on the post title <Image className="object-cover h-48 w-96 rounded-xl" src={`(link unavailable){encodeURIComponent( post.title )}`} // Set the width and height props for the Image component width={500} height={500} // Set the alt prop for accessibility alt="Image Description" /> </div> // Create a container for the post title <div className="my-6"> // Render an h3 element with the post title <h3 className="text-xl font-semibold text-white "> {post.title} </h3> </div> </Link> ))} </div> </div> ); ``` 然後導航到<http://localhost:3000> ,您應該會看到您發布的文章,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bpwvh0b3cm7dfrgwixtv.png) 接下來,前往`/[root]/src/app/[slug]/page.tsx`檔案並匯入 createClient 函數。 ``` import { createClient } from "@/utils/supabase/client"; ``` 在導入下方,定義一個名為「getArticleContent」的非同步函數,該函數根據 slug 參數從 supabase 資料庫檢索文章資料,如下所示。 ``` // Define an asynchronous function to retrieve article content async function getArticleContent(params: any) { // Extract the slug parameter from the input params object const { slug } = params; // Create a Supabase client instance const supabase = createClient(); // Query the "articles" table in Supabase // Select all columns (*) // Filter by the slug column matching the input slug // Retrieve a single record (not an array) const { data, error } = await supabase .from("articles") .select("*") .eq("slug", slug) .single(); // Return the retrieved article data return data; } ``` 之後,如下所示更新功能元件Post,以渲染文章內容。 ``` export default async function Post({ params }: { params: any }) { // Fetch the post content using the getArticleContent function const post = await getArticleContent(params); // Return the post component return ( // Fragment component to wrap multiple elements <> // Header component <Header /> // Main container with max width and height <main className="p-3 flex flex-col max-w-6xl mx-auto min-h-screen"> // Post title <h1 className="text-3xl text-white mt-10 p-3 text-center font-serif max-w-2xl mx-auto lg:text-4xl"> {post && post.title} // Display post title if available </h1> // Post metadata (author, date, etc.) <div className="flex justify-between text-white p-3 border-b border-slate-500 mx-auto w-full max-w-2xl text-xs"> <span></span> // Estimated reading time <span className="italic"> {post && (post.content.length / 1000).toFixed(0)} mins read </span> </div> // Post content <div className="p-3 max-w-2xl text-white mx-auto w-full post-content border-b border-slate-500 mb-2" // Use dangerouslySetInnerHTML to render HTML content dangerouslySetInnerHTML={{ __html: post && post.content }}></div> // Comment component <Comment /> </main> </> ); } ``` 導覽至<http://localhost:3000>並點擊部落格主頁上顯示的文章。然後您應該被重定向到文章的內容,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/byfdvwr7anceq09gto1g.png) ### **使用 Supabase 功能設定插入和取得評論資料** 在這裡,我將引導您完成使用 Supabase 資料庫為部落格內容評論設定插入和獲取資料功能的過程。 首先,請前往 Supabase 儀表板中的[SQL 編輯器](https://supabase.com/dashboard/project/_/sql/new)頁面。然後將以下 SQL 程式碼新增至編輯器中,然後按一下 CTRL + Enter 鍵建立一個名為 comments 的表。評論表有 id、content 和 postId 欄位。 ``` create table if not exists comments ( id bigint primary key generated always as identity, postId text, content text, ); ``` 建立表格後,您應該會收到一條成功訊息,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5h05jkk1g33ewtupsb5a.png) 之後,請前往`/[root]/src/utils/supabase`資料夾並建立一個名為`AddComment.ts`的檔案。然後將以下程式碼新增至該檔案中,將部落格文章評論資料插入 Supabase 資料庫。 ``` // Importing necessary functions and modules for server-side operations "use server"; import { createServerComponentClient } from "@supabase/auth-helpers-nextjs"; import { cookies } from "next/headers"; import { redirect } from "next/navigation"; // Define an asynchronous function named 'addComment' that takes form data as input export async function addComment(formData: any) { // Extract postId and content from the provided form data const postId = formData.get("postId"); const content = formData.get("content"); // Retrieve cookies from the HTTP headers const cookieStore = cookies(); // Create a Supabase client configured with the provided cookies const supabase = createServerComponentClient({ cookies: () => cookieStore }); // Insert the article data into the 'comments' table on Supabase const { data, error } = await supabase.from("comments").insert([ { postId, content, }, ]); // Check for errors during the insertion process if (error) { console.error("Error inserting data", error); return; } // Redirect the user to the home page after successfully adding the article redirect("/"); // Return a success message return { message: "Success" }; } ``` 接下來,到`/[root]/src/app/components/Comment.tsx`文件,導入 addArticle createClient 函數。 ``` import { addComment } from "@/utils/supabase/AddComment"; import { createClient } from "@/utils/supabase/client"; ``` 然後將postId作為prop參數加入Comment功能元件中。 ``` export default function Comment({ postId }: { postId: any }) {} ``` 在函數內部,新增以下程式碼,程式碼使用`useEffect`掛鉤在元件安裝或`postId`更改時從 Supabase 取得評論和文章內容。 `fetchComments`函數取得所有評論,而`fetchArticleContent`函數則取得具有目前`postId`的文章內容。 ``` useEffect(() => { // Define an async function to fetch comments const fetchComments = async () => { // Create a Supabase client instance const supabase = createClient(); // Fetch comments from the "comments" table const { data, error } = await supabase.from("comments").select("*"); // If data is available, update the comments state if (data) { setComments(data); } }; // Define an async function to fetch article content const fetchArticleContent = async () => { // Create a Supabase client instance const supabase = createClient(); // Fetch article content from the "articles" table // Filter by the current postId const { data, error } = await supabase .from("articles") .select("*") .eq("id", postId) .single(); // If the fetched article ID matches the current postId if (data?.id == postId) { // Update the article content state setArticleContent(data.content); } }; // Call the fetch functions fetchArticleContent(); fetchComments(); }, [postId]); // Dependency array includes postId, so the effect runs when postId changes ``` 然後新增`addComment`函數作為表單操作參數,如下所示。 ``` <form action={addComment} className="border border-teal-500 rounded-md p-3 mb-4"> <textarea id="content" name="content" placeholder="Add a comment..." rows={3} onChange={(e) => setComment(e.target.value)} value={comment} className="hidden" /> <CopilotTextarea className="p-4 w-full rounded-lg mb-2 border text-sm border-gray-600 bg-gray-700 text-white placeholder-gray-400 focus:border-cyan-500 focus:ring-cyan-500 resize-none" ref={copilotTextareaRef} placeholder="Start typing for content autosuggestion." onChange={(event) => setComment(event.target.value)} rows={5} autosuggestionsConfig={{ textareaPurpose: articleContent, chatApiConfigs: { suggestionsApiConfig: { forwardedParams: { max_tokens: 5, stop: ["\n", ".", ","], }, }, insertionApiConfig: {}, }, debounceTime: 250, }} /> <input type="text" id="postId" name="postId" value={postId} className="hidden" /> <div className="flex justify-between items-center mt-5"> <button type="submit" className="bg-blue-500 text-white font-bold py-2 px-4 rounded"> Submit </button> </div> </form> ``` 在表單元素下方,新增以下用於呈現貼文評論的程式碼。 ``` {comments?.map( (postComment: any) => postComment.postId == postId && ( <div key={postComment.id} className="flex p-4 border-b dark:border-gray-600 text-sm"> <div className="flex-shrink-0 mr-3"> <Image className="w-10 h-10 rounded-full bg-gray-200" src={`https://source.unsplash.com/featured/?${encodeURIComponent( "Silhouette" )}`} width={500} height={500} alt="Profile Picture" /> </div> <div className="flex-1"> <div className="flex items-center mb-1"> <span className="font-bold text-white mr-1 text-xs truncate"> Anonymous </span> </div> <p className="text-gray-500 pb-2">{postComment.content}</p> </div> </div> ) )} ``` 接下來,前往`/[root]/src/app/[slug]/page.tsx`檔案並將 postId 作為 prop 新增至 Comment 元件。 ``` <Comment postId={post && [post.id](http://post.id/)} /> ``` 前往已發佈的文章內容頁面並開始在文字區域中輸入評論。您應該在鍵入時獲得內容自動建議。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2m6br70wf3mhxzovgfet.png) 然後點擊提交按鈕以加入您的評論。前往 Supabase 上專案的儀表板並導航到表格編輯器部分。點擊評論表,您應該會看到您的評論資料已插入到 Supabase 資料庫中,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3j9c6cy82cw9fcao2pe9.png) 返回您發表評論的文章內容頁面,您應該會看到您的評論,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n98o9kxqnyzm90tzvw40.png) 恭喜!您已完成本教學的專案。 結論 -- [CopilotKit](https://copilotkit.ai/)是一款令人難以置信的工具,可讓您在幾分鐘內將 AI Copilot 加入到您的產品中。無論您是對人工智慧聊天機器人和助理感興趣,還是對複雜任務的自動化感興趣,CopilotKit 都能讓您輕鬆實現。 如果您需要建立 AI 產品或將 AI 工具整合到您的軟體應用程式中,您應該考慮 CopilotKit。 您可以在 GitHub 上找到本教學的源程式碼:https://github.com/TheGreatBonnie/aiblogapp --- 原文出處:https://dev.to/copilotkit/im-building-an-ai-powered-blog-nextjs-langchain-supabase-5145

C++ 能做什麼 Rust 不能做的事情?

我想先說這是我的兩種主要語言。我對兩者都抱有充分的尊重,並計劃無論如何都專注於兩者。我知道這是一個具有挑戰性的問題,而且我是兩種語言的初學者。 我不是說那些你應該使用[JavaScript](https://en.wikipedia.org/wiki/JavaScript)或[C#](https://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29)或其他東西的東西 - 儘管[Rust](https://www.rust-lang.org/)實際上在[這些方面也還](https://www.rust-lang.org/what/networking)[不錯](https://www.rust-lang.org/what/embedded),並且[一直在改進](https://www.rust-lang.org/what/wasm)。我甚至沒有談論[C](https://en.wikipedia.org/wiki/C_%28programming_language%29) ,儘管我認為最終我們也可能能夠進行這樣的對話。我特別斷言 Rust 可以與[C++](https://isocpp.org/)正面競爭。 也就是說,隨著我對 C++ 的了解越來越多,我也越來越了解我對 C++ 和一般程式設計的了解還有多少。從我的角度來看,[受 Hindley-Milner](https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system)啟發的類型系統與 Rust 所針對的資料操作類型的記憶體粒度控製完美匹配。我非常願意讓別人知道我為什麼錯了。 我最近發布了關於我實現的 Rust 樹的文章,其中包含了 Rust 限制性的解決方法,但我提到的第一個替代方案是[`unsafe`](https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html) 。當然,總是需要直接操作記憶體。許多標準庫工具本質上都是用`unsafe` Rust 實現的,編寫的安全 API 已經過才華橫溢的 Rust 團隊和整個 OSS 社群的審查。有許多`lib*-sys`包本質上是相同的東西。任何使用 C 的 FFI 都會包含`unsafe`原始指標。 這就是任何工具,無論是開源軟體還是專有工具,都被認為是“安全的”,對吧?聰明人都看出來了嗎? 我對[模板](https://en.cppreference.com/w/cpp/language/templates)的討論充滿敬意,但對我來說,它們是一個更笨重的[Rust 特徵](https://doc.rust-lang.org/book/ch10-02-traits.html)。您可以使用 Rust 特徵 + 巨集不能做的範本做什麼?說到這裡, [OCaml](https://ocaml.org/)中的[Functor](https://v1.realworldocaml.org/v1/en/html/functors.html) ? [Jane Street](https://www.janestreet.com/technology/)為此工具提供了堅實的案例,甚至超越了 Haskell 或 C++。 OCaml 本身就是一種令人驚嘆的[UNIX/Linux 程式](https://ocaml.github.io/ocamlunix/)語言。 C++ 已被鞏固,但新程式碼一直在編寫。我是否沒有理解 C++ 的強大之處? 拋開所有迷因,為什麼不用 Rust 編寫所有全新的適用領域軟體,並在需要的地方編寫 Rust 介面呢? 我知道C++預設施加的限制較少,允許人們超越人們更了解的機器。我不知道為什麼這會阻礙一種新的*基礎*語言的出現,這種語言是對我們現有語言的改進,以及為什麼 Rust 不是。 *照片由 Edvin Johansson 在 Unsplash 上拍攝* --- 原文出處:https://dev.to/deciduously/what-does-c-do-that-rust-doesn-t-4h2g

20 多個 DOM 專案:您的前端突破!

透過 DOM 專案提升您的前端技能:新手開發人員的遊樂場 ---------------------------- 透過[DOM 專案改變您的學習體驗!](https://github.com/jisan-mia/dom-projects/)深入研究 20 多個使用 HTML、CSS 和 JavaScript 建構的實用專案。非常適合新手和經驗豐富的開發人員,您會發現一些可以挑戰和激勵您的東西。 以下是 DOM 專案的與眾不同之處: - **邊做邊學:** DOM 專案直接深入前端開發的實際面向。您將透過建立實際專案來學習,鞏固對核心概念的理解。 - **漸進式學習:** DOM 專案提供了按難度分類的精選專案。從適合初學者的專案開始,例如“計數器”或“滾動動畫”,並逐漸進展到更高級的專案,例如“高級待辦事項”或“REST 用戶端”。 - **[開源與協作:](https://github.com/jisan-mia/dom-projects/)** DOM 專案的美妙之處在於其開源特性。您不僅可以從現有專案中學習,還可以將您的創作貢獻給該平台,從而培養一個充滿活力的學習者和開發者社群。 - **輕鬆設定:**設定 DOM 專案輕而易舉。不涉及複雜的安裝過程。只需分叉存儲庫,將其克隆到本地計算機,然後在瀏覽器中打開 index.html 文件。您已準備好開始您的程式設計冒險! ### 深入研究專案: [DOM Projects](https://www.jisan.io/dom-projects/)擁有**20 多個專案**,每個專案都針對特定技能和概念精心設計。以下是一些激發您興趣的詳細範例: ### [計數器](https://www.jisan.io/dom-projects/projects/counter/) ![櫃檯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egsodt4dyfekiwp8ln4q.png) **描述**:一個簡單的計數器專案,允許使用者增加和減少螢幕上顯示的數字。它還包括一個用於將計數器重置為零的按鈕。 **學習理念:** - DOM 操作:了解如何使用 JavaScript 存取和修改 HTML 元素。 - 事件處理:了解如何擷取使用者互動(在本例中為點擊)並使用 JavaScript 觸發特定操作。 - 基本 JavaScript 函數:探索如何寫函數來執行遞增、遞減和重置計數器值等任務。 ### [爸爸笑話](https://www.jisan.io/dom-projects/projects/dad-jokes/) ![爸爸笑話](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z09wwb70arrb5ccjhl87.png) **描述**:該專案使用 JavaScript 中的非同步技術從外部 API 獲取隨機爸爸笑話。一旦檢索到,笑話就會顯示在網頁上供您娛樂。 **學習理念:** - 非同步程式設計:了解如何處理需要時間才能完成的操作(例如從 API 取得資料)而不阻塞 JavaScript 中的主執行緒。 - Fetch API:了解如何使用內建瀏覽器功能向 API 發出 HTTP 請求並擷取資料。 - 使用 API:探索如何與外部 API 互動以存取這些服務提供的資料或功能。 ### [表單驗證](https://www.jisan.io/dom-projects/projects/form-validation/) ![表單驗證](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7b7mbyvuwxdwkzv2eidr.png) **描述**:此專案示範了使用 JavaScript 進行客戶端表單驗證。它在提交之前驗證表單中的使用者輸入。此外,驗證成功後,它會顯示成功訊息並允許使用者以唯讀格式預覽提交的資料。 **學習理念:** - 表單驗證:了解如何使用 JavaScript 在提交之前驗證表單中的使用者輸入。這有助於確保資料完整性並防止處理無效資料。 - DOM 操作:了解如何根據驗證結果存取和修改表單元素(例如顯示錯誤訊息或停用輸入欄位)。 - 事件處理:使用 JavaScript 擷取表單提交事件並觸發驗證邏輯。 ### [隨機用戶](https://www.jisan.io/dom-projects/projects/random-user/) ![隨機用戶](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jlfog2j2okpgtx01eyso.png) **描述**:此專案利用 API 產生隨機使用者資訊。它會取得姓名、電子郵件、頭像等資料,並將其顯示在網頁上,模擬隨機使用者設定檔。 **學習理念:** - 非同步程式設計:與專案 2 (DadJokes) 類似,此專案強化了 JavaScript 中的非同步操作。 - Fetch API:繼續練習使用工具向 API 發出 HTTP 請求並檢索資料。 - 使用 API:進一步探索與外部 API 互動以存取特定功能或資料。 ### [摩斯電碼翻譯器](https://www.jisan.io/dom-projects/projects/morse-translator/) ![摩斯電碼翻譯器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il6si3v62r76udcis9lq.png) **描述**:此專案允許使用者在摩斯電碼和文字之間進行翻譯。使用者可以鍵入文字並查看對應的摩斯電碼,也可以輸入摩斯電碼並查看翻譯後的文字。 **學習理念**: - 字串操作:了解如何在 JavaScript 中使用字串,包括拆分、連接和字元操作的函數,這對於摩斯電碼翻譯至關重要。 - 條件語句:學習如何在 JavaScript 中使用條件語句(if/else)來實現基於使用者輸入(文字或摩斯電碼)的翻譯邏輯。 ### [基本計算機](https://www.jisan.io/dom-projects/projects/basic-calculator/) ![基本計算機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/riz357iso4aux1an08sx.png) **描述**:該專案使用 JavaScript 建立一個最基本的計算器應用程式。它允許使用者執行基本算術運算,例如加法、減法、乘法和除法。使用者可以輸入數字並使用螢幕上的按鈕選擇所需的操作。計算器顯示計算結果。 **學習理念**: - 事件處理:與先前的專案類似,此專案練習捕捉使用者對計算器按鈕的點擊並觸發操作(更新計算和結果)。 - DOM 操作:示範如何使用 JavaScript 更新計算器介面中顯示的數字和結果。 - JavaScript 中的基本數學運算:探索使用 JavaScript 內建的數學運算子和函數來執行加法、減法、乘法和除法等計算。 ### [普通計算機](https://www.jisan.io/dom-projects/projects/normal-calculator/) ![普通計算機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qpgq9hnt59vlcaz8r0zx.png) **描述**:該專案建立在基本計算器的基礎上,為標準數學計算提供更全面的使用者體驗。它適合熟悉基本計算器功能的使用者。 **學習理念:** - 基於現有專案:示範對基本計算器概念的擴展,以建立更用戶友好且功能豐富的計算器。 - 增強的使用者互動:引入改進使用者與計算器互動的技術,例如處理小數輸入或合併記憶體功能。 ### [科學計算機](https://www.jisan.io/dom-projects/projects/scientific-calculator/) ![科學計算機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4taeew6vv1ublamhbyod.png) **描述**:此專案透過提供三角函數(正弦、餘弦、正切)、對數和指數等科學函數,將計算器功能提升到一個新的水平。它迎合需要高級數學計算的用戶。 **學習理念:** - 建立複雜的應用程式:示範如何建立具有先進科學功能的更複雜的應用程式。 - JavaScript 中的數學函數:介紹使用 JavaScript 內建的數學函數進行高階計算 ### [簡單的一切應用程式](https://www.jisan.io/dom-projects/projects/js-todo/) ![簡單的一切應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/55d842o20i8j528q2maz.png) **描述**:該專案是一個基本的待辦事項清單應用程式。使用者可以新增任務、將其標記為已完成以及從清單中刪除它們。它演示了管理和追蹤任務。 \*\*學習理念: - DOM 操作:此專案強化了使用 JavaScript 動態新增、刪除和修改 HTML 中的清單專案的實務。 - 陣列:它演示了在 JavaScript 中使用陣列儲存和管理任務資料。 - 使用者介面更新:探索如何根據使用者互動更新待辦事項清單的視覺表示(新增、完成、刪除任務)。 ### [個人資料表和卡片](https://www.jisan.io/dom-projects/projects/profile-form/) ![個人資料表和卡片](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13yidfqfe156556rky87.png) **描述**:此專案允許使用者使用表單建立動態個人資料卡。用戶可以輸入他們的訊息,提交後,將建立一個新的個人資料卡並顯示在頁面上。它還包括刪除現有個人資料卡的功能。 **學習理念:** - 表單處理:該專案基於表單驗證(專案 3)的概念,重點關注捕獲表單資料並將其用於進一步的操作。 - DOM 建立和操作:它超越了基本的 DOM 操作,根據使用者輸入動態建立新的 HTML 元素(個人資料卡)。 - 事件處理:繼續練習捕獲使用者與表單和刪除按鈕的互動並觸發適當的操作。 ### [PC元件過濾](https://www.jisan.io/dom-projects/projects/pc-component-filter/) ![PC元件過濾](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txtgpqu4t0zbi2mcovbo.png) **描述**:該專案允許使用者根據他們的選擇過濾電腦部件。使用者可以從各種選項中進行選擇,例如 CPU 品牌、RAM 大小、顯示卡類型等,顯示的元件清單將動態更新以反映所選的篩選器。 **學習理念:** - DOM 操作:與先前的專案類似,此專案實踐根據使用者選擇動態更新顯示的元件清單。 - 陣列和資料過濾:探索使用陣列來存儲計算機部件資料,並在 JavaScript 中實現過濾邏輯以匹配用戶選擇。 - 使用者介面更新:重點是根據應用的過濾器更新元件列表的視覺表示。 ### [天氣應用程式](https://www.jisan.io/dom-projects/projects/weather-app/) ![天氣應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l4tjhdmz5xlpxia218lp.png) **描述**:該專案是一個天氣應用程式,允許用戶透過城市名稱搜尋當前的天氣資訊。它利用外部天氣 API 來獲取資料並在螢幕上顯示溫度、濕度和天氣狀況等詳細資訊。 **學習理念:** - 非同步程式設計:與 DadJokes(專案 2)等專案類似,此專案強化了處理非同步操作以獲取天氣資料的概念。 - Fetch API:繼續練習使用工具向 API 發出 HTTP 請求並檢索天氣資料。 - 使用 API:進一步探索與外部 API 互動以存取天氣資訊。 ### [感言滑塊](https://www.jisan.io/dom-projects/projects/testimonial-slider/) ![感言滑塊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sroguxb8914j1dv65fpw.png) **描述**:此專案建立一個具有滑桿功能的推薦部分。它顯示使用者的引言或推薦,使用者可以使用滑桿控制來瀏覽它們。 **學習理念:** - DOM 操作:示範如何根據滑桿位置操作建議元素的可見性。 - 事件處理:捕捉使用者與滑桿控制項的互動並觸發滑動動畫。 ### [滾動動畫](https://www.jisan.io/dom-projects/projects/animation-on-scroll/) ![滾動動畫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3o5psut9f3d5cmns3ld3.png) **描述**:此專案包含向下捲動頁面時觸發的動畫。當使用者滾動時,網頁上的不同元素會變成動畫,增加視覺趣味和互動性。 ### 學習理念: - CSS 動畫:探索使用 CSS 動畫來建立根據滾動位置啟動的視覺效果。 - 用於捲動事件的 JavaScript:介紹使用 JavaScript 來偵測滾動事件並相應地觸發動畫。 ### [搜尋字段顯示](https://www.jisan.io/dom-projects/projects/search-field-reveal/) ![搜尋字段顯示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awycht9282x9n35gyy5j.png) **描述**:此專案利用動畫來增強使用者體驗。它會建立一個搜尋字段,在使用者互動(例如,點擊按鈕)時透過動畫顯示自身。 **學習理念:** - CSS 動畫:介紹使用 CSS 動畫為搜尋欄位顯示建立動態視覺效果。 - 事件處理:涵蓋捕獲使用者互動(例如按鈕單擊)並使用 JavaScript 觸發動畫。 ### [問題清單及進展](https://www.jisan.io/dom-projects/projects/question-list-progress/) ![問題清單及進展](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1p6unngf1az0084i3tnb.png) **描述**:此專案示範了 JavaScript 中常見的 DOM 操作技術。它具有問題清單和進度指示器,進度指示器會隨著使用者回答問題而更新。 **學習理念:** - DOM 操作:此專案強調根據使用者與問題的互動來操作進度指示器等元素。 - 事件處理:捕捉使用者與問題元素的互動並觸發更新進度指示器等操作。 ### [莫代爾](https://www.jisan.io/dom-projects/projects/modal/) ![莫代爾](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0b06e0fi84z7wqsjev4.png) **描述**:該專案會建立一個模式窗口,它是一個覆蓋頁面主要內容的彈出元素。它通常用於登入表單、註冊提示或警報訊息等內容。 **學習理念:** - DOM 操作:重點是根據使用者互動顯示和隱藏模式視窗元素。 - 事件處理:捕捉觸發元素和模式的關閉按鈕上的點擊以控制其可見性。 ### [高級待辦事項](https://www.jisan.io/dom-projects/projects/advanced-todo/) ![高級待辦事項](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8baq9a3n6qdwlookd338.png) **描述**:該專案基於簡單的待辦事項應用程式(專案 8)建置,提供過濾、編輯和刪除任務等高級功能。使用者可以對任務進行分類、編輯現有任務以及從清單中刪除不需要的任務。 **學習理念:** - 基於現有專案:與科學計算器(專案 7)類似,該專案演示了對基本概念(待辦事項清單)的擴展以建立更高級的應用程式。 - 使用者介面更新:擴展了更新待辦事項清單的概念,包括過濾、編輯任務內容和刪除任務等功能。 ### [復古計算器](https://www.jisan.io/dom-projects/projects/retro-calculator/) ![復古計算器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/thdpc8rzcppjfhlw8aru.png) **描述**:該專案實現了經典的計算器設計,並支援實體鍵盤輸入。它允許用戶使用類似於傳統計算器的佈局輸入數字並執行計算。 **學習理念:** - 事件處理:與其他專案類似,該專案側重於捕獲用戶交互,但在本例中,它包括處理計算器按鈕上的點擊和鍵盤上的按鍵。 - DOM 操作:根據使用者輸入和計算結果更新計算器顯示。 - 物件導向程式設計:此專案引入了 JavaScript 中物件導向程式設計 (OOP) 的概念,用於建立更模組化且可重複使用的計算器功能。 ### [簡單的測驗應用程式](https://www.jisan.io/dom-projects/projects/simple-quiz-app/) ![簡單的測驗應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/khvz1xnzfvusxb8hvwrh.png) **描述**:該專案建立一個簡單的測驗應用程式,用戶可以在其中回答問題並查看結果。它包括每個問題的計時器,以加入時間壓力元素。 **學習理念:** - DOM 操作:更新測驗介面以顯示問題、處理答案選擇並顯示最終結果 ### [進階測驗應用程式](https://www.jisan.io/dom-projects/projects/advanced-quiz-app/) ![進階測驗應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98kzkz9jyfl6vjkau9z1.png) **描述**:該專案建立在簡單的測驗應用程式的基礎上,提供更多自訂選項。使用者可以在開始測驗之前設定問題數量、選擇主題並定義難度等級。 **學習理念:** - 基於現有專案:與其他專案(科學計算器、高級待辦事項清單)類似,該專案演示了透過附加功能擴展基本概念。 - 使用者輸入驗證:它引入了驗證自訂選項的使用者輸入的概念(例如,確保選擇有效數量的問題)。 - 條件語句:在此專案中發揮更重要的作用,因為 JavaScript 邏輯需要根據使用者定義的參數來調整測驗。 ### 採取下一步: 準備好開始您的前端開發之旅了嗎?以下是如何開始使用 DOM 專案: 1. 造訪 GitHub 上的 DOM 專案儲存庫: <https://github.com/Jisan-mia/dom-projects> 2. 瀏覽專案清單並選擇一個符合您的技能水平和興趣的專案。 3. 請按照設定[說明](https://github.com/Jisan-mia/dom-projects?tab=readme-ov-file#how-to-set-up-dom-projects-for-development)進行操作並在瀏覽器中開啟專案。 4. 深入研究程式碼、實驗並學習! DOM 專案中的每個專案都可以讓您練習編碼技能,並幫助您理解前端開發中的關鍵概念。無論您是剛起步的初學者,還是希望提高技能的經驗豐富的開發人員,DOM 專案都能滿足每個人的需求。 請記住,最好的學習方法是實踐。所以,捲起袖子,選擇一個專案,然後開始編碼吧!快樂學習! --- 原文出處:https://dev.to/jisan/20-dom-projects-your-frontend-breakthrough-1h8a

簡化程式碼:20 多個方便的 JavaScript 函數

JavaScript 是一種函數式程式語言,函數扮演著至關重要的角色。它們允許您封裝可重複使用程式碼並執行特定任務。以下是一些可以讓您的生活更輕鬆的功能的快速範例: ### 常規功能 ``` function sum(a, b) { return a + b; } ``` ### 函數表達式 ``` const sum = function (a, b) { return a + b; }; ``` ### 箭頭功能 ``` const sum = (a, b) => { return a + b; }; // OR const sum = (a, b) => a + b; ``` ### 發電機功能 ``` function* indexGenerator() { let index = 0; while (true) { yield index++; } } const g = indexGenerator(); console.log(g.next().value); // => 0 console.log(g.next().value); // => 1 ``` ### 建立一個從 1 到 n 的數字陣列 ``` const range = (n) => Array.from({ length: n }, (_, i) => i + 1); console.log(range(10)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ``` ### 使用步驟建立一個從 1 到 n 的數字陣列 ``` const range = (n, step = 1) => Array.from({ length: n }, (_, i) => i * step); console.log(range(10, 2)); // [1, 3, 5, 7, 9] ``` ### 建立一個陣列並用一個值填充它 ``` const fill = (len, value) => Array(len).fill(value); console.log(fill(3, 0)); // [0, 0, 0] ``` ### 打亂陣列 ``` const shuffleArray = (arr) => arr.sort(() => 0.5 - Math.random()); console.log(shuffleArray([1, 2, 3, 4])); // [3, 2, 1, 4] ``` ### 從陣列中刪除重複項 ``` const removeDuplicated = (arr) => [...new Set(arr)]; console.log(removeDuplicated([1, 2, 3, 3, 4, 4, 5, 5, 6])); // Result: [ 1, 2, 3, 4, 5, 6 ] const removeDuplicate = (arr) => Object.values(arr.reduce((a, b) => (a[b] ? a : { ...a, [b]: b }), {})); console.log(removeDuplicate([1, 2, 3, 3])); // Result: [ 1, 2, 3, ] ``` ### 產生隨機數 ``` const random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; console.log(random(1, 10)); // Result: 1 ~ 10 ``` ### 找到最大的數字 ``` const findLargest = (arr) => arr.map((subArr) => Math.max(...subArr)); console.log( findLargest([ [4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1], ]) ); // [5, 27, 39, 1001] ``` ### 找出最小的數字 ``` const findSmallest = (arr) => arr.map((subArr) => Math.min(...subArr)); console.log( findSmallest([ [4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1], ]) ); // [1, 18, 32, 857] ``` ### 從陣列中選擇一個隨機元素 ``` const pick = (arr) => arr[Math.floor(Math.random() * arr.length)]; console.log(pick([1, 2, 3, 4])); // 2 ``` ### 將陣列轉換為物件 ``` const toObject = (arr) => ({ ...arr }); console.log(toObject(["a", "b"])); // { 0: 'a', 1: 'b' } ``` ### 找出兩個陣列的交集 ``` const intersection = (arr1, arr2) => { const set = new Set(arr1); return arr2.filter((x) => set.has(x)); }; console.log(intersection([1, 2, 3], [2, 3, 4])); // [2, 3] ``` ### 從陣列中刪除虛假值 ``` const compact = (arr) => arr.filter(Boolean); console.log(compact([0, 1, false, 2, "", 3, "a", "e" * 23, NaN, "s", 34])); // [1, 2, 3, 'a', 's', 34] ``` ### 反轉字串 ``` const reverseString = (str) => str.split("").reverse().join(""); console.log(reverseString("hello")); // olleh ``` ### 字串是回文嗎 ``` const isPalindrome = (str) => str === str.split("").reverse().join(""); console.log(isPalindrome("madam")); // true ``` ### 檢查物件是否為空 ``` const isEmpty = (obj) => Object.keys(obj).length === 0; console.log(isEmpty({})); // true ``` ### 找出一個月中的天數 ``` const getDaysInMonth = (date) => new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(); console.log(getDaysInMonth(new Date())); // 31 ``` ### 產生隨機顏色 ``` const getRandomColor = () => `#${Math.floor(Math.random() * 16777215).toString(16)}`; console.log(getRandomColor()); // #f0f0f0 const randomHex = () => `#${Math.floor(Math.random() * 0xffffff) .toString(16) .padEnd(6, "0")}`; console.log(randomHex()); // #f0f0f0 ``` --- ##### 必須閱讀(如果還沒有) https://dev.to/devsmitra/how-to-create-the-app-using-jsx-without-react-k08 https://dev.to/devsmitra/reactjs-signal-for-state-mangement-21pf https://dev.to/devsmitra/simplify-javascripts-async-concepts-with-one-gif-3c6a --- ###### 更多內容請造訪[Dev.to](https://dev.to/devsmitra "拉胡爾·夏爾馬(DevsMitra)") 。 --- 原文出處:https://dev.to/devsmitra/20-handy-javascript-functions-to-simplify-your-code-javascript-tutorial-i0e

JavaScript 物件 |完整指南

JavaScript 物件 ------------- 與其他程式語言類似,javascript 物件是鍵值對的集合,其中每個鍵是一個字串,每個值可以是任何資料類型。 ### 建立 JavaScript 物件的方法 1. **物件字面量表示法** ``` The simplests way that you will use 98% of time. ``` ``` const scorcism = { name: "Abhishek", age:21 } ``` ``` The key-value pairs are enclosed within curly braces `{}` ``` 2. **使用`new`關鍵字** ``` Creating objects with constructor functions and the `new` keyword. You will use this only 1.8% of the time ``` ``` function About(name, age, city) { this.name = name; this.age = age; this.city = city; } const me = new About("Abhishek", 21, "Mumbai"); ``` “new”建立一個包含內部“this”的物件。如果省略“new”,則這是全域上下文,因此您的屬性是在物件外部建立的。 ~埃克哈德 3. **使用 Object.create()** ``` This method allows creating a new object with specified prototype object. ``` ``` You will use this only 0.2% of the time ``` ``` const aboutData = { greet:function(){ return `Hello, my is ${this.name}`; // {this.name} is the key of this object } } const me = Object.create(aboutData); me.name = 'Abhishek' me.age = 21; ``` ``` Don't worry much about this :) ``` ### 存取物件屬性 JS 物件的屬性可以使用點表示法和括號表示法來存取。 ``` const me = { name: "Abhishek", age:21 } console.log(me.name); console.log(me["age"]); ``` 嘗試執行程式碼片段。 (每個控制台日誌後面的`undefined`是`console.log`函數本身的回傳值。放鬆,沒什麼好擔心的🕺) ### 物件原型和繼承 JS 的核心是原型的概念。 JS 中的每個物件都與一個原型物件相關聯,原型物件充當該物件的**藍圖**。 簡而言之;物件原型充當建立新物件的模板。 這個原型物件包含所有從它建立的實例都可以存取的屬性和方法。 **繼承**是透過物件的原型連結來實現的。 考慮我們上面使用的**Object.create()** 。它是建立新物件的方法。 ### 靜態方法 (嘗試😃) 1. **物件.keys()** ``` Returns an array of a given object's own enumerable property **names**. ``` ``` TL;DR Object.keys() method will return list of keys. ``` ``` **NOTE:** Own enumerable refers to the properties of an object that are both owned by the object itself (Not inherited from its property chain) ``` ``` const aboutMe= { name: "Abhishek", age:21 } let aboutMeKeys = Object.keys(aboutMe); // Expected Output: [ 'name', 'age' ] ``` 2. **物件.values()** ``` Return an array of a given object's own enumerable property **values**. ``` ``` TL;DR Object.values() method will return list of values. ``` ``` const aboutMe= { name: "Abhishek", age:21 } let aboutMeKeys = Object.values(aboutMe); // Expected Output: [ 'Abhishek', 21 ] ``` 3. **物件.分配()** ``` Copies the values of all enumerable own properties from one or more source objects to a target object. ``` ``` const target = {age: 21} const source = {name: "Abhishek"} const merged = Object.assign(target, source); console.log(merged) // Expected Output: { age: 21, name: 'Abhishek' } ``` ``` **Note:** You can add any number of source args. ``` ``` **target** will contain the modified object. ``` ``` console.log(merged === target) // Expected Output: true ``` 4. **物件.create()** ``` Create new object, using an existing object as the prototype. ``` ``` const me = { name: "Abhishek", eatsAppleDaily: false, printAbout: function(){ console.log(`I am ${this.name}. and I ${this.eatsAppleDaily ? "eat" :"don't eat"} apple daily.`); } }; // Creating a myFriend Object inheriting from me. const myFriend = Object.create(me); // He is my child now😃. myFriend.name = "Ladoo"; myFriend.eatsAppleDaily = true; console.log(me.printAbout()); // Expected Output: I am Abhishek. and I don't eat apple daily. console.log(myFriend.printAbout()); // Expected Output: I am Ladoo. and I eat apple daily. ``` 5. **物件.entries()** ``` Return array of he given object's own enumerable string-keyed property key-value pair😒. ``` ``` It returns an array where each element is a key-value pair of the object. Each key-value pair is represented as an array with two elements: the key as the first element and the corresponding value as the second element. ``` ``` const me = { name:"Abhishek", age:21 } console.log(Object.entries(me)) // Expected output: [ [ 'name', 'Abhishek' ], [ 'age', 21 ] ] ``` 6. **Object.fromEntries()** ``` Object.fromEntries transforms a list of key-value pairs into an object. ``` ``` TL;DR Oppsite of Object.entries(). ``` ``` const me = [ [ 'name', 'Abhishek' ], [ 'age', 21 ] ] console.log(Object.fromEntries(me)) // Expected output: { name: 'Abhishek', age: 21 } ``` 7. **物件.freeze()** ``` The Object.freeze() is a method that "freezes" an object. ``` ``` When you freeze an object, you prevent new properties from being added to it, existing properties from being removed or changed, and also prevent the prototype from being changed. ``` ``` const me = { name:"Abhishek", age:21 } Object.freeze(me); // Freezing the object me.name = "scorcism"; me.age = 22; console.log(me) // Expected output: { name: "Abhishek", age: 21 } ``` ``` Changes are not affected to the object ``` 8. **物件.isFrozen()** ``` Determines if the object is frozen ``` ``` const me = { name:"Abhishek", age:21 } Object.freeze(me); console.log(Object.isFrozen(me)) // Expected output: true ``` 9. **物件.seal()** ``` Object.seal() is a method that "seals" an object. ``` ``` Sealing an object prevent new properties from being added to it and marks all existing properties an non-configurable (i.e prevent them from bein deleted or theri attributes from being changed). ``` ``` const me = { name:"Abhishek", age:21 } Object.seal(me); me.name = "scorcism"; // This change will be affected delete me.age; // This deleting will not take effect console.log(me) // Expected Output: { name: 'scorcism', age: 21 } ``` ``` **Note:** `Object.freeze()` prevents any changes to the object, while `Object.seal()` allows changes to existing properties but prevents addition or removal of properties. ``` 10. **物件.isSealed()** ``` Determines if an object is sealed. ``` ``` const me = { name:"Abhishek", age:21 } Object.seal(me); console.log(Object.isSealed(me)); // Expected output: true ``` ### 繼承靜態方法 在轉向實例靜態方法之前,讓我們先了解一下物件中的`this`關鍵字 假設我們有一個物件 ``` const person = { name: 'Abhishek' }; ``` 所以如果我們在物件中加入一個函數; `this`將引用同一物件的所有屬性 ``` const person = { name: 'Abhishek', sayMyName: function() { return `My name is ${this.name}`; } }; console.log(person.sayMyName()); // Expected Output: My name is Abhishek ``` 正如您在這裡所觀察到的, `this.name`被替換為鍵`name`值。 現在您已經了解了`this`關鍵字的用例,讓我們繼續進一步 1..**原型.bind()** `bind()`方法建立一個新函數,在呼叫該函數時,會將其`this`關鍵字設定為提供的值。 當我們想要從一個物件借用一種方法並在其他物件的上下文中使用它時,這非常有用, ``` function sayMyName (){ return `My name is ${this.name}` } const person = { name: 'Abhishek', sayMyName: sayMyName }; console.log(person.sayMyName()); // Expected Output: My name is Abhishek const person2 = { name: 'Walter' } const person2NameFunc = sayMyName.bind(person2); console.log(person2NameFunc()); // Expected Output: My name is Walter ``` 對於 person2NameFunc,person 物件`this.name`取自 person2 物件,因為我們已將`sayMyName`函數與 person2 物件綁定。 2..**原型.call()** `call()`方法用於呼叫具有給定`this`值和單獨提供的參數的函數。 ``` function introduce(language) { console.log(`I code in ${language}. My name is ${this.name}.`); } const mySelf = { name: "Abhishek" } introduce.call(mySelf, 'Java'); // Expected output: I code in Java. My name is Abhishek. ``` 在這裡,*介紹*函數採用語言參數並記錄有關語言和人名的資訊。 **call()**方法用於以 mySelf 物件作為 this 值來呼叫此函數,從而允許存取其屬性。 與使用指定的`this`值建立新函數的`bind()`不同, `call()`直接使用指定的`this`值以及各個參數來呼叫該函數。 3..**原型.apply()** `apply()`方法與`call()`類似,但它不是單獨接受參數,而是以陣列形式接受參數。 ``` function add(...args){ let sum = args.reduce((acc, curr)=> acc + curr, 0 ); console.log(sum); } const numbers = [1,2,3,4,5]; add.apply(null, numbers) // Expected output: 15 ``` ### 何時使用呼叫、綁定和應用 - **call** :當您想要立即執行函數並指定`this`應該引用的內容時,請使用`call` - **bind** :當您想要建立一個新函數,該函數在稍後執行時具有預先確定的`this`值時,請使用`bind` - **apply** " 當您有要傳遞給函數的參數陣列時,請使用`apply` 。 --- PS:之所以到處用我的名字,是因為在閱讀時,每當你看到我的名字時,你都會傾向於嘗試用你的名字來稱呼它。 這些是最常用的,您可以 [在此處](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)探索更多訊息 --- 如果這篇文章對您有幫助,請留下喜歡、關注或其他任何東西 🙂。 您可以在[LinkedIn](https://www.linkedin.com/in/abhishekpathak32/) 、 [GitHub](https://github.com/scorcism) 、 [Dev.to](https://dev.to/scorcism)和[hashnode](https://scorcism.hashnode.dev/)上關注我。 **再見🍕** --- 原文出處:https://dev.to/scorcism/objects-in-js-complete-guide-3gl8