🔍 搜尋結果:套件

🔍 搜尋結果:套件

從 SDE1 到 SDE2,甚至更高! 🚀 實際需要什麼。

> ***「我擅長寫程式碼。就在這個月,我發了 11 個 PR!我甚至按時更新了我的大部分票。也沒有請那麼多假!而且我也比 Sam 工作了更多時間!為什麼沒有我沒有升職,但他們卻升職了?*** > *-- 一些不幸的人,這次沒有得到促銷。* 這聽起來有關聯嗎? 我以前見過這個。 很多。 有時原因是辦公室政治。 🤬 有時,這只是期望沒有得到良好的溝通。那可能很糟糕。 🥲 有時,你如何達到既定的期望與實際的標準之間**存在不匹配**。 🤔 您可能無法控製或改變您的辦公環境。但你當然可以控制自己,確保沒有任何事情可以阻止你**在職業階梯上的上升**。 ![你明白了,規劃辦公室](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6htoz012vjxxtc5po2hk.gif) > ### 涼爽的!你能快速引導我完成我需要做的事情嗎? 首先要知道身為軟體開發人員的職責是什麼。我不是指您在目前組織中的職責,而是指作為整體和個人開發人員的職責。 #### 目錄 我認為開發人員應該致力於涵蓋**5 個廣泛的領域**。 *點擊連結可跳轉至該部分。* 1. [技術](#1-technical-skills-)(程式碼品質、語言熟練度、測試、效能) 2. [生產力](#2-productivity-)(可靠性和效率) 3. [協作](#3-collaboration-)(溝通和評論) 4. [所有權](#4-ownership-)(責任和主動性) 5. [影響](#5-impact-)(系統/產品改進和創新) *“至此,我們製作 D&D 角色表的工作就完成了一半。滾動 Nat 20!🤣”* **我只會介紹您可以控制的事情。** 我特別提到這一點是因為我看到許多組織犯錯的一件事是,評估的各個領域最終都包括您可能無法控制的事情。 例如,您可能無法控制您的工作對公司的影響力。在大多數情況下,您只能完成直接要求您做的事情。 > ### 好吧!我們走吧!我已經準備好升職了! ![辦公室一百萬美元](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2q5npkuc8euhcnb2pvtm.gif) 我上面提到的 5 個領域並不是 SDE1 所特有的。這是每個開發人員都需要掌握的東西。但每個領域的標準和期望都會改變。 讓我們討論一下每個領域的基線期望是什麼,以及您需要做什麼才能達到下一個水平。 **稍安毋躁。這會很長。** **但請記住,下面只有 5 個部分...👇** ![這需要一段時間](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qaj5r04sxuc1fsfsaqtv.png) ### 1. 技術能力[\[🔝\]](#table-of-contents) 在 SDE1,沒有人指望您能引起轟動、改變世界、節省數十億美元! 他們希望您以最少或最多偶爾需要指導的方式完成工作,並且您交付的工作不需要重新審視或修復(只要合理)。 **太長了;博士** 編寫其他人可以閱讀的體面程式碼,並且不會每 2 秒就中斷一次。 有幾種方法可以做到這一點。 **寫愚蠢的程式碼。不是“智能”程式碼。** - 您可能是 Leetcode、Hackerrank 或類似事物的奇才。但不幸的是,這些網站鼓勵初級人員如此努力地追求效能,以至於常常以**犧牲可讀性為代價**。 - 如果您知道兩個循環僅針對`i`和`j`的較小值執行,那麼使用嵌套循環並不是一個壞主意。 - 如果保證陣列最多只有幾個專案,那麼不使用映射/字典而不是陣列並不是一個壞主意。 ![編寫與閱讀程式碼](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/amla8isarsp66etjd99v.png) **了解該語言為您提供的所有工具。** - 您可能習慣於對所有事情使用 for 循環,但箭頭/lambda 函數可以使您的程式碼更具可讀性。 - \[JS 範例\] 你可能習慣將事物儲存在物件`{}`中,每次尋找的時間複雜度為 O(1),但是`set.has(thing)`比`!!obj[thing]` (甚至`Boolean(obj[thing])` **了解為什麼測試有價值,然後編寫測試** - 人們常常只是在寫測試,因為這是「最佳實踐」。 - 如果不了解背後的原因,您可能會編寫無效或毫無意義的測試。 - 這個想法是,**做任何你需要做的事情,以增加對程式碼穩定性的信心**。您需要使用類型嗎?當然。您需要聘請 QA 人員嗎?有點低效,但很酷。**也許你需要寫...測試?**好吧,但是……我的目標是什麼? - 這可以是一個單獨的部落格。**但這裡有一個簡短的簡短介紹...** - 您是否需要編寫單元測試、整合測試、驗收測試,無論您如何稱呼它們,都沒關係。人們可能對此感到「宗教」。但只要你的測試做了一件基本的事情,這一切都不重要…提高你對程式碼不會破壞的信心。 - 有時您可能需要重構程式碼,使其更易於測試,但是一旦您這樣做了幾次,您就會開始從可測試性的角度考慮程式碼。 - 在實現任何東西之前,為您預期的實作編寫測試也是一個好主意!導致測試套件一開始就完全失敗,而當您實施一些東西時,它會逐漸保持通過!順便說一句,這基本上就是測試驅動開發(TDD)。 **關心表現** - 沒有人會期望您始終以 60 FPS 的速度執行所有內容,或者所有內容的延遲都低於 100 毫秒。 - 但請注意,您的程式碼何時可能會導致對資料庫發出過多請求,或載入過多資料。不要讓你的元件渲染 5 次,因為你無法弄清楚如何正確使用`useEffect`和`useState` 。在需要的地方尋求協助,但要夠小心,不要讓這些東西進入生產階段。 ![延遲紙飛機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57g9q3qria2u6k6s3of5.gif) **⏫ 進入 SDE2:** - 更深入地了解您使用的語言和框架的內部結構。 🧠 了解 React 如何實際渲染事物。了解瀏覽器如何處理從瀏覽器到伺服器的多個請求。了解 Postgres 如何選擇優化或不優化查詢。了解應用程式部署管道的配置方式。 - 詢問有關專案、元件、API 等是如何建構的問題。了解這些設計模式的名稱以及它們的優點和缺點。開始參與架構討論並提出改進建議。誰知道?您可能有更有經驗的人沒有考慮到的想法。 - 指導他人最佳編碼實務。團隊中常常會有比你資歷低的人。查看他們的程式碼。讓他們審查您的程式碼並分享他們應該關注的內容。像尤達一樣,你應該分享你的智慧。 🧠 ### 2. 生產力[\[🔝\]](#table-of-contents) 作為 SDE1,您的生產力是透過您按時可靠地完成任務、有效管理工作負載以及保持專案一致進度的能力來衡量的。您還應該能夠處理輕微的干擾和依賴性,而不會失去焦點或需要持續的指導。 您可能經常需要依靠工具或應用程式或腳本來更有效地完成某些事情。有時您可能需要自己製作這些工具。 如果感覺太多了也沒關係。它不會總是完美的。即使是更資深的開發人員也並不總是能確定這一點。 你會到達那裡的。重要的是,如果您無法履行承諾,請儘早溝通。 **太長了;博士** 目標是按時出色地完成任務。當您覺得自己做不到時,請盡快讓人們知道。 **知道什麼時候該做什麼,什麼時候該說「不」🙅** - 學會區分什麼是緊急的,什麼是重要的。使用艾森豪威爾矩陣等工具有效地確定優先順序。 - 專注於高影響力的任務,但不要忽略那些讓車輪轉動的小任務。 - **學會說不。**天哪,這是一個很大的。這非常重要,以至於它可以單獨成為一個部落格。我有故事。 - 如果你不善於拒絕,你偶爾會發現自己的工作負擔過重。如果你能簡單、清楚地解釋你正在做的事情,以及你何時能夠處理下一件事情,人們通常會認為這是可以接受的。 - 如果你發現自己被逼入絕境,你需要依靠你的經理來為你確定優先事項。只需詢問他們認為最重要的是什麼。 ![沒有上帝請不](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46j4r2r8b9oho91fduvw.gif) *你看到這個人來了,不是嗎?* **管理好你的時間,別讓自己精疲力竭** - 使用番茄鐘等技巧來保持工作效率而不至於精疲力竭。我有很多朋友使用某種數字或實體番茄計時器來管理他們的工作日。 - 追蹤您在不同任務上的時間,以了解您可能在哪些方面花費了過多或過少的時間。 ![番茄計時器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ktom06mrbpkg10u0vslo.png) *我的朋友以前常用的番茄計時器* **如果必須的話,可以透過製作自己的工具來自動化無聊的工作** - 自動執行重複性任務以節省時間。腳本和工具可以處理很多平凡的事情。我已經建立了一大堆腳本、用於內部偵錯的 Slack 命令等,這已經為我和團隊在[Middleware](https://github.com/middlewarehq/middleware)節省了無數的時間。 - 熟悉 IDE 快捷方式、插件和其他可以加快開發過程的工具。如果您的團隊中的大多數人都使用 VSCode 進行開發,您甚至可以就通用 IDE 配置達成一致,並透過將 .vscode 目錄提交到儲存庫來共享該程式碼庫! **⏫ 進入 SDE2:** - 開始更獨立地管理您的專案。建立現實的時間表並滿足它們。 SDE1 可能會不時錯過時間表。 SDE2,則不然。你走得越高,你就越有可能提前完成你的專案! - 主動辨識並解決工作流程中的瓶頸。向團隊提出流程改善建議。通常,您可能沒有時間或支援來實施此類改進。一個可靠的 SDE2+ 舉措就是在其他工作之間的零碎時間裡自己完成,突然有一天,團隊的一些關鍵工作流程痛點神奇地得到了解決!都是因為你。 - 平衡多個專案和任務,同時不忘記最後期限,並了解您並不總是透過每天工作 28 小時來滿足最後期限,您會找到更有效地完成同一件事的方法。因此,表明您可以以相同的生產力水平承擔更多的責任。像托尼史塔克管理他的套裝技術一樣升級你的多任務遊戲! 🦾 ### 3. 合作[\[🔝\]](#table-of-contents) 在 SDE1,您需要清晰溝通、分享您的進步並成為樂於助人的團隊成員。您與他人有效協作的能力對於團隊的成功至關重要。 有很多人依賴你按時交付東西。他們是您的工程經理、產品經理,也許還有他們報告的其他經理,還有等待您完成專案部分的同事。 人們通常可能會晚一點理解某些事情,特別是如果儘早得知的話。但真正導致問題的是: - 不到最後一刻才告訴你會遲到。 - 您的估計不清楚或非常不準確。 我仍然把其中的一些搞砸了。但總體而言,情況確實有所改善。 👌 **太長了;博士** 做一個好的隊友並進行良好的溝通。 ![團隊合作](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/385iu3jjbits6zfgq6zz.gif) **早說、常說,但最重要的是──傾聽** - 讓您的團隊了解您的最新進展。透過站立會議和 Jira 或 Trello 等專案管理工具進行定期更新可以幫助每個人保持一致。 (我知道,Jira 很糟糕,但你必須明白,對於你的經理和高層來說,這是一個相當不錯的工具,可以用來追蹤事情的運作情況。) - 在會議和討論期間積極傾聽。在做出回應之前先了解別人在說什麼。 - 成為一個好的傾聽者也會讓你更快找到女朋友/男朋友🤣。如果你不這樣做,我們希望你能通過規則 1 和 2。 **保護您的生產,檢查程式碼** - 積極參與程式碼審查。提供建設性的回饋並樂於接受。非常關心不要讓可讀性差或有潛在風險(效能、使用者體驗或安全性方面)的程式碼最終出現在產品中。 - 從您收到的回饋中學習並將其應用到您未來的工作中。 如果您需要令人信服地了解為什麼程式碼審查至關重要以及如何正確執行,也許這會有所幫助: {% 嵌入 https://dev.to/middleware/the-senior-engineers-guide-to-the-code-reviews-1p3b %} **讓您的團隊隨時了解您所學到的知識** - 與您的團隊分享您所學到的知識。無論是新工具、編碼技巧還是有趣的文章,讓您的團隊了解情況有助於每個人成長。如果您使用 Slack,#engineering 頻道是進行此類活動的好地方。 #memes 也是如此。 😄 - 為程式碼庫或流程的複雜部分撰寫文件並建立指南。這有助於其他人更有效地理解和使用您的工作。記住這個文件需要可搜尋是非常重要的。無法搜尋到的文件就不存在。 [Glean](https://www.glean.com)可能是一個很好的工具來幫助解決這個問題,但它是一個付費(而且昂貴)的東西。 **⏫ 進入 SDE2:** - 發揮指導作用。幫助初級開發人員應對任務和挑戰。幫助他們規劃、估算、記錄等。 - 領導小型專案或倡議。表明您可以協調努力並將團隊聚集在一起以實現共同目標。 - 促進團隊內部的溝通。幫助解決衝突並確保每個人的意見都得到傾聽。每個團隊都有內向的人,通常他們是最難溝通的,盡可能幫助他們。成為團隊中的美國隊長,團結一致,以身作則! 🛡️ ### 4. 所有權[\[🔝\]](#table-of-contents) 擁有所有權意味著對你的工作及其影響負責。作為 SDE1,這意味著您應該確保您的程式碼按預期工作,勤奮地處理您的任務,並履行您的承諾。 就像創始人或執行長必須盡一切努力確保公司生存、繁榮和盈利一樣,你也必須盡一切努力確保你的工作符合規定的時間表,並以以下方式交付:不僅滿足,而且超越標準。 可以理解的是,有時設定的時間表或期望可能根本不切實際。這就是你的溝通技巧需要發揮的地方。 **太長了;博士** 擁有你的工作及其品質。完成你開始的事情。 ![德懷特覆蓋](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hc5yu0726kgkxrws7xmy.gif) *也許不像……那樣。* **學會承諾** - 如果您致力於一項任務,請堅持到底直至完成。如果遇到障礙,請儘早溝通。 - 不要推卸責任。如果您的程式碼或任務有問題,請努力解決它,而不是責怪他人。 **積極主動:看到一些事情,做一些事情** - 不要等待問題被分配給您。如果您發現有問題需要修復,請主動解決。當然,您需要適當地確定優先順序。並非所有需要修復的東西都需要您先停放正在處理的任何東西並先修復它。 - 提前想好。預測潛在問題並在它們成為問題之前解決它們。對於技術或工程相關的工作,ERD(工程需求文件)可以大大幫助您制定工作計劃。 - 您的經理可能會從他們的角度關注您團隊的生產力,但作為積極主動的開發人員,您也可以這樣做。畢竟,您才是真正了解是什麼讓您有生產力的人。如果你能想出一種方法向你的經理進行生產力分析,向他們展示你的團隊實際上做得很好,或者在需要他們注意的事情上遇到了阻礙,這會讓你得到一些嚴肅的觀點。 DORA 指標是衡量開發團隊生產力的一種相當流行的方法。如果您不確定如何開始衡量這樣的事情,也許這個部落格會有所幫助: [什麼是 DORA 指標?](https://www.middlewarehq.com/blog/what-are-dora-metrics-how-they-can-help-your-software-delivery-process) **每一天,都要比前一天更好** - 反思你的工作。什麼進展順利?還有什麼可以更好的呢?利用這種反思來不斷改進。這將是您的經理將(或應該)進行的 Sprint 回顧的更個人化版本。 - 積極尋求回饋並應用它。努力讓您承擔的每個專案變得更好。對於提供回饋的人來說,共享回饋也是一項艱鉅的工作。如果您的組織沒有為此定義流程,那麼每季、每月等阻止一些時間可能是個好主意。 - 嘗試遵循童子軍規則,該規則基本上規定您應該留下比您發現時更好的程式碼庫。[在這裡閱讀更多內容](https://deviq.com/principles/boy-scout-rule)。 **⏫ 進入 SDE2:** - 從頭到尾推動專案。承擔需要您在最少監督的情況下規劃、執行和交付的任務。如果你證明自己有足夠的自我能力,你的經理可能會讓你監督更多的開發人員來執行這個專案。現在這是一些高級開發的東西。 💪 - 辨識並實施流程、工具或程式碼庫的改進。之前也提到過,但這裡的重點略有不同。表明您正在著眼於更大的前景並為組織的長期成功做出貢獻。 - 倡導最佳實踐並確保它們得到遵循。成為您專案中的蝙蝠俠—可靠、警惕並始終提供卓越服務。 🦇 ### 5.影響[\[🔝\]](#table-of-contents) 作為 SDE1,您的影響可能僅限於分配給您的任務和專案。然而,表現出更廣泛的理解並在你的直接職責之外做出貢獻可以讓你與眾不同。影響力不僅指你所做的事情,也指你的工作如何影響和造福你的團隊、你的專案和整個組織。 **太長了;博士** 做出改變。不只是做,而是改進。 ![往前想](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikxg6wmu8bnj72alus4c.png) **不要局限於“你的工作”** - 了解您所從事的業務和行業。 - 確定改進或創新的機會。建議可以使團隊或產品受益的增強功能。 - 關注產品的最終用戶。了解他們的需求和痛點可以引導您做出更有影響力的貢獻。不要只是建立你要求的任何東西,還要分析你的努力對使用者和組織有多成功。 **為社區做出貢獻** - 參與內部和外部開發者社群。參加聚會、為開源專案做出貢獻或撰寫技術部落格。 - 分享您的知識和專業知識,幫助他人成長和學習。組織技術講座、網路研討會或程式設計訓練營或在技術講座、網路研討會或程式設計訓練營中發表演講。 - 與組織內的其他團隊合作。為跨職能專案提供協助和協作,以擴大您的影響力。 ![瑞安社區服務](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zh2nexhrfd6azq4cz6qm.gif) *您可能不會被「要求」在工作中幫助您的社區🤣* **積極主動地解決問題** - 超越任務的直接要求。考慮一下您的解決方案如何使其他專案或未來的工作受益。 - 養成批判性思考您使用的工具和流程的習慣。提出並實施可以節省時間、減少錯誤或提高效能的改進措施。 - 不要等待有人給您分配有影響力的工作。尋找機會做出有意義的貢獻,即使這意味著走出你的舒適圈。 有時您可能必須依賴第三方工具來辨識流程中的問題。像[中間件](https://github.com/middlewarehq/middleware)這樣的工具可以讓您發現軟體交付中的問題。現在這是高級開發人員的舉動。 {% 嵌入 https://github.com/middlewarehq/middleware %} **創新與改進** - 隨時了解您所在領域的最新趨勢和技術。嘗試可以使您的專案受益的新工具和方法。 - 考慮工作中的可擴展性和可維護性。設計系統並編寫可以隨著業務需求而成長和發展的程式碼。 - 鼓勵團隊內部的創新文化。促進腦力激盪會議和黑客馬拉松,以產生新的想法和解決方案。 **⏫ 進入 SDE2:** - 開始戰略性思考。找出對團隊目標和公司成功產生重大影響的方法。尋找您和團隊的工作模式,並提出可以使每個人受益的改進建議。大多數人都不太擅長這一點,所以如果你能做到這一點,那絕對會讓你脫穎而出。 - 領導推動創新和改進的措施。表明您可以創造性地思考並提出有效的解決方案。這可能涉及提出新功能、優化現有系統或改進開發流程。 - 倡導可以提高生產力或品質的新技術或方法。 🚀 帶頭將這些技術整合到您的專案中並指導其他人使用它們。 --- 請記住,從 SDE1 升級到 SDE2 以及更高版本是一個旅程。專注於你可以控制的事情,尋求回饋,並不斷改進。作為開發人員,您的成長是技術技能、生產力、協作、所有權和影響力的結合。透過奉獻和努力,您不僅會升級,而且會享受成為更好的工程師和有價值的團隊成員的過程。遊戲開始! 🎮 **PS:資深工程師擅長辨識阻礙團隊準時交付的各種問題,同時又不影響輸出品質。** 其中一些使用[中間件](https://github.com/middlewarehq/middleware)等工具。 {% 嵌入 https://github.com/middlewarehq/middleware %} --- 原文出處:https://dev.to/middleware/going-from-sde1-to-sde2-and-beyond-what-it-actually-takes-1cld

建構強大的 CI/CD 管道:綜合指南

歡迎參加 DevSecOps in 5 的第 2 週:您獲得安全開發超級大國的門票! \_嘿,安全冠軍和編碼戰士! 您是否渴望提升 DevSecOps 水平並成為堅如磐石的軟體架構師?好吧,您來對地方了!這個為期 5 週的部落格系列是您掌握安全開發和部署的快速通道。 準備好拋棄開發戲劇,對您的安全實踐建立不可動搖的信心。我們同舟共濟,所以係好安全帶,讓我們踏上這段史詩般的旅程! --- 軟體開發環境處於不斷變化的狀態。更快的發布週期、不斷發展的技術以及不斷增長的品質需求正在推動團隊採用敏捷方法並擁抱自動化。進入 CI/CD 管道—簡化軟體交付背後的主力。這篇部落格深入探討了 CI/CD 的世界,提供了從入門到探索先進技術的全面指南。 為什麼 CI/CD 管道是您的秘密武器 ------------------- 在深入研究之前,讓我們先了解 CI/CD 管道無可否認的優勢: #### 更快的上市時間: 漫長的發布週期的日子已經一去不復返了。 CI/CD 可自動執行建置、測試和部署流程,從而實現頻繁且更快的部署。新功能可以更快地觸及用戶,保持他們的參與度並培養競爭優勢。 例:想像一家公司正在開發一個新的電子商務平台。透過實施 CI/CD 管道,他們可以自動部署新功能,例如改進的搜尋功能或更快的結帳流程。這使他們能夠快速響應用戶反饋和市場趨勢,在競爭中保持領先地位。 #### 提升軟體品質: 想像一下,儘早發現錯誤並在影響生產之前防止回歸。 CI/CD 在整個管道中整合了自動化測試。單元測試、集成測試,甚至端到端測試都可以無縫集成,確保每個階段的程式碼品質。 範例:開發金融服務應用程式的公司可以利用具有強大單元和整合測試的 CI/CD 管道。這確保帳戶管理和交易處理等關鍵功能在投入生產之前經過徹底測試,從而最大限度地減少錯誤和財務損失的風險。 #### 提高協作和效率: CI/CD 透過打破開發和營運團隊之間的孤島來促進協作。開發人員可以充滿信心地編寫程式碼,因為他們知道自動化測試提供了安全網。營運團隊受益於可預測和簡化的部署。這培育了一種共同所有權和責任的文化。 範例:在傳統的開發過程中,開發人員可能會將程式碼「越過牆」扔給操作,導致相互指責和延遲。透過 CI/CD 管道,兩個團隊都參與整個過程。開發人員可以看到他們的程式碼在自動化測試中的執行情況,而操作人員可以更了解即將進行的部署。這可以促進更順暢的協作和更快的問題解決。 設定您的第一個 CI/CD 管道(不僅僅是 Jenkins) ------------------------------ 雖然 Jenkins 仍然是一個流行的選擇,但 CI/CD 環境提供了大量工具來滿足您的特定需求。以下是一些受歡迎的競爭者,以及他們的優勢的簡要概述: #### GitLab CI/CD: 與 GitLab 緊密整合,實現無縫版本控制和 DevOps 工作流程。非常適合已經使用 GitLab 進行程式碼管理的團隊。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1masi4ldtu7fm6bz5kva.png) #### Circle CI: 基於雲端的平台以其易用性、可擴展性和注重開發人員體驗而聞名。對於尋求用戶友好且可擴展解決方案的團隊來說,這是一個不錯的選擇。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3sozor0d4vf3iik92n6.png) #### Azure DevOps: Microsoft 提供全面的 DevOps 工具鏈,提供 CI/CD 管道以及建置管理和工件儲存庫等其他功能。非常適合大量投資於 Microsoft 生態系統的組織。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hxmg0lxkoduvbopjhtll.png) #### Travis CI: 開源平台以其簡單性和專注於持續整合而聞名。對於小型團隊或從 CI/CD 開始的團隊來說,這是一個不錯的選擇。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hd6fr17cr7ckgfn5isyl.png) 現在,讓我們探討 CI/CD 管道的常見階段及其用途: #### 程式碼提交: 將變更推送到版本控制系統 (VCS)(如 Git)的觸發點。 #### 建造: 程式碼被編譯成可部署的工件(例如,可執行檔、WAR 檔)。 #### 測試: 針對建置的工件執行自動化測試,以辨識任何錯誤或回歸。 #### 部署: 測試成功後,工件將部署到目標環境(暫存、生產)。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kr66y6ycum7sd9suxpdd.png) #### CI/CD 工作流程設定範例(使用 GitLab CI/CD): ``` stages: - build - test - deploy build: stage: build script: - npm install - npm run build test: stage: test script: - npm run test deploy: stage: deploy script: - scp -r dist/ user@server_ip:/var/www/html/my_app only: - master ``` 將版本控制與 CI/CD 整合:自動化的力量 ---------------------- VCS 在 CI/CD 管道中發揮著至關重要的作用。這就是它的工作原理: #### 版本控制系統 (VCS): Git 等工具追蹤程式碼更改,允許開發人員協作並在需要時恢復到先前的版本。 CI/CD 管道利用此功能來確保可追溯性並在部署失敗時促進回溯。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mikn0zfpeydo5oiv2mno.png) #### 管道執行的觸發器: CI/CD 管道可以設定為自動觸發 VCS 內的特定事件。常見的觸發因素包括: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t3t78w8ex3pzkjpnwkg2.png) #### 程式碼提交: 每當開發人員將程式碼變更推送到特定分支時,管道就會啟動。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxx9bnifs1go7mw4frhx.png) #### 合併到特定分支: 僅當程式碼合併到特定分支(例如 master 或 staging)時才能觸發管道。這允許對部署進行更多控制。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vwx42no4pb94b3xxovzw.png) #### 被推送的標籤: 將標籤推送到儲存庫可以觸發管道,通常用於與版本相關的部署。 #### 分支策略: CI/CD 管道可以客製化以適應不同的分支策略。以下是兩種常見的方法: #### 功能分支工作流程: 開發人員為開發工作建立功能分支。完成並進行程式碼審查後,程式碼將合併到主分支(例如 master),觸發 CI/CD 管道進行部署。這種方法允許單獨開發和測試新功能。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8hmkjpemri80yjn2h9m.png) #### Git 流程工作流程: 此策略利用專用的開發分支進行持續開發。功能從開發中分支出來,並在測試後合併回來。合併以開發觸發 CI/CD 管道以部署到臨時環境。最後,從開發部署到生產需要手動升級。這種方法在開發、登台和生產環境之間提供了明確的分離。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6l6zc5zq47nljqjs17w4.png) #### 選擇分支策略: 最佳策略取決於您的團隊規模、專案複雜性以及所需的部署控制等級。功能分支工作流程適合專案較簡單的小型團隊。 Git Flow 為大型團隊或複雜專案提供了更多的環境控制和分離。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tsvx28v0iigzvwfobfng.png) 持續交付與持續部署: ---------- 了解差異 這些術語經常互換使用,但有一個關鍵區別: #### 持續部署: 成功完成管道後,變更將自動部署到生產中。這種方法需要強大的測試和對程式碼品質的高度信心。它非常適合風險承受能力低且注重快速迭代的應用程式。 範例:開發社交媒體應用程式的公司可能會利用持續部署來實現不影響核心功能的功能。自動化測試可確保品質,快速部署可實現快速實驗和功能推出。 #### 持續交付: 該管道自動建置、測試並部署到臨時環境。在部署到生產之前需要手動批准。這種方法為關鍵應用程式提供了一個安全網,並允許在實施變更之前進行手動監督。 例如:開發金融交易平台的公司可能會從持續交付中受益。管道成功執行後,部署將在投入生產之前進行分階段和審查。這確保了關鍵功能在影響現實世界的交易之前經過徹底的測試和批准。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7rlprqoto2rihmk28xu3.png) #### 選擇正確的策略: 持續部署和持續交付之間的選擇取決於以下因素: #### 風險承受能力: 對於具有高風險或影響的應用程式,可能首選透過手動批准進行持續交付。 #### 應用關鍵性: 關鍵任務應用程式可能會受益於生產部署之前手動批准的額外安全網。 #### 測試覆蓋範圍: 強大而全面的測試對於持續部署至關重要。如果測試範圍較小,則透過手動審核進行持續交付可能是更安全的選擇。 #### 回滾策略:總是有一個 B 計劃 無論您的 CI/CD 管道多麼細緻,都可能會出現不可預見的問題。制定回滾策略可確保您可以快速恢復到穩定狀態: ### 版本控制的救援: 如果部署出現問題,VCS 允許您輕鬆恢復到先前的程式碼提交。這是一種快速可靠的回滾部署方法。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/doul01tn1rf1bn51cs95.png) #### 回滾腳本: 在 CI/CD 管道中定義腳本,以便在發生故障時自動回滾部署。這可能涉及恢復基礎架構變更或降級配置。這些腳本提供了一種更自動化的回滾方法。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4swhforiux7h7sxnykkn.png) #### 藍/綠部署: 此策略涉及將新版本部署到單獨的環境(綠色),同時保持現有版本運作(藍色)。如果新版本正常執行,流量將切換到綠色環境。如果出現問題,可以無縫切換回藍色。藍/綠部署可最大限度地減少回滾期間的停機時間。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rhcwn0cwttal0yfymgk.png) #### 選擇回滾策略: 最佳方法取決於您的特定需求。 VCS 回滾簡單可靠,但需要手動介入。回滾腳本提供自動化,但需要仔細的設計和測試。藍/綠部署提供了更強大的回滾方法,但可能需要額外的基礎設施設定。 將您的 CI/CD 管道提升到新的水平 ------------------- #### CI/CD 管道安全: 安全性在任何軟體開發過程中都是至關重要的,CI/CD 管道也不例外。以下是保護管道安全的一些最佳實踐: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2hl4xwf0krot2nlx54p0.png) #### 管理秘密: 使用機密管理工具安全地儲存密碼、API 金鑰和資料庫憑證等敏感資訊。這些工具對機密進行加密並限制對 CI/CD 管道內授權使用者和應用程式的存取。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ieww0aoauvexapf9dkq.png) #### 限制存取控制: 在 CI/CD 工具中定義明確的存取控制,以限制誰可以修改或觸發管道。實施基於角色的存取控制 (RBAC) 以根據使用者角色和職責授予權限。這確保只有授權的個人才能更改管道配置。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wxvwarjo75beumbr0swk.png) #### 定期安全審核: 對 CI/CD 管道進行定期安全審核,以辨識和解決潛在漏洞。這種主動方法可以最大限度地降低未經授權的存取或安全漏洞的風險。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p0gobpx2nw8b0u9e867h.png) #### 監控和記錄: 密切監控 CI/CD 管道的性能和錯誤檢測。實施日誌記錄解決方案來追蹤管道執行並辨識潛在的瓶頸或故障。用於監控和記錄的常用工具包括: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzg4r2y894s742wbxd04.png) #### 格拉法納: 一個開源平台,用於視覺化來自各種來源(包括 CI/CD 管道)的指標和日誌。這允許您建立儀表板來監控管道執行狀況、建置時間和部署成功率。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vrob5ut2ipkrq6iz6y4.png) #### ELK 堆疊(Elasticsearch、Logstash、Kibana): 用於收集、儲存、分析和視覺化日誌的強大工具組合。您可以使用 ELK Stack 集中來自 CI/CD 管道和其他系統的日誌,以進行全面監控和故障排除。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gg5aqvi50jyoyd0rh81q.png) #### 內建監控工具: 許多 CI/CD 平台提供內建的監控和日誌記錄功能。利用這些工具深入了解管道執行並辨識潛在問題。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djrjfa9uk1if4jux25zg.png) #### 不同程式語言的 CI/CD: CI/CD 管道與語言無關。特定於您的程式語言的建置工具和測試框架可以無縫整合在管道中。這裡有些例子: #### 爪哇: Maven 或 Gradle 等建置工具可用於自動化 Java 應用程式的建置流程。可以整合 JUnit 等測試框架以進行單元測試和整合測試。 #### JavaScript: 對於 JavaScript 專案,npm 或yarn 等工具可以管理依賴項。 Jest 或 Mocha 等測試框架可用於自動化測試。 #### Python: Python 專案經常利用 setuptools 或 Poetry 等建置工具。像unittest或pytest這樣的測試框架是自動化測試的流行選擇。 請記住:雖然 CI/CD 管道的核心概念在不同語言中保持一致,但特定工具和配置可能會有所不同。研究適合您選擇的程式語言的最佳實踐和工具,以優化您的 CI/CD 管道。 加深您的 CI/CD 專業知識:進階主題 -------------------- CI/CD 是一個不斷發展的領域。讓我們探索一些進階概念,將您的管道推向極限: #### 先進的 CI/CD 技術: #### 基礎設施即程式碼 (IaC): Terraform 或 Ansible 等工具可讓您將基礎架構配置定義為程式碼。這些配置可以整合到您的 CI/CD 管道中,以自動化基礎設施配置和管理。 IaC 促進基礎設施的一致性、可重複性,並減少手動配置錯誤。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rpivmcb9c1792csuhjdo.png) #### 與遺留系統的持續整合: 將遺留系統整合到 CI/CD 管道中可能具有挑戰性。策略包括使用包裝器或適配器透過 API 公開遺留功能。這允許遺留系統與管道互動以進行自動化測試和部署。 #### 藍/綠部署: 前面討論過,藍/綠部署可最大限度地減少應用程式更新期間的停機時間。透過先部署到單獨的環境,您可以確保在出現問題時無縫回滾。 #### 金絲雀部署: 此策略涉及將應用程式的新版本部署到一小部分使用者(金絲雀),以便在全面部署之前辨識並修復問題。金絲雀部署可讓您在將新版本公開給所有使用者之前在有限的範圍內測試新版本,從而最大限度地降低風險。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g5df1jw6f9ckmtop4t7y.png) #### 不同專案類型的 CI/CD: #### 微服務架構: 基於微服務的應用程式可以受益於旨在處理單一微服務的獨立建置、測試和部署的 CI/CD 管道。這允許更快地部署和更輕鬆地管理複雜的應用程式。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uqrrbc30qetaklxuvmn.png) #### 使用 Docker 進行容器化: Docker 容器提供了一種打包和部署應用程式的標準化方法。 CI/CD 管道可用於跨環境自動建置和部署 Docker 映像。容器化簡化了部署並確保跨環境的應用程式行為一致。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xakuitegoux6baihwdb4.png) #### 用於機器學習 (ML) 專案的 CI/CD: 機器學習專案通常需要管理大型資料集和複雜模型。 CI/CD 管道可以客製化為: #### 自動化資料版本控制和管理: 確保用於培訓和測試的資料與程式碼變更一起進行追蹤和版本控制。這樣可以實現可重複性並更輕鬆地進行故障排除。 #### 整合模型訓練與測試: 在管道中利用 TensorFlow 或 PyTorch 等工具來自動化模型訓練和測試過程。這確保了模型在部署之前經過嚴格評估。 #### 管理模型部署: CI/CD 管道可用於將經過訓練的模型部署到生產環境。這簡化了流程並確保開發和生產模型之間的一致性。 持續改進與優化: -------- #### 效能優化: CI/CD 管道可能會遇到效能瓶頸,尤其是隨著專案的成長。以下是一些優化策略: #### 快取依賴: 快取經常使用的依賴項(例如,庫、套件)以減少建置期間的下載時間。這可以顯著提高建置速度,尤其是對於大型專案。 #### 並行化: 分解可以同時執行的管道階段(例如,不同模組的單元測試)並並行執行它們。這減少了整體管道執行時間。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tb4qguz8vmi4vb6anaiw.png) #### 資源優化: 根據管道階段的要求分配適當的資源(CPU、記憶體)。這確保了資源的有效利用並避免了瓶頸。 #### 指標和監控: 不要只是建立管道,還要積極監控其效能和運作狀況。就是這樣: #### 定義關鍵績效指標 (KPI): 確定代表管道有效性的指標,例如建置時間、部署頻率和回滾率。隨著時間的推移追蹤這些 KPI,以確定需要改進的領域。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8quogqkfkkjbkul4ype8.png) #### 利用監控工具: 實施 Grafana 或 Prometheus 等監控工具來視覺化管道指標並辨識潛在問題。這使您能夠主動解決瓶頸和效能下降。 #### 追蹤管道日誌: 日誌提供了有關管道執行的寶貴見解。利用 ELK Stack 等日誌分析工具來分析日誌並辨識可能表明潛在問題的錯誤或警告。 #### CI/CD 版本控制: 就像程式碼一樣對 CI/CD 管道配置進行版本控制。原因如下: #### 追蹤變化: 版本控制允許您追蹤對管道配置所做的更改,類似於追蹤程式碼更改的方式。這有助於在必要時進行回滾,並確保您可以恢復到先前的工作配置。 #### 協作與評審: 透過版本控制,多個團隊成員可以協作處理管道配置並在部署之前檢查變更。這可以促進最佳實踐並降低錯誤風險。 #### 災難復原: 如果您的 CI/CD 管道出現重大問題,版本控制可以讓您快速恢復到已知的良好狀態。這可以最大限度地減少停機時間並確保您可以從意外問題中恢復。 CI/CD 的未來:展望未來 -------------- CI/CD 格局不斷發展。以下是一些值得關注的令人興奮的趨勢: #### CI/CD 中的人工智慧和機器學習: 人工智慧可以自動化管道內的任務、優化資源分配並預測潛在問題。機器學習可用於分析歷史資料並提出管道的改進建議。這裡有些例子: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/frk52c5r06hdj3dvhc6r.png) #### 自動測試用例產生: AI可用於分析程式碼並自動產生測試案例,提高測試覆蓋率並減少手動工作。 #### 預測管道分析: 機器學習演算法可以分析管道資料,以在潛在瓶頸或故障發生之前預測它們。這允許主動幹預並確保管道平穩執行。 #### 自癒管道: 想像一下可以自動偵測故障並從故障中恢復的管道。這可能涉及重新啟動失敗的階段或回滾部署。人工智慧和機器學習在開發自我修復管道方面可以發揮至關重要的作用。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9uf4xg8jl4yvtcy4fqyd.png) #### 無伺服器應用程式的 CI/CD: 無伺服器功能變得越來越流行。 CI/CD 管道可用於自動部署和管理無伺服器功能。就是這樣: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7lflsufhkb84dsqk7dk.png) #### 建置與打包無伺服器功能: CI/CD 管道可用於建置無伺服器函數並將其打包到特定於雲端提供者的部署工件中(例如,AWS Lambda 套件、Azure Functions)。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9mnbn81w0w66yw39aq3x.png) #### 部署和管理無伺服器功能: 此管道可以自動將無伺服器功能部署到目標雲端平台。此外,它還可以根據流量模式管理配置更新和擴充。 #### 監控和優化無伺服器功能: CI/CD 管道可以與監控工具集成,以追蹤無伺服器功能的效能和成本。這允許持續優化和成本管理。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qv998kwcpr7cbo3fug4.png) 透過採用這些進步並不斷改進您的 CI/CD 實踐,您可以確保您的軟體交付快速、高效且可靠。以下是一些鞏固您的 CI/CD 知識的結論: CI/CD 是一段旅程,而不是目的地 建立防彈 CI/CD 管道是一個持續的過程。隨著專案的發展,調整和完善您的管道以滿足不斷變化的需求。隨時了解最新趨勢和工具,以持續優化您的 CI/CD 工作流程。 溝通和協作是關鍵成功的 CI/CD 管道需要開發、營運和安全團隊之間的密切協作。促進開放式溝通並鼓勵回饋,以確保管道符合每個人的需求。 測量和分析 不要只是建造管道並設置它就忘記它了。定期監控管道性能、分析指標並確定需要改進的領域。使用資料驅動的見解來優化您的 CI/CD 流程並確保其提供最大價值。 結論 -- CI/CD 管道是現代軟體開發的主力。透過了解本綜合指南中探討的核心概念、最佳實踐和先進技術,您可以幫助您的團隊更快、更有效率地交付高品質的軟體。擁抱 CI/CD,不斷改進您的管道,並見證您的軟體交付飆升至新的高度。 --- 我很高興有機會與您一起深入研究《建立防彈 CI/CD 管道:綜合指南》。這是一個令人著迷的領域,具有改善安全狀況的巨大潛力。 感謝您與我一起探索《建立防彈 CI/CD 管道:綜合指南》。您持續的興趣和參與推動了這趟旅程! 如果您發現有關建立防彈 CI/CD 管道:綜合指南的討論有幫助,請考慮與您的網路分享!知識就是力量,尤其是在安全方面。 讓我們繼續談話吧!在下面的評論中分享您的想法、問題或經驗《建立防彈 CI/CD 管道:綜合指南》。 渴望了解有關 DevSecOps 最佳實踐的更多資訊?請繼續關注下一篇文章! 透過共同努力並採用安全的開發實踐,我們可以建立一個更具彈性和值得信賴的軟體生態系統。 請記住,安全開發之旅是一個持續學習的過程。這是為了持續改進! --- 原文出處:https://dev.to/gauri1504/building-a-bulletproof-cicd-pipeline-a-comprehensive-guide-3jg3

使用 Langchain 為您的文件建立 QA 機器人 😻

--- 標題:使用 Langchain 為您的文件建立 QA 機器人 😻 描述:使用 Wing Framework、NextJS 和 Langchain 建立的 ChatGPT 用戶端應用程式 canonical\_url:https://www.winglang.io/blog/2024/05/29/qa-bot-for-your-docs-with-langchain 發表:真實 --- 長話短說 ---- 在本教學中,我們將為您的網站文件建立一個人工智慧驅動的問答機器人。 - 🌐 建立一個用戶友好的 Next.js 應用程式來接受問題和 URL - 🔧 設定一個 Wing 後端來處理所有請求 - 💡 透過使用 RAG 抓取和分析文件,將 @langchain 納入 AI 驅動的答案 - 🔄 前端輸入和人工智慧處理的回應之間的完整連接。 ![問題](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykw5f2sos4fdhj8akowt.gif) 什麼是翼? ----- [Wing](https://wing.cloud/redirect?utm_source=qa-bot-reddit&redirect=https%3A%2F%2Fwww.winglang.io%2Fblog%2F2024%2F05%2F29%2Fqa-bot-for-your-docs-with-langchain)是一個雲端開源框架。 它允許您將應用程式的基礎架構和程式碼組合為一個單元,並將它們安全地部署到您首選的雲端提供者。 Wing 讓您可以完全控制應用程式基礎架構的配置方式。除了其易於學習的[程式語言](https://www.winglang.io/docs/language-reference)之外,Wing 還支援 Typescript。 在本教學中,我們將使用 TypeScript。所以,別擔心,您的 JavaScript 和 React 知識足以理解本教學。 ![翼登陸頁面](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u366v255drbwqmcoagrz.png) {% cta https://wingla.ng/github %} 看 Wing ⭐️ {% endcta %} --- 使用 Next.js 建立前端 --------------- 在這裡,您將建立一個簡單的表單,它接受文件 URL 和使用者的問題,然後根據網站的資料回傳回應。 首先,建立一個包含兩個子資料夾的資料夾 - `frontend`和`backend` 。 `frontend`資料夾包含 Next.js 應用程式, `backend`資料夾用於 Wing。 ``` mkdir qa-bot && cd qa-bot mkdir frontend backend ``` 在**`frontend`**資料夾中,透過執行以下程式碼片段來建立 Next.js 專案: ``` cd frontend npx create-next-app ./ ``` ![下一個應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyq8dnmmmplvzl7g41ir.png) 將下面的程式碼片段複製到`app/page.tsx`檔案中,以建立接受使用者問題和文件 URL 的表單: ``` "use client"; import { useState } from "react"; export default function Home() { const [documentationURL, setDocumentationURL] = useState<string>(""); const [question, setQuestion] = useState<string>(""); const [disable, setDisable] = useState<boolean>(false); const [response, setResponse] = useState<string | null>(null); const handleUserQuery = async (e: React.FormEvent) => { e.preventDefault(); setDisable(true); console.log({ question, documentationURL }); }; return ( <main className='w-full md:px-8 px-3 py-8'> <h2 className='font-bold text-2xl mb-8 text-center text-blue-600'> Documentation Bot with Wing & LangChain </h2> <form onSubmit={handleUserQuery} className='mb-8'> <label className='block mb-2 text-sm text-gray-500'>Webpage URL</label> <input type='url' className='w-full mb-4 p-4 rounded-md border text-sm border-gray-300' placeholder='https://www.winglang.io/docs/concepts/why-wing' required value={documentationURL} onChange={(e) => setDocumentationURL(e.target.value)} /> <label className='block mb-2 text-sm text-gray-500'> Ask any questions related to the page URL above </label> <textarea rows={5} className='w-full mb-4 p-4 text-sm rounded-md border border-gray-300' placeholder='What is Winglang? OR Why should I use Winglang? OR How does Winglang work?' required value={question} onChange={(e) => setQuestion(e.target.value)} /> <button type='submit' disabled={disable} className='bg-blue-500 text-white px-8 py-3 rounded' > {disable ? "Loading..." : "Ask Question"} </button> </form> {response && ( <div className='bg-gray-100 w-full p-8 rounded-sm shadow-md'> <p className='text-gray-600'>{response}</p> </div> )} </main> ); } ``` 上面的程式碼片段顯示了一個表單,該表單接受使用者的問題和文件 URL 並將它們暫時記錄到控制台。 ![QA 機器人表單](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7b4w3tq0srua93gnk73n.png) 完美的! 🎉您已經完成了應用程式的使用者介面。接下來,讓我們設定 Wing 後端。 --- 如何在電腦上設定 Wing ------------- Wing 提供了一個 CLI,使您能夠在專案中執行各種 Wing 操作。 它還提供[VSCode](https://marketplace.visualstudio.com/items?itemName=Monada.vscode-wing)和[IntelliJ](https://plugins.jetbrains.com/plugin/22353-wing)擴展,透過語法突出顯示、編譯器診斷、程式碼完成和片段等功能增強開發人員體驗。 在繼續之前,請停止 Next.js 開發伺服器並透過在終端機中執行下面的程式碼片段來安裝 Wing CLI。 ``` npm install -g winglang@latest ``` 執行以下程式碼片段以確保 Winglang CLI 已安裝並按預期工作: ``` wing -V ``` 接下來,導航到`backend`資料夾並建立一個空的 Wing Typescript 專案。確保選擇`empty`模板並選擇 Typescript 作為語言。 ``` wing new ``` ![永新](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezy04zqvz9lura0d25dj.png) 將下面的程式碼片段複製到`backend/main.ts`檔案中。 ``` import { cloud, inflight, lift, main } from "@wingcloud/framework"; main((root, test) => { const fn = new cloud.Function( root, "Function", inflight(async () => { return "hello, world"; }) ); }); ``` **`main()`**函數充當 Wing 的入口點。 它建立一個雲端函數並在編譯時執行。另一方面, **`inflight`**函數在執行時執行並返回`Hello, world!`文字. 透過執行下面的程式碼片段啟動 Wing 開發伺服器。它會自動在瀏覽器中開啟 Wing 控制台,網址為`http://localhost:3000` 。 ``` wing it ``` ![Wing TS 最小控制台](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1ejobkm0dq5akhut732.png) 您已在電腦上成功安裝 Wing。 --- 如何將 Wing 連接到 Next.js 應用程式 ------------------------- 在前面的部分中,您已在`frontend`資料夾中建立了 Next.js 前端應用程式,並在`backend`資料夾中建立了 Wing 後端。 在本部分中,您將了解如何在 Next.js 應用程式和 Wing 後端之間通訊和發送資料。 首先,透過執行以下程式碼在後端資料夾中安裝[Wing React](https://github.com/winglang/winglibs/tree/main/react)函式庫: ``` npm install @winglibs/react ``` 接下來,更新`main.ts`文件,如下所示: ``` import { main, cloud, inflight, lift } from "@wingcloud/framework"; import React from "@winglibs/react"; main((root, test) => { const api = new cloud.Api(root, "api", { cors: true }) ; //👇🏻 create an API route api.get( "/test", inflight(async () => { return { status: 200, body: "Hello world", }; }) ); //👉🏻 placeholder for the POST request endpoint //👇🏻 connects to the Next.js project const react = new React.App(root, "react", { projectPath: "../frontend" }); //👇🏻 an environment variable react.addEnvironment("api_url", api.url); }); ``` 上面的程式碼片段建立了一個 API 端點 ( `/test` ),它接受 GET 請求並傳回`Hello world`文字。 `main`函數也連接到 Next.js 專案並將`api_url`新增為環境變數。 環境變數中包含的 API URL 使我們能夠將請求傳送到 Wing API 路由。我們如何在 Next.js 應用程式中檢索 API URL 並發出這些請求? 更新 Next.js `app/layout.tsx`檔案中的`RootLayout`元件,如下所示: ``` export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang='en'> <head> {/** ---👇🏻 Adds this script tag 👇🏻 ---*/} <script src='./wing.js' defer /> </head> <body className={inter.className}>{children}</body> </html> ); } ``` 透過執行`npm run build`重新建置 Next.js 專案。 最後,啟動Wing開發伺服器。它會自動啟動 Next.js 伺服器,可以在瀏覽器中透過**`http://localhost:3001`**存取該伺服器。 ![控制台到 URL](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7rkxw9bds97a0qzg5vh.gif) 您已成功將 Next.js 連接到 Wing。您也可以使用`window.wingEnv.<attribute_name>`存取環境變數中的資料。 ![視窗.wingEnv](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0up5430jmxufmyeb9e4h.gif) 使用LangChain和Wing處理用戶請求 ---------------------- 在本節中,您將學習如何向 Wing 發送請求,使用[LangChain 和 OpenA](https://js.langchain.com/docs/get_started/quickstart#llm-chain) I 處理這些請求,並在 Next.js 前端顯示結果。 首先,我們更新 Next.js **`app/page.tsx`**檔案以檢索 API URL 並將使用者資料傳送到 Wing API 端點。 為此,請透過在**`page.tsx`**檔案頂部新增以下程式碼片段來擴充 JavaScript **`window`**物件。 ``` "use client"; import { useState } from "react"; interface WingEnv { api_url: string; } declare global { interface Window { wingEnv: WingEnv; } } ``` 接下來,更新`handleUserQuery`函數以將包含使用者問題和網站URL 的POST 請求傳送到Wing API 端點。 ``` //👇🏻 sends data to the api url const [response, setResponse] = useState<string | null>(null); const handleUserQuery = async (e: React.FormEvent) => { e.preventDefault(); setDisable(true); try { const request = await fetch(`${window.wingEnv.api_url}/api`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ question, pageURL: documentationURL }), }); const response = await request.text(); setResponse(response); setDisable(false); } catch (err) { console.error(err); setDisable(false); } }; ``` 在建立接受 POST 請求的 Wing 端點之前,請在`backend`資料夾中安裝下列套件: ``` npm install @langchain/community @langchain/openai langchain cheerio ``` [Cheerio](https://js.langchain.com/v0.2/docs/integrations/document_loaders/web_loaders/web_cheerio/)使我們能夠抓取軟體文件網頁,而[LangChain 軟體包](https://js.langchain.com/v0.1/docs/get_started/quickstart/)使我們能夠存取其各種功能。 LangChain OpenAI整合包使用OpenAI語言模型;因此,您需要一個有效的 API 金鑰。您可以從[OpenAI 開發者平台](https://platform.openai.com/api-keys)取得。 ![朗查恩](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omg4o524oklrssso5rqc.png) 接下來,讓我們建立處理傳入請求的`/api`端點。 端點將: - 接受來自 Next.js 應用程式的問題和文件 URL, - 使用[LangChain 文件載入器](https://js.langchain.com/v0.1/docs/modules/data_connection/document_loaders/)載入文件頁面, - 將檢索到的文件分成區塊, - 轉換分塊文件並將它們保存在[LangChain 向量儲存](https://js.langchain.com/v0.1/docs/modules/data_connection/vectorstores/)中, - 並建立一個[檢索器函數](https://js.langchain.com/v0.1/docs/modules/data_connection/),從向量儲存中檢索文件。 首先,將以下內容匯入`main.ts`檔案: ``` import { main, cloud, inflight, lift } from "@wingcloud/framework"; import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai"; import { ChatPromptTemplate } from "@langchain/core/prompts"; import { createStuffDocumentsChain } from "langchain/chains/combine_documents"; import { CheerioWebBaseLoader } from "@langchain/community/document_loaders/web/cheerio"; import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"; import { MemoryVectorStore } from "langchain/vectorstores/memory"; import { createRetrievalChain } from "langchain/chains/retrieval"; import React from "@winglibs/react"; ``` 在`main()`函數中加入以下程式碼片段以建立`/api`端點: ``` api.post( "/api", inflight(async (ctx, request) => { //👇🏻 accept user inputs from Next.js const { question, pageURL } = JSON.parse(request.body!); //👇🏻 initialize OpenAI Chat for LLM interactions const chatModel = new ChatOpenAI({ apiKey: "<YOUR_OPENAI_API_KEY>", model: "gpt-3.5-turbo-1106", }); //👇🏻 initialize OpenAI Embeddings for Vector Store data transformation const embeddings = new OpenAIEmbeddings({ apiKey: "<YOUR_OPENAI_API_KEY>", }); //👇🏻 creates a text splitter function that splits the OpenAI result chunk size const splitter = new RecursiveCharacterTextSplitter({ chunkSize: 200, //👉🏻 characters per chunk chunkOverlap: 20, }); //👇🏻 creates a document loader, loads, and scraps the page const loader = new CheerioWebBaseLoader(pageURL); const docs = await loader.load(); //👇🏻 splits the document into chunks const splitDocs = await splitter.splitDocuments(docs); //👇🏻 creates a Vector store containing the split documents const vectorStore = await MemoryVectorStore.fromDocuments( splitDocs, embeddings //👉🏻 transforms the data to the Vector Store format ); //👇🏻 creates a document retriever that retrieves results that answers the user's questions const retriever = vectorStore.asRetriever({ k: 1, //👉🏻 number of documents to retrieve (default is 2) }); //👇🏻 creates a prompt template for the request const prompt = ChatPromptTemplate.fromTemplate(` Answer this question. Context: {context} Question: {input} `); //👇🏻 creates a chain containing the OpenAI chatModel and prompt const chain = await createStuffDocumentsChain({ llm: chatModel, prompt: prompt, }); //👇🏻 creates a retrieval chain that combines the documents and the retriever function const retrievalChain = await createRetrievalChain({ combineDocsChain: chain, retriever, }); //👇🏻 invokes the retrieval Chain and returns the user's answer const response = await retrievalChain.invoke({ input: `${question}`, }); if (response) { return { status: 200, body: response.answer, }; } return undefined; }) ); ``` API 端點接受使用者的問題和來自 Next.js 應用程式的頁面 URL,初始化[`ChatOpenAI`](https://js.langchain.com/v0.2/docs/integrations/chat/openai/)和[`OpenAIEmbeddings`](https://js.langchain.com/v0.2/docs/integrations/text_embedding/openai/) ,載入文件頁面,並以文件的形式檢索使用者查詢的答案。 然後,將文件分割成區塊,將區塊保存在`MemoryVectorStore`中,並使我們能夠使用[LangChain 檢索器](https://js.langchain.com/v0.1/docs/modules/data_connection/)來取得問題的答案。 從上面的程式碼片段來看,OpenAI API金鑰直接輸入到程式碼中;這可能會導致安全漏洞,使 API 金鑰可供攻擊者存取。為了防止這種資料洩露,Wing 允許您將私鑰和憑證保存在名為`secrets`的變數中。 當您建立機密時,Wing 會將此資料保存在`.env`檔案中,確保其安全且可存取。 更新`main()`函數以從 Wing Secret 取得 OpenAI API 金鑰。 ``` main((root, test) => { const api = new cloud.Api(root, "api", { cors: true }); //👇🏻 creates the secret variable const secret = new cloud.Secret(root, "OpenAPISecret", { name: "open-ai-key", }); api.post( "/api", lift({ secret }) .grant({ secret: ["value"] }) .inflight(async (ctx, request) => { const apiKey = await ctx.secret.value(); const chatModel = new ChatOpenAI({ apiKey, model: "gpt-3.5-turbo-1106", }); const embeddings = new OpenAIEmbeddings({ apiKey, }); //👉🏻 other code snippets & configurations ); const react = new React.App(root, "react", { projectPath: "../frontend" }); react.addEnvironment("api_url", api.url); }); ``` - 從上面的程式碼片段來看, ``` - The `secret` variable declares a name for the secret (OpenAI API key). ``` ``` - The [`lift().grant()`](https://www.winglang.io/docs/typescript/inflights#permissions) grants the API endpoint access to the secret value stored in the Wing Secret. ``` ``` - The [`inflight()`](https://www.winglang.io/docs/typescript/inflights) function accepts the context and request object as parameters, makes a request to LangChain, and returns the result. ``` ``` - Then, you can access the `apiKey` using the `ctx.secret.value()` function. ``` 最後,透過在終端機中執行此命令將 OpenAI API 金鑰儲存為機密。 ![翅膀的秘密](https://www.winglang.io/assets/images/qa-bot-wing-secrets-883db5e81515894ae280d77b7f72bb25.gif) 恭喜!您已成功完成本教學的專案。 以下是該應用程式的簡短演示: ![QA 機器人演示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ropklqge2xzpibl29vye.gif) --- 讓我們更深入地研究 Wing 文件,看看我們的 AI 機器人可以提取哪些資料。 ![QA 機器人演示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnmf6n6mszc6go0uiw1v.gif) --- 總結一下 ---- 到目前為止,我們已經討論了以下內容: - 什麼是翼? - 如何使用Wing並使用Langchain查詢資料, - 如何將 Wing 連接到 Next.js 應用程式, - 如何在 Next.js 前端和 Wing 後端之間發送資料。 > [Wing](https://github.com/winglang/wing)旨在恢復您的創意流並縮小想像力與創造之間的差距。 Wing 的另一個巨大優勢是它是開源的。因此,如果您希望建立利用雲端服務的分散式系統或為雲端開發的未來做出貢獻, [Wing](https://github.com/winglang/wing)是您的最佳選擇。 請隨意為[GitHub 儲存庫做出貢獻,](https://github.com/winglang/wing)並與團隊和大型開發人員社群[分享您的想法](https://t.winglang.io/discord)。 本教學的源程式碼可[在此處](https://github.com/NathanTarbert/wing-langchain-nextjs)取得。 感謝您的閱讀! 🎉 --- 原文出處:https://dev.to/winglang/build-a-qa-bot-for-your-documentation-with-langchain-27i4

17 個讓我保持高效率的開發者工具

許多開發人員喜歡從頭開始建立東西,但有時工作量太大,使用這些工具可以讓工作變得更容易。 這裡包含一系列工具,因此我相信您會找到適合您需求的工具。 我無法涵蓋所有內容,但如果您知道其他很棒的工具,請隨時在評論中告訴我! 我們開始做吧。 --- 1. [Taipy](https://github.com/Avaiga/taipy) - 資料和人工智慧演算法融入生產級網路應用程式。 -------------------------------------------------------------------- ![打字](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wd10iiofzmt4or4db6ej.png) 通常,當我需要 Python 介面時,我會使用 Streamlit。然而,它的效率不是很高,並且存在許多基於效能的問題。 另一方面,Taipy(開源)是用於輕鬆、端到端應用程式開發的完美 Python 程式庫,具有假設分析、智慧管道執行、內建調度和部署工具。 需要明確的是,Taipy 用於為基於 Python 的應用程式建立 GUI 介面並改進資料流管理。 關鍵是性能,而 Taipy 是最佳選擇。 雖然 Streamlit 是一種流行的工具,但正如我之前告訴您的那樣,它的性能可能會顯著下降,尤其是在處理大型資料集時,這使得它對於生產級使用來說不切實際。 另一方面,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://docs.taipy.io/en/release-3.1/gallery/)其中包含程式碼和適當的文件供您遵循。我將詳細討論其中一些專案! ![示範](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wigid2aokt6spkkoivr.png) 這些用例令人驚嘆,因此請務必查看一些演示應用程式。 Taipy 還在其企業版中提供了 Designer 應用程式(拖放低程式碼編輯器)。它非常有用,您可以觀看下面的演示來了解它是如何工作的! {% 嵌入 https://www.youtube.com/watch?v=y3VPT6IPvC4 %} Taipy 在 GitHub 上有 9.2k+ 顆星,並且處於`v3.1`版本,因此它們正在不斷改進。 {% cta https://github.com/Avaiga/taipy %} 明星 Taipy ⭐️ {% endcta %} --- 2. [Jam](https://jam.dev/) - 一鍵錯誤報告。 ------------------------------------ ![果醬](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tn2c6djsj5hej0gj07xs.png) 幾個月前我發現了 Jam,並且用過它好幾次。 Jam 是一款免費的 Chrome 擴充功能(非開源),您可以使用它來有效地報告錯誤。當然,您還可以做更多的事情。 報告錯誤是一個漫長的過程,您最終可能會錯過解決該錯誤所需的基本資料。這就是開發人員更喜歡使用 Jam 的原因。 觀看此影片,了解 Jam 的工作原理! {% 嵌入 https://www.youtube.com/watch?v=iXjmUwZLzVs&amp;embeds\_referring\_euri=https%3A%2F%2Fchromewebstore.google.com%2F&amp;source\_ve\_path=OTY3MTQ&amp;feature=emb\_imp\_woyt %} 正如您所看到的,最好的部分是它捕獲控制台和網頁日誌訊息,這使得其他開發人員可以方便地查看它。 您還將獲得人工智慧除錯器、後端追蹤、重現步驟和瀏覽器資訊。您還需要什麼? ![即興開發](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2tpffk9h60skslw8i0b.png) 我已經使用 Jam 很長時間了,因此您還將獲得一個儀表板來查看您迄今為止建立的所有 Jam。它非常高效並且效果非常好。 ![儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t01buvno1r7pfrolfu6k.png) 它還可以與許多流行的工具一起使用,因此您根本不必改變您的環境。 ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gr566uwdcmors2yvkfcb.png) 不要使用傳統的方式,您可以簡單地對 Jam 進行評論並改進整個流程來輕鬆處理它。 --- 3. [DevGPT](https://www.getdevkit.com/devgpt) - 開發者的人工智慧助理。 ----------------------------------------------------------- ![開發組](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8k8a8jyeo9qkj2hqmc4n.png) 我已經使用 DevGPT 很久了,尤其是當 ChatGPT 還很新的時候。我曾經反覆核對訊息,看看它是否正確。我不相信 ChatGPT 和用於它的訓練資料。 您會驚訝地發現,在某些情況下 DevGPT 比 ChatGPT 更好。但這並不是 DevGPT 的唯一用例。 他們提供了一系列可以直接使用的提示。您可以修改它們的結構並使用斜線命令來使用它。 ![提示結構](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fc74vge21d65nbpauig.png) ![提示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yhl7o1grjvcg9q1fee5.png) 範例提示 ![提示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0y51yi3t4s0a54tw0jrs.png) 範例提示 DevGPT 與其他人工智慧助理的獨特之處在於它提供了許多有用的迷你工具。 ![迷你工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il3qcaykt4k9x612251n.png) 我使用最多的是響應式設計,它有助於同時在所有螢幕上查看任何網站預覽。 ![響應式設計](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nodp7fbhagwqavd5ud5h.png) 響應式設計 每個工具本身都是完整的,因此您不會得到任何不完整的東西。我相信這實際上可以改善您的工作流程條件。 ![日期檢查員](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1q5bau21dd8dqaqbu4c.png) 日期檢查員 --- 4. [DevToys](https://github.com/DevToys-app/DevToys) - 開發者的瑞士軍刀。 ---------------------------------------------------------------- ![開發玩具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7zfl1wjr01fdvca6wxbi.png) DevToys 協助完成日常開發任務,例如格式化 JSON、比較文字和測試 RegExp。 用例是相同的,但 DevToys 提供了更多選項,而且它是一個離線工具,這是一個優點。 這樣,就無需使用不可信的網站來處理您的資料執行簡單的任務。透過智慧型偵測,DevToys 可以偵測用於複製到 Windows 剪貼簿的資料的最佳工具。 緊湊的覆蓋範圍讓您可以保持應用程式較小並位於其他視窗之上。最好的部分是可以同時使用該應用程式的多個實例。 我可以肯定地說,很多開發人員從來不知道這件事。 我很高興地說它是專為 Windows 生態系統設計的軟體。哈哈! ![工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7wd60jsgdb5tx2t2adi.png) 他們提供的一些工具是: > 轉換器 - JSON &lt;&gt; YAML - 時間戳 - 數基數 - 規劃任務解析器 ![轉換器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g8x784fx53x6ia02zal0.png) > 編碼器/解碼器 - 超文本標記語言 - 網址 - Base64 文字與圖片 - 壓縮包 - 智威湯遜解碼器 ![編碼器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73ts4x1vtcy4yswsmytw.png) > 格式化程式 - JSON - SQL - XML ![XML](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5dc8ko2baywta82ymq5.png) > 發電機 - 哈希(MD5、SHA1、SHA256、SHA512) - UUID 1 和 4 - 洛雷姆·伊普蘇姆 - 校驗和 ![發電機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwsq8xig6jf69wr99iuv.png) > 文字 - 逃脫/逃脫 - 檢驗員和箱子轉換器 - 正規表示式測試器 - 文字比較 - XML驗證器 - 降價預覽 ![MD預覽](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vcbkse1i5324qg3xu1yd.png) ![文字差異](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hlqqib4fcjimc03pdrwr.png) > 形象的 - 色盲模擬器 - 顏色選擇器和對比度 - PNG / JPEG 壓縮器 - 影像轉換器 ![圖形工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/631upekcqzh62xyrdjwt.png) 我不了解你,但我不會錯過這個! 您可以閱讀[如何執行 DevToys](https://github.com/DevToys-app/DevToys?tab=readme-ov-file#how-to-run-devtoys) 。 > 關於許可證的註解。 DevToys 使用的授權允許將應用程式作為試用軟體或共享軟體重新分發而無需進行任何更改。然而,作者 Etienne BAUDOUX 和 BenjaminT 不希望你這樣做。如果您認為自己有充分的理由這樣做,請先與我們聯絡討論。 他們在 GitHub 上擁有超過 23,500 顆星,並使用 C#。 {% cta https://github.com/DevToys-app/DevToys %} 明星 DevToys ⭐️ {% endcta %} --- 5. [Linear-](https://github.com/linear)任務管理工具。 ---------------------------------------------- ![線性](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zlvr12b9untwos846i2.png) 我之前嘗試過使用 Trello 或 Jira 等工具,我想說線性絕對值得。 Jira 似乎有點複雜,適合大型團隊。 Linear 是開源的,是簡化問題、專案和產品路線圖的最佳方法之一。它是一種管理工具,我們都需要它來了解正在發生的事情以及未來的計劃。 ![工作管理](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gbno2672e69ofqonsob3.png) 您還可以獲得一個全域命令選單,可以幫助您更快地完成操作。作為開發人員,我們都喜歡這一點! 它們提供了一系列很酷的功能,例如自動跟踪,這可確保將啟動的問題加入到當前週期中。您還將收到有關有風險週期的警告,這可以幫助預測延誤。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o3bi4fgk4vp0nfc75jlc.png) ![線性](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pfl0onb6rmiepiu1ibns.png) ![循環](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eb7tpqvlbxyhkwzkroyj.png) 您可以看到[25+ 個完整功能](https://linear.app/features)的清單。您還可以了解[他們的整個旅程](https://linear.app/readme)。 如果您喜歡觀看影片,可以觀看此影片,其中涵蓋了有關線性的大部分基本內容。 {% 嵌入 https://youtu.be/oh2AfSFe0H0 %} 它有一個針對 2 個團隊的免費套餐計劃,這足以讓您嘗試一下並看看它們是否合適。 Linear 在主儲存庫上有 650 顆星,是使用 TypeScript 建構的。 {% cta https://github.com/linear %} 星線性 ⭐️ {% endcta %} --- 6. [Pieces](https://github.com/pieces-app) - 您的工作流程副駕駛。 ------------------------------------------------------- ![件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qf2qgqtpv78fxw5guqm5.png) Pieces 是一款 AI 生產力工具,旨在透過智慧程式碼片段管理、情境化副駕駛互動和主動呈現有用材料來幫助開發人員管理混亂的工作流程。 它改善了您的工作流程和整體開發體驗,同時透過完全離線的 AI 方法保持工作的隱私和安全。 實時上下文的最新概念使其更上一層樓。您可以觀看引起熱議的演示! {% 嵌入 https://www.youtube.com/watch?v=aP8u95RTCGE %} 有了這個,Pieces Copilot+ 現在可以提供高度感知的幫助,引導您回到上次離開的地方。 - 問它, `What was I working on an hour ago?`並讓它幫助你重新進入心流狀態。 - 問一下, `How can I resolve the issue I got with Cocoa Pods in the terminal in IntelliJ?` - 或者`What did Mack say I should test in the latest release?` 。 Copilot 可以顯示您知道自己擁有但不記得在哪裡的資訊。 ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2ro3rcwnqp4qrmv5e8s.png) 它與您最喜歡的工具無縫集成,以簡化、理解和提升您的編碼流程。 它具有比表面上看到的更令人興奮的功能。 ✅ 它可以透過閃電般的搜尋體驗找到您需要的資料,讓您可以根據您的喜好透過自然語言、程式碼、標籤和其他語義進行查詢。可以放心地說“您的個人離線谷歌”。 ✅ Pieces 使用 OCR 和 Edge-ML 升級螢幕截圖,以提取程式碼並修復無效字元。因此,您可以獲得極其準確的程式碼提取和深度元資料豐富。 您可以查看 Pieces 可用[功能的完整清單](https://pieces.app/features/?utm_source=anmol&utm_medium=cpc&utm_campaign=anmol-article)。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysluzx8qtyaqrtnp4fld.png) ![分享程式碼片段](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wz4xtesz5empxatxju1l.png) 您可以閱讀[文件](https://docs.pieces.app/?utm_source=anmol&utm_medium=cpc&utm_campaign=anmol-article)並存取[網站](https://pieces.app/)。 它還允許您捕獲程式碼片段,您可以在編輯現有程式碼或處理新專案時將其用作參考。這對於開源開發人員來說非常方便。 ✅ 在應用程式中保存部分程式碼。 ✅ 輕鬆存取已儲存的程式碼片段。 ✅ 從網路貼上程式碼。 ✅ 與您的團隊分享您的程式碼。 他們為 Pieces OS 用戶端提供了一系列 SDK 選項,包括[TypeScript](https://github.com/pieces-app/pieces-os-client-sdk-for-typescript) 、 [Kotlin](https://github.com/pieces-app/pieces-os-client-sdk-for-kotlin) 、 [Python](https://github.com/pieces-app/pieces-os-client-sdk-for-python)和[Dart](https://github.com/pieces-app/pieces-os-client-sdk-for-dart) 。 就開源流行度而言,他們仍然是新的,但他們的社群是迄今為止我見過的最好的社群之一。加入他們,成為 Pieces 的一部分! {% cta https://github.com/pieces-app/ %} 星星碎片 ⭐️ {% endcta %} --- 7.[螢幕截圖到程式碼](https://github.com/abi/screenshot-to-code)- 放入螢幕截圖並將其轉換為乾淨的程式碼。 --------------------------------------------------------------------------- ![截圖到程式碼](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5akiyz5telxqqsj32ftu.png) 這個開源專案廣泛流行,但許多開發人員仍然不了解它。這可以幫助您以 10 倍的速度建立使用者介面。 這是一個簡單的工具,可以使用 AI 將螢幕截圖、模型和 Figma 設計轉換為乾淨、實用的程式碼。 該應用程式有一個 React/Vite 前端和一個 FastAPI 後端。如果您想使用 Claude Sonnet 或獲得實驗視訊支持,您將需要一個能夠存取 GPT-4 Vision API 的 OpenAI API 金鑰或一個 Anthropic 金鑰。您可以閱讀[指南](https://github.com/abi/screenshot-to-code?tab=readme-ov-file#-getting-started)來開始。 您可以在託管版本上[即時試用](https://screenshottocode.com/),並觀看 wiki 上提供的[一系列演示影片](https://github.com/abi/screenshot-to-code/wiki/Screen-Recording-to-Code)。 他們在 GitHub 上擁有超過 52k 顆星,並支援許多技術堆疊,例如 React 和 Vue,以及不錯的 AI 模型,例如 GPT-4 Vision、Claude 3 Sonnet 和 DALL-E 3。 {% cta https://github.com/abi/screenshot-to-code %} 將螢幕截圖轉為程式碼 ⭐️ {% endcta %} --- 8. [Silver Searcher](https://github.com/ggreer/the_silver_searcher) - 超快速的程式碼庫搜尋工具。 ----------------------------------------------------------------------------------- ![銀色搜尋者](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/41z8goks4ag2opm0ynvp.png) 許多開源專案都有開發人員多年來建立的大型程式碼庫。顯然,有人無法一次理解所有內容,這就是這個工具的用武之地。 Silver Searcher(開源),通常縮寫為 Ag,是一種快速且有效率的程式碼搜尋工具,專為使用大型程式碼庫的開發人員而設計。 Ag 是作為傳統 grep 命令的替代品而建置的,它利用平行性和智慧過濾來提供超快速的搜尋結果。 它最初是[Ack](https://github.com/beyondgrep/ack3)的克隆,但速度快了 5 到 10 倍。您可以閱讀[為什麼它這麼快](https://github.com/ggreer/the_silver_searcher?tab=readme-ov-file#how-is-it-so-fast)。 它有很多很酷的功能,例如: ✅ 多執行緒可加快程式碼錯誤搜尋速度。 ✅ 忽略 .gitignore、.ignore 和 .hgignore 中的檔案模式以避免不必要的搜尋。 ✅ 可透過命令列選項和可下載的設定檔進行自訂。 好處是它可以與文字編輯器和 IDE 集成,以在您首選的工作流程中增強搜尋功能。 它可以根據您的開發環境在 Windows、macOS 和 Linux 上無縫執行。 您可以閱讀[安裝指南](https://github.com/ggreer/the_silver_searcher?tab=readme-ov-file#installing)。 它在 GitHub 上擁有超過 25,500 顆星,擁有 200 多名貢獻者。 唯一的問題是它不再被維護,因為最後一次提交是 4 年前的事情,並且有 400 多個活躍問題。 {% cta https://github.com/ggreer/the\_silver\_searcher %} 星銀搜尋者 ⭐️ {% endcta %} --- 9. [Obsidian](https://github.com/obsidianmd) - 根據您的風格編寫應用程式。 ------------------------------------------------------------ ![黑曜石](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/26r33zlctwpny1f7hf96.png) Obsidian 是一款私密且靈活的寫作應用程式,可適應您的思維方式。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mz0eig3tzezhm32i314m.png) ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z983u116nummmo8n16b7.png) 您也可以查看插件清單\](https://obsidian.md/plugins),它們可以幫助您塑造 Obsidian 以適應您的思維方式。我已經檢查了那裡存在的瘋狂數量的選項! ![外掛](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/voyny8k3zbh6a92u3qy4.png) 您甚至可以協作並輕鬆追蹤修訂之間的更改,每個註釋都有一年的版本歷史記錄。 ![版本歷史](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqj3sxbwh1y5t9rbwb4l.png) 您可以發布這些(我從未嘗試過)並透過主題、自訂網域、密碼保護等控制網站的外觀和風格。這是一項付費功能,但您可以閱讀有關[使用 Obsidian 發布的](https://obsidian.md/publish)所有內容。 您可以閱讀詳細[文件](https://docs.obsidian.md/Home)並查看[即時網站](https://obsidian.md/)。您也可以使用本[指南](https://docs.obsidian.md/Plugins/Getting+started/Build+a+plugin)建立自訂插件,並使用 React 或 Svelte。 根據您使用的平台下載[Obsidian](https://obsidian.md/download) 。 他們提供永久免費的套餐,並且不根據功能或使用情況收費。只有當您將 Obsidian 用於商業用途時才需要付費。 您可以嘗試的最佳替代方案之一是[Capacities](https://capacities.io/) 。在某些方面它甚至可能比黑曜石更好。我將在以後的一篇文章中介紹它。 主儲存庫在 GitHub 上有 8k+ 顆星,有 1400 多名貢獻者。開源社群的另一個很棒的專案。 {% cta https://github.com/obsidianmd/obsidian-releases %} 星黑曜石 ⭐️ {% endcta %} --- 10.[自動完成](https://github.com/withfig/autocomplete)- IDE 風格的自動完成功能適用於您現有的終端和 shell。 ---------------------------------------------------------------------------------- ![自動完成](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8i8vcidsa023jf8r9382.png) [Fig](https://fig.io/?ref=github_autocomplete)讓命令列對個人來說更容易,對團隊來說更具協作性。 他們最受歡迎的產品是自動完成。當您鍵入時,Fig 會在現有終端機中彈出子命令、選項和上下文相關的參數。 作為開發人員,我們確實需要它來最大限度地提高我們的日常生產力。 最好的部分是您也可以將 Fig 的自動完成功能用於您自己的工具。以下是建立私人完成的方法: ``` import { ai } from "@fig/autocomplete-generators" ... generators: [ ai({ // the prompt prompt: "Generate a git commit message", // Send any relevant local context. message: async ({ executeShellCommand }) => { return executeShellCommand("git diff") }, //Turn each newline into a suggestion (can specify instead a `postProcess1 function if more flexibility is required) splitOn: "\n", }) ] ``` 您可以閱讀[Fig.io/docs](https://fig.io/docs/getting-started)了解如何開始。 您可以觀看下面的演示來了解它是如何工作的! ![影像](https://camo.githubusercontent.com/c477525cab041ce8177323e8140aa872341e3b8130d61454b89ccae87d00d87b/68747470733a2f2f646f63732e6177732e616d617a6f6e2e636f6d2f696d616765732f616d617a6f6e712f6c61746573742f71646576656c6f7065722d75672f696d616765732f636f6d6d616e642d6c696e652d636f6d706c6574696f6e732e676966) 它們在 GitHub 上有 24k+ 顆星,對於經常使用 shell 或終端機的開發人員很有用。 {% cta https://github.com/withfig/autocomplete %} 星狀自動完成 ⭐️ {% endcta %} --- 11. [Excalidraw](https://github.com/excalidraw/excalidraw) - 線上白板,讓您的想法得以實現。 ---------------------------------------------------------------------------- ![外畫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u691s86xjinjvehmun51.png) 向遠距工作的過渡讓我懷念使用記號筆和白板進行腦力激盪的簡單性。 我們知道,當語言無法表達時,視覺效果可以彌補理解複雜想法的差距。 Excalidraw(開源)以數位方式重新建立白板體驗,對於補充無聊文字的快速圖表或插圖來說具有無價的價值。您可以建立漂亮的手繪圖表、線框圖或任何您喜歡的內容。 ![外畫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ki8wave2sgy3mikv4nec.png) 作為開發人員,對我來說最好的部分是您可以安裝 Excalidraw npm 套件以將 Excalidraw 整合到我自己的應用程式中。哇! ``` npm install react react-dom @excalidraw/excalidraw ``` 一些很棒的功能是: ✅ 本地化 (i18n) 支援。 ✅ 匯出到 PNG、SVG 和剪貼簿。 ✅ 多種工具 - 長方形、圓形、菱形、箭頭、線條、自由繪製、橡皮擦... ✅ 撤銷/重做。 ✅ PWA 支援(離線工作)。 ✅ 即時協作。 ✅ 本機優先支援(自動儲存至瀏覽器)。 ✅ 可分享連結(匯出至可與他人分享的唯讀連結)。 ![exalidraw 具有大螢幕功能](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru356oc83ll9mo4dhjd5.png) Google Cloud、Meta、CodeSandbox、Notion 和 Replit 等產品整合了 Excalidraw,賦予其巨大的可信度。 您可以閱讀[文件](https://docs.excalidraw.com/docs/introduction/development)並檢查[excalidraw 編輯器](https://excalidraw.com/)。 他們甚至有一套迷你的人工智慧功能,並支援從美人魚轉換,這非常有幫助。 ![人工智慧特點](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ihl90jf222ahtymec8ui.png) 團隊提供了一個[即時編輯器](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/customizing-styles),如果您不想在本地執行,您可以直接檢查任何類型的變更。讓我著迷的是,有些團隊工作非常努力,因此開發人員的體驗是一流的。 ![即時編輯器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob848loog24milg0h2uv.png) 儘管它是免費使用的,但他們提供了增強版本,因此您可以檢查[付費計劃和免費計劃之間的差異](https://plus.excalidraw.com/excalidraw-plus-vs-excalidraw/)。 說實話,我從來沒有真正想過這會是開源的。但它非常受歡迎,GitHub 上有超過 74,000 顆星,有 1,300 多個活躍問題。 {% cta https://github.com/excalidraw/excalidraw %} 明星 Excalidraw ⭐️ {% endcta %} --- 12. [Mintlify](https://github.com/mintlify/writer) - 在建置時出現的文件。 --------------------------------------------------------------- ![精簡](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gvk07kmn8p48cpssogov.png) 我們都知道在程式碼中建立文件非常重要,這樣我們就可以了解稍後發生的情況。但這是一個漫長的過程,而且大多數時候我們都懶得這麼做。 這就是 Mintlify 作為人工智慧文件編寫者可以幫助您在短短 1 秒內記錄程式碼的地方。哇! 幾個月前我發現了 Mintlify,從那時起我就一直是它的粉絲。 正如我們在該公司的大多數網站上看到的那樣,他們還為任何專案提供完整的文件。我見過很多公司使用它,甚至我使用我的商務電子郵件產生了完整的文件,結果證明這是非常簡單和體面的。如果您想要這些文件,Mintlify 就是解決方案。 ![副駕駛套件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7obg1a3hilqx47h6nw3o.png) copilotkit 文件也由 Mintlify 提供支持 我們在這裡要討論的主要用例是根據程式碼產生文件。當您編寫程式碼時,它會自動記錄程式碼,以便其他人更容易跟上。 您可以安裝[VSCode 擴充功能](https://marketplace.visualstudio.com/items?itemName=mintlify.document)或將其安裝在[IntelliJ](https://plugins.jetbrains.com/plugin/18606-mintlify-doc-writer)上。 您只需突出顯示程式碼或將遊標放在要記錄的行上。然後點選「編寫文件」按鈕(或按 ⌘ + 。) 您可以閱讀[文件](https://github.com/mintlify/writer?tab=readme-ov-file#%EF%B8%8F-mintlify-writer)和[安全指南](https://writer.mintlify.com/security)。 如果您更喜歡教程,那麼您可以觀看[Mintlify 的工作原理](https://www.loom.com/embed/3dbfcd7e0e1b47519d957746e05bf0f4)。它支援 10 多種程式語言,並支援許多文件字串格式,例如 JSDoc、reST、NumPy 等。 順便說一句,他們的網站連結是[writer.mintlify.com](https://writer.mintlify.com/) ;回購協議中目前的似乎是錯誤的。 Mintlify 是一個方便的工具,用於記錄程式碼,這是每個開發人員都應該做的事情。它使其他人更容易有效地理解您的程式碼。 它在 GitHub 上有大約 2.5k 顆星,基於 TypeScript 建置,受到許多開發人員的喜愛。 {% cta https://github.com/mintlify/writer %} Star Mintlify ⭐️ {% endcta %} --- 13. [Focusmate](https://www.focusmate.com/) - 虛擬協同辦公,可以完成任何事情。 -------------------------------------------------------------- ![焦點伴侶](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bwxmwxio6jq7bw2mw10j.png) 儘管我們盡量不拖延,但在編碼期間我們總是擔心拖延。對於這些情況,Focusmate 是完美的解決方案! 這是一個共同工作的虛擬社區,您會在其中分配一位合作夥伴,確保您專注於自己的任務。 您需要與其他 Focusmate 用戶預訂會議。確定何時預訂課程後,您可以存取 Focusmate 儀表板。在那裡,您將看到一個日曆,其中包含其他使用者的可用會話時間。 ![怎麼運作的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bqjf66nrzrdjyccc6gl.png) 要與其他人預訂會議,您只需點擊日曆中的個人資料圖片,然後選擇與他們預訂會議。 ![儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/21pudw9jdj90uup92k4j.png) 一旦您這樣做,Focusmate 就會推薦幾個可用使用者供您選擇。 重點是它允許[安靜模式](https://support.focusmate.com/en/articles/8060080-session-settings-my-task-quiet-mode-and-partner),在這種模式下,人們沒有麥克風或無法說話(想想圖書館和共享空間)。 ![靜音模式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vav48ckhnn2dhikx19ju.png) 就我個人而言,我沒有嘗試過很多次,但它有一個很大的社區,所以值得一試。 --- 14. [Spark Mail](https://sparkmailapp.com/) - 優化您的電子郵件管理。 --------------------------------------------------------- ![火花郵件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/824r33nf4lc8p28fkoyp.png) Spark(非開源)不僅僅是一個電子郵件用戶端。這是關於人們應該如何溝通和組織工作的哲學。 Spark 的目標是幫助您專注於重要的事情並實現收件匣之外的目標。 他們首先使電子郵件變得智能,然後改進了團隊協作,現在他們已經解決了資訊過載問題,使電子郵件變得聚焦。 觀看快速演示,了解 Spark 的工作原理! {% 嵌入 https://www.youtube.com/watch?v=l2QpqNw3zXU&amp;t=3s %} 我喜歡 Spark 的一些很酷的功能: ✅ 您可以設定電子郵件稍後返回收件匣的時間。 ✅ 您可以新增提醒來提示您跟進。 ✅ 您可以安排電子郵件的發送時間。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/czr3jmfmkhmqj7yd264k.png) ✅ 您也可以與您的團隊合作: - 在同一地址下管理電子郵件和團隊角色。 - 即時一起撰寫電子郵件草稿。 - 將任務分配給同事並追蹤他們的狀態。 ✅ 您甚至可以將電子郵件變成帶有私人評論的聊天。 ![合作](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v7p0vdhd7vh5s72qjgub.png) 我知道你想知道人工智慧,所以它有很多功能,你可以讓人工智慧為你起草電子郵件或獲得一堆回覆選項。 ![你有回覆](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vyux9mn1wc0h5bde3w9l.png) 更好的是,您可以校對、調整語氣、改寫、擴展或縮短文本,等等。 ![已編輯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yxs7vejau2h96ell5dr.png) 但我最喜歡的是建立電子郵件簽名的選項,因為簡單的選項並不那麼有效。 ![電子郵件簽名](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rhq44742us4lity50jig.png) 您可以查看[定價計劃](https://sparkmailapp.com/plans-comparison),其中包括足夠好的免費套餐,然後下載[Spark for Windows](https://sparkmailapp.com/windows) 。也請查看他們的[部落格](https://sparkmailapp.com/blog)和[電子郵件指南](https://sparkmailapp.com/how-to)以了解更多資訊。 儘管我喜歡人工智慧,但我不喜歡人工智慧為我建立電子郵件草稿。我比較喜歡自己做,哈哈! 不管怎樣,Spark 絕對是一種有趣的電子郵件管理方式。嘗試一下並讓我知道效果如何。 如果您正在尋找替代方案,我推薦[Inbox Zero](https://github.com/elie222/inbox-zero) ,它是開源的,我已經在我的一篇文章中介紹過,以及 SaneBox (https://www.sanebox.com/),我沒有介紹它因為它沒有免費套餐。 --- 15. [n8n](https://github.com/n8n-io/n8n) - 工作流程自動化工具。 ----------------------------------------------------- ![n8n](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4pqsc84nhgj0b9dhfaxo.png) n8n 是一個可擴展的工作流程自動化工具。透過公平程式碼分發模型,n8n 將始終擁有可見的原始程式碼,可用於自託管,並允許您加入自訂函數、邏輯和應用程式。 每個開發人員都想使用的工具。畢竟,自動化是生產力和簡單性的關鍵。 ![n8n](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rxnp57kw5szbpj6mfs1p.png) n8n 基於節點的方法使其具有高度通用性,使您能夠將任何事物連接到任何事物。 有[400 多個集成選項](https://n8n.io/integrations),這幾乎是瘋狂的! 您可以看到所有[安裝](https://docs.n8n.io/choose-n8n/)選項,包括 Docker、npm 和自架。 開始使用以下命令。 ``` npx n8n ``` 此命令將下載啟動 n8n 所需的所有內容。然後,您可以透過開啟`http://localhost:5678`來存取 n8n 並開始建置工作流程。 在 YouTube 上觀看此[快速入門影片](https://www.youtube.com/watch?v=1MwSoB0gnM4)! {% 嵌入 https://www.youtube.com/watch?v=1MwSoB0gnM4 %} 您可以閱讀[文件](https://docs.n8n.io/)並閱讀本[指南](https://docs.n8n.io/try-it-out/),根據您的需求快速開始。 他們還提供初學者和中級[課程,](https://docs.n8n.io/courses/)以便輕鬆學習。 他們在 GitHub 上有 41k+ 顆星,並提供兩個包供整體使用。 {% cta https://github.com/n8n-io/n8n %} 明星 n8n ⭐️ {% endcta %} --- 16. [Infisical](https://github.com/Infisical/infisical) - 秘密管理平台。 ----------------------------------------------------------------- ![內部的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrolzjdnkky1r694h9av.png) Infisical 是一個開源秘密管理平台,團隊可以用它來集中 API 金鑰、資料庫憑證和設定等秘密。 他們讓每個人(而不僅僅是安全團隊)都可以更輕鬆地進行秘密管理,這意味著從頭開始重新設計整個開發人員體驗。 就我個人而言,我不介意使用 .env 文件,因為我並不特別謹慎。不過,您可以閱讀[立即停止使用 .env 檔案!](https://dev.to/gregorygaines/stop-using-env-files-now-kp0)由格雷戈里來理解。 他們提供了四種 SDK,分別用於<a href="">Node.js</a> 、 <a href="">Python</a> 、 <a href="">Java</a>和<a href="">.Net</a> 。您可以自行託管或使用他們的雲端。 開始使用以下 npm 指令。 ``` npm install @infisical/sdk ``` 這是使用入門 (Node.js SDK) 的方法。 ``` import { InfisicalClient, LogLevel } from "@infisical/sdk"; const client = new InfisicalClient({ clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", logLevel: LogLevel.Error }); const secrets = await client.listSecrets({ environment: "dev", projectId: "PROJECT_ID", path: "/foo/bar/", includeImports: false }); ``` ![內部](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h3eu288l470du91b66pd.png) Infisical 還提供了一組工具來自動防止 git 歷史記錄的秘密洩露。可以使用預提交掛鉤或透過與 GitHub 等平台直接整合在 Infisical CLI 層級上設定此功能。 您可以閱讀[文件](https://infisical.com/docs/documentation/getting-started/introduction)並檢查如何[安裝 CLI](https://infisical.com/docs/cli/overview) ,這是使用它的最佳方式。 Infisical 還可用於將機密注入 Kubernetes 叢集和自動部署,以便應用程式使用最新的機密。有很多整合選項可用。 ![內部](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5x0tvt5ycaiqhggv6wml.png) 在使用整個原始程式碼之前一定要檢查他們的[許可證](https://github.com/Infisical/infisical/blob/main/LICENSE),因為他們有一些受 MIT Expat 保護的企業級程式碼,但不用擔心,大部分程式碼都是免費使用的。 他們在 GitHub 上擁有超過 11k 顆星,並發布了超過 125 個版本,因此他們正在不斷發展。另外,Infiscial CLI 的安裝次數超過 540 萬次,因此非常值得信賴。 {% cta https://github.com/Infisical/infisical %} 明星 Infisical ⭐️ {% endcta %} --- 17. [Gitinfluence](https://github.com/geovanesantana/gitfluence) - 尋找正確 git 指令的 AI 工具。 -------------------------------------------------------------------------------------- ![影響力](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8mr459i8l2lwa892nkae.png) 如您所知,學習每一個 git 指令是很困難的。如果用例很複雜,它就會變得複雜。 這就是為什麼 Gitinfluence 是人工智慧驅動的解決方案,可以幫助您快速找到正確的命令。借助這個出色的工具,您可以節省大量時間。 例如,這是我輸入我需要的內容後得到的回應。 ![回覆](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqylmd1mim7smgc78cby.png) 它就像聽起來一樣簡單而且非常有效率。 ![怎麼運作的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfmsm5cazm7sdnbvbmqe.png) 這是一個非常早期的開源專案 (next.js),擁有 55 顆星,但我確信它有很大的發展潛力。 {% cta https://github.com/geovanesantana/gitfluence %} 明星 Gitinfluence ⭐️ {% endcta %} --- 其中許多工具可以幫助您提高日常工作效率。 不管怎樣,如果您知道其他很棒的工具,請在評論中告訴我們。 祝你有美好的一天!直到下一次。 |如果你喜歡這類東西, 請關注我以了解更多:) | [![用戶名 Anmol_Codes 的 Twitter 個人資料](https://img.shields.io/badge/Twitter-d5d5d5?style=for-the-badge&logo=x&logoColor=0A0209)](https://twitter.com/Anmol_Codes) [![用戶名 Anmol-Baranwal 的 GitHub 個人資料](https://img.shields.io/badge/github-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/Anmol-Baranwal) [![用戶名 Anmol-Baranwal 的 LinkedIn 個人資料](https://img.shields.io/badge/LinkedIn-0A66C2?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/Anmol-Baranwal/) | |------------|----------| 關注 Taipy 以了解更多此類內容。 {% 嵌入 https://dev.to/taipy %} --- 原文出處:https://dev.to/taipy/17-developer-tools-that-keep-me-productive-37e2

Node.js 最佳實務:開發人員指南

Nodejs 是一個用於建立快速且可擴展的 Web 應用程式的強大工具。然而,為了充分利用 Nodejs,遵循最佳實踐非常重要。在這篇文章中,我們將探討 Nodejs 開發的一些關鍵最佳實務。 1. 建構你的專案 --------- 結構良好的專案易於維護和擴展。這是一個您可以遵循的簡單結構: ``` my-node-app/ │ ├── src/ │ ├── controllers/ │ ├── models/ │ ├── routes/ │ └── services/ │ ├── tests/ │ ├── .env ├── .gitignore ├── package.json └── README.md ``` 解釋: - `src/`包含您的主要應用程式程式碼。 - `controllers/`處理您的應用程式的邏輯。 - `models/`定義您的資料結構。 - `routes/`管理 API 的不同端點。 - `services/`包含業務邏輯。 - `tests/`包含所有測試檔案。 - `.env`儲存您的環境變數 - `.gitignore`指定 GIT 中要忽略的檔案。 - `.package.json`追蹤依賴項和腳本。 - `README.md`描述了您的專案。 2.使用環境變數 -------- 環境變數有助於將配置設定保留在程式碼之外。這使您的應用程式更安全且更易於管理。 例子: 建立一個`.env`檔: ``` DB_HOST=localhost DB_USER=root DB_PASS=password ``` 使用`dotenv`包在程式碼中載入這些變數: ``` require('dotenv').config(); const dbHost = process.env.DB_HOST; const dbUser = process.env.DB_USER; const dbPass = process.env.DB_PASS; console.log(`Connecting to database at ${dbHost} with user ${dbUser}`); ``` 3.正確處理錯誤 -------- 正確處理錯誤可確保您的應用程式不會意外崩潰。 ``` app.get('/user/:id', async (req, res, next) => { try { const user = await getUserById(req.params.id); if (!user) { return res.status(404).send('User not found'); } res.send(user); } catch (error) { next(error); } }); app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something went wrong!'); }); ``` 4. 使用非同步程式碼 ----------- Nodejs 本質上是異步的。使用`async`和`await`更乾淨地處理非同步程式碼。 例子: ``` async function fetchData() { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); console.log(data); } catch (error) { console.error('Error fetching data:', error); } } fetchData(); ``` 5. 保持依賴關係更新 ----------- 定期更新您的依賴項,以確保您擁有最新的功能和安全性修復。 使用`npm outdated`檢查是否有過時的軟體包。 ``` npm outdated ``` 更新套件: ``` npm update ``` 6. 編寫測試 ------- 測試您的程式碼有助於及早發現錯誤並確保您的應用程式正常執行 正如預期的那樣。 例子: **第 1 步:安裝`Jest`** ``` npm install --save-dev jest ``` **第 2 步:編寫測試** 建立測試文件,例如, `tests/example.test.js` 。這是一個幫助您入門的簡單範例。 ``` const sum = (a, b) => a + b; test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); }); ``` 7. 使用 Linter ------------ Linters 可協助您編寫乾淨且一致的程式碼。 ESLint 是一個受歡迎的選擇。 例子: 安裝 ESLint: ``` npm install eslint --save-dev ``` 初始化 ESLint: ``` npx eslint --init ``` 將 lint 腳本加入`package.json` : ``` "scripts": { "lint": "eslint ." } ``` 執行短絨檢查: ``` npm run lint ``` 結論 -- 遵循這些最佳實踐將幫助您編寫更好、更易於維護的 Nodejs 應用程式。請記住建立您的專案、使用環境變數、正確處理錯誤、編寫非同步程式碼、保持依賴項更新、編寫測試並使用 linter。透過這樣做,您將建立健壯且高效的 Nodejs 應用程式,並且更易於管理和維護。 快樂編碼! --- 原文出處:https://dev.to/mehedihasan2810/nodejs-best-practices-a-guide-for-developers-4d65

提升你的技能

介紹 -- 學習如何成為更好的開發人員需要不斷提升自己的技能。一個人如何學習成長並成為更好的開發人員?讓我們探討幾個總體上適用於大多數開發人員的想法。程式碼範例全部採用 C# 語言,之所以選擇它們是因為它們對於大多數開發人員來說並不常見,並且是在內部完成的。 腳步 -- - [Pluralsight](https://www.pluralsight.com/)是一個付費網站,提供數百門 C# 課程。首先使用他們的人工智慧評估,這將引導您走上正確的道路。許多課程也有自己的評估。 Pluralsight 讓您輕鬆地向高評價作者學習,並透過任何裝置(例如筆記型電腦、手機或平板電腦)存取課程。 Pluralsite 提供免費試用,有時還會在購買訂閱時提供折扣。 - 使用[微軟學習](https://learn.microsoft.com/en-us/training/)。無論您是剛開始職業生涯,還是經驗豐富的專業人士,我們的自我導向方法都可以幫助您更快、更有信心地按照自己的步調實現目標。透過互動式模組和路徑培養技能或向講師學習。以您的方式學習和成長。 - 花時間閱讀 Microsoft 文件,例如,閱讀[C# 程式的一般結構、類型運算子和表達式語句、](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/)各種[類別](https://learn.microsoft.com/en-us/dotnet/api/system.string?view=net-6.0)[、物件導向程式設計](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/tutorials/oop)等等。 - 在學習過程中,嘗試使用控制台或單元測試專案使事情變得簡單,換句話說,將後端學習與前端使用者介面學習分開。 - 在您感覺舒服的某個時間點,確定一個簡單的專案,在編碼之前寫出任務,然後編寫程式碼,而不是同時思考和編碼。新手等級的思考和編碼簡直就是一場即將發生的災難。 - 在網路上尋找資訊並找到解決方案時,不要簡單地複製和貼上,檢查程式碼,在使用所述程式碼之前先嘗試弄清楚它在做什麼。 - 了解如何在 Visual Studio 中使用 GitHub 來備份和版本程式碼。假設您編寫了程式碼並破壞了它,透過 GitHub 儲存庫中的正確版本控制,您可以還原變更並還原程式碼。 - 使用 .NET Framework Core 6 或 .NET Core Framework 8 而不是 .NET Framework classic,因為使用 .NET Core 有更多好處 - 如果學習使用資料,請從 SQL-Server Express 開始並安裝 SSMS (SQL-Server Management Studio),同時學習使用 Entity Framework Core。 - 充分了解學習任何語言時慢速學習比快速學習好,而且沒有人知道這一切。 ![了解如何使用除錯器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xp3uj4nuhzx7sple8tad.png) 加速學習的工具 ------- Microsoft Visual Studio 絕對是最好的 IDE(整合開發環境),它具有以下專案可以增加學習並節省編碼時間。 - 適用於 Visual Studio 和 SSMS 的 Red Gate [SQL 提示符](https://www.red-gate.com/products/sql-prompt/) - 高級 IntelliSense 風格的程式碼完成 - 重構 SQL 程式碼 - SSMS SQL 歷史記錄 - 以及更多 - Jetbrains [ReSharper](https://www.jetbrains.com/resharper/)這是一個非常寶貴的 Visual Studio 擴充功能。 - [EF Power Tools](https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools)可輕鬆對 EF Core 的 SQL-Server 資料庫進行逆向工程 深入了解程式碼基礎知識 ----------- 掌握基礎知識後,尋找有助於成長為更好的開發人員的程式碼範例。 一個可能的途徑是使用[Microsoft Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/) (EF Core) 或使用[Dapper](https://www.learndapper.com/)等資料提供者來處理資料庫。 還有其他處理資料的方法,但 EF Core 和 Dapper 在效能和易於學習方面是最好的。 在 Web 上尋找程式碼範例時,請確保它們適用於您的專案的 .NET Framework,因為 .NET Framework 4.8 程式碼範例與 .NET Core 8 Framework 有很大不同。 Microsoft 每年都會為 EF Core 建立程式碼範例,但在許多情況下,其結構可能不適合缺乏經驗的開發人員學習,因此 Karen Payne 採用 EF Core 8 程式碼範例並建立了以下[文章](https://dev.to/karenpayneoregon/microsoft-entity-framework-core-8-samples-3dj8)/[儲存庫,在大多數情況下,這些文章/儲存庫](https://github.com/karenpayneoregon/ef-code-8-samples)很容易學習。 第 1 課 - SQL-Server 計算列 ---------------------- ### EF 核心版本 {% cta https://github.com/karenpayneoregon/sql-basics/tree/master/EF\_CoreBirthdaysCompulatedColumns %} 範例專案 {% endcta %} [計算列](https://learn.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table?view=sql-server-ver16)是虛擬列,除非該列被標記為 PERSISTED,否則不會實際儲存在表中。計算列表達式可以使用其他欄位中的資料來計算其所屬列的值。您可以使用 SQL Server Management Studio (SSMS) 或 Transact-SQL (T-SQL) 為 SQL Server 中的計算列指定運算式。 完整文章,請參閱[SQL-Server:使用 Ef Core 計算列](https://dev.to/karenpayneoregon/sql-server-computed-columns-with-ef-core-3h8d) 但在這裡,我們將使用 EF Core 和 Dapper 從開始和演練使用情況建立一個計算列。 原文來自以下 Stackoverflow貼[文](https://stackoverflow.com/questions/9/how-do-i-calculate-someones-age-based-on-a-datetime-type-birthday?page=2&tab=modifieddesc#tab-top)。取得出生日期和目前日期,用出生日期減去目前日期,然後除以 10,000。 在 SSMS(SQL Server Management Studio)中 請注意,在程式碼範例中,完整資料庫存在於腳本資料夾下的專案 EF\_CoreBirthdaysCompulatedColumns 中。在執行腳本之前,請在 SSMS 中建立資料庫,然後執行腳本來建立表格並填入資料。 另請注意,在程式碼範例中,連接字串使用 NuGet 套件[ConsoleConfigurationLibrary](https://www.nuget.org/packages/ConsoleConfigurationLibrary/)駐留在 appsettings.json 中。 **表結構** ![表結構](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06sfbbb9i4ru5203l1nx.png) **SQL** ![選擇語句](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8bqiabe7j0a4nvez1yqa.png) 將聲明分開。 - 使用日期分隔符號格式化兩個日期並將每個日期轉換為整數。 - 從目前日期減去出生日期,括號很重要。 - 將以上除以 10,000 即可得到年齡。 **結果** ![SELECT 的結果](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cvzc25dc1ojr4arurnqy.png) 現在為名為 YearsOld 的表建立一個 nvarchar 類型的新欄位,並將此語句放入計算列屬性中,然後儲存變更。 ``` (CAST(FORMAT(GETDATE(), 'yyyyMMdd') AS INTEGER) - CAST(FORMAT(BirthDate, 'yyyyMMdd') AS INTEGER)) / 10000 ``` ![ssms中的表設計](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvwq73hel66uumzbixh5.png) - 建立一個新的 C# 控制台專案。 - 新增[Microsoft.EntityFrameworkCore.SqlServer](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.SqlServer/8.0.0?_src=template)的依賴項 - 安裝 Visual Studio 擴充[EF Power Tools](https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools) 。若要了解如何使用 EF Power Tools,請觀看作者提供的以下[影片](https://www.youtube.com/watch?v=uph-AGyOd8c)。新增[完整文件](https://github.com/ErikEJ/EFCorePowerTools/wiki/Reverse-Engineering)。 使用 EF Power Tools 後,將產生以下類別。 代表 SQL-Server 資料庫表的模型。 ``` public partial class BirthDays { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateOnly? BirthDate { get; set; } public int? YearsOld { get; set; } } ``` 所謂的[DbContext](https://learn.microsoft.com/en-us/dotnet/api/system.data.entity.dbcontext?view=entity-framework-6.2.0)和與資料庫互動的配置。 注意 YearsOld 上的[HasCompulatedColumnSql](https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.relationalpropertybuilderextensions.hascomputedcolumnsql?view=efcore-8.0) ,這是我們的計算列。 ``` public partial class Context : DbContext { public Context() { } public Context(DbContextOptions<Context> options) : base(options) { } public virtual DbSet<BirthDays> BirthDays { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) #warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263. => optionsBuilder.UseSqlServer(DataConnections.Instance.MainConnection); protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<BirthDays>(entity => { entity.Property(e => e.YearsOld).HasComputedColumnSql("((CONVERT([int],format(getdate(),'yyyyMMdd'))-CONVERT([int],format([BirthDate],'yyyyMMdd')))/(10000))", false); }); OnModelCreatingPartial(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); } ``` > **筆記** > 執行上述工作有兩個陣營:資料庫優先或程式碼優先。對於剛開始使用 EF Core 的人來說,資料庫優先是最好的路徑。 要查看資料, [Spectre.Console](https://spectreconsole.net/)用於建立一個漂亮的表格。 ``` internal partial class Program { static async Task Main(string[] args) { await Setup(); var table = CreateTable(); await using (var context = new Context()) { var list = await context.BirthDays.ToListAsync(); foreach (var bd in list) { table.AddRow( bd.Id.ToString(), bd.FirstName, bd.LastName, bd.BirthDate.ToString(), bd.YearsOld.ToString()); } AnsiConsole.Write(table); } ExitPrompt(); } public static Table CreateTable() { var table = new Table() .AddColumn("[b]Id[/]") .AddColumn("[b]First[/]") .AddColumn("[b]Last[/]") .AddColumn("[b]Birth date[/]") .AddColumn("[b]Age[/]") .Alignment(Justify.Left) .BorderColor(Color.LightSlateGrey); return table; } } ``` ![上述程式碼的截圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i60dye7au7fve08y1wfu.png) 為了獲取我們的資料,一行程式碼用於實例化 EF Core,一行程式碼用於讀取資料。 EF Core 也非常適合關聯式資料庫,請參閱以下[儲存庫](https://github.com/karenpayneoregon/ef-code-8-samples)。 有關記錄 EF Core 產生的 SQL,請參閱下列[專案](https://github.com/karenpayneoregon/ef-code-8-samples/tree/master/DualContextsApp),該專案也展示如何使用兩個不同的 SQL-Server 實例。 ### 短小精悍的版本 {% cta https://github.com/karenpayneoregon/sql-basics/tree/master/DapperBirthdaysCompulatedColumns %} 範例專案 {% endcta %} 與 EF Core 不同,使用 Dapper,開發人員在 SSMS 中編寫 SQL 語句並將有效語句新增到程式碼中。有關 Dapper 的更多訊息,請參閱我的[系列](https://dev.to/karenpayneoregon/series/25270)。 這裡 SQL 儲存在唯讀字串中,替代方法是將 SQL(或任何語句)儲存在預存程序中。 ![學習編寫正確的 SQL](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uyn1awyunv0pvbhtgzy1.png) ``` internal class SqlStatements { public static string GetBirthdays => """ SELECT Id ,FirstName ,LastName ,BirthDate ,YearsOld FROM BirthDaysDatabase.dbo.BirthDays """; } ``` 讀取資料的程式碼。 ``` internal class DapperOperations { private IDbConnection _cn; public DapperOperations() { _cn = new SqlConnection(DataConnections.Instance.MainConnection); SqlMapper.AddTypeHandler(new SqlDateOnlyTypeHandler()); SqlMapper.AddTypeHandler(new SqlTimeOnlyTypeHandler()); } public async Task<List<BirthDays>> GetBirthdaysAsync() { return (await _cn.QueryAsync<BirthDays>(SqlStatements.GetBirthdays)).AsList(); } } ``` 在類別構造函數中 1. 使用[Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient/5.2.1?_src=template) NuGet 套件建立連線。 1. 使用[kp.Dapper.Handlers](https://www.nuget.org/packages/kp.Dapper.Handlers/1.0.0?_src=template) NuGet 套件為 Dapper 新增理解 DateOnly 類型的功能。 讀取資料是一個單行資料,表示我們需要非同步生日列表。 ``` public async Task<List<BirthDays>> GetBirthdaysAsync() { return (await _cn.QueryAsync<BirthDays>(SqlStatements.GetBirthdays)).AsList(); } ``` 回到 Program.cs,除了建立 Dapper 類別的實例並呼叫方法之外,程式碼與 EF Core 相同。 ``` internal partial class Program { static async Task Main(string[] args) { await Setup(); var table = CreateTable(); var operations = new DapperOperations(); var list = await operations.GetBirthdaysAsync(); foreach (var bd in list) { table.AddRow( bd.Id.ToString(), bd.FirstName, bd.LastName, bd.BirthDate.ToString(), bd.YearsOld.ToString()); } AnsiConsole.Write(table); ExitPrompt(); } public static Table CreateTable() { var table = new Table() .AddColumn("[b]Id[/]") .AddColumn("[b]First[/]") .AddColumn("[b]Last[/]") .AddColumn("[b]Birth date[/]") .AddColumn("[b]Age[/]") .Alignment(Justify.Left) .BorderColor(Color.LightSlateGrey); return table; } } ``` ### 計算列的摘要 並未詳細介紹程式碼的每個方面,這意味著在專案中採用技術之前需要花時間剖析程式碼以及使用了哪些 NuGet 套件。也可以考慮透過[Visual Studio 偵錯器](https://learn.microsoft.com/en-us/visualstudio/get-started/csharp/tutorial-debugger?view=vs-2022)執行程式碼。 偵錯是許多新手開發人員忽略的事情,也是 Visual Studio 的最佳功能之一。學習如何除錯並不需要花費大量時間。 第 2 課 - 重構程式碼 ------------- 許多人認為編碼的主要任務是讓程式碼正常工作,然後返回並重構程式碼。從個人經驗來看,這種情況一般不會發生。這就是開發人員需要在工作專案之外磨練技能的原因。 ![從未停止學習](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ju4889uewhkpfrfmp0w5.png) ### 實施例1 開發人員被要求將字串拆分為大寫字符,並將字串放在前面。 例如,給定 ThisIsATest,輸出將是 This Is A Test。開發者在網路上搜尋並找到以下內容。 ``` public static class StringExtensions { private static readonly Regex CamelCaseRegex = new(@"([A-Z][a-z]+)"); /// <summary> /// KarenPayne => Karen Payne /// </summary> [DebuggerStepThrough] public static string SplitCamelCase(this string sender) => string.Join(" ", CamelCaseRegex.Matches(sender) .Select(m => m.Value)); } ``` 這是可行的,但有一個更好的版本,在下面的範例中是由GitHub Copilot 編寫的,並且是第二次迭代,這意味著第一次copilot 被問到時,它提供了一個未經優化的解決方案,因為問題是如何提出的。 ``` [DebuggerStepThrough] public static string SplitCamelCase(this string input) { if (string.IsNullOrEmpty(input)) { return input; } Span<char> result = stackalloc char[input.Length * 2]; var resultIndex = 0; for (var index = 0; index < input.Length; index++) { var currentChar = input[index]; if (index > 0 && char.IsUpper(currentChar)) { result[resultIndex++] = ' '; } result[resultIndex++] = currentChar; } return result[..resultIndex].ToString(); } ``` ![更少的程式碼並不總是最好的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i8u0zjrr2qjgot6tmav8.png) 等一下,第二個版本的程式碼多了很多,這個版本怎麼會更好呢?新手和經驗豐富的開發人員都有一種心態,就是程式碼行數越少越好,也許是為了提高可讀性。當然,開發人員應該始終努力編寫可讀的程式碼,但多行程式碼也可以輕鬆閱讀。 如何編寫可讀的程式碼。 - 使用有意義的變數名稱,例如在 for 語句中使用索引而不是 i 或使用firstName 而不是fName。 - 折疊程式碼而不是一行,如下所示 ``` public static class CheckedListBoxExtensions { public static List<T> CheckedList<T>(this CheckedListBox sender) => sender.Items.Cast<T>() .Where((_, index) => sender.GetItemChecked(index)) .Select(item => item) .ToList(); } ``` 而不是 ``` public static class CheckedListBoxExtensions { public static List<T> CheckedList<T>(this CheckedListBox sender) => sender.Items.Cast<T>().Where((_, index) => sender.GetItemChecked(index)).Select(item => item).ToList(); } ``` 下一步 --- 這裡有一些想法,即使是許多經驗豐富的開發人員也會避免,而不是你! - [泛型](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics) - [介面](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface) - 建立公共庫 - [JSON 序列化與反序列化](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/overview) 概括 -- 這些是成為更好的開發人員的更多技巧中的一些。實現這一目標的唯一方法是在專案之外不斷學習。 如果您的老闆或團隊領導者沒有提供時間來學習新技能,您可以每週花一兩個小時來學習和成長。 --- 原文出處:https://dev.to/karenpayneoregon/push-your-skills-2pho

Kubernetes 編譯失敗:然後正式機掛掉的情況!

我從來都不是一個大賭徒。過去我可能會下一個小賭注來為超級盃增添趣味,但我並沒有那麼投入,但這並不是什麼瘋狂的事情。真正投入資金需要一定程度的確定性,而我在任何體育賽事、選舉結果或未來預測中都很少有這種確定性。科技領域的確定性非常少。工作保障並不是既定的,產業趨勢潮起潮落,你每天使用的[工具](https://glasskube.dev/guides/kubectl/)和技術堆疊很可能會隨著時間的推移而不斷發展。儘管充滿了不確定性,但還是有一些東西你可以安全地押注,但在某些時候,**你會遭遇中斷。** ![賭場](https://media1.giphy.com/media/26tneF8wxg0H4NrC8/200.webp?cid=ecf05e4725b5vpix4vj3x0ajz06gb8rehvx96kjva729y9nu&ep=v1_gifs_search&rid=200.webp&ct=g) 從事任何時間的 Kubernetes 工程師都可以證明這個現實。在這種情況下,害怕失敗或執行艱鉅的任務來確保[100% 可用性](https://andrewmatveychuk.com/why-99-99-uptime-or-sla-is-bad/)是沒有意義的,如果有任何[錯誤](https://www.amazon.com/Black-Box-Thinking-People-Mistakes-But/dp/1591848229)和中斷應該被視為學習機會,這對於任何渴望成熟並提供高品質的環境來說都是必要的邪惡以可靠的方式提供服務。 有效處理和消化中斷的最佳方法是系統地進行[事後分析](https://www.atlassian.com/incident-management/postmortem/reports)。事實證明,這些是我們尋找模式並綜合中斷所提供的經驗教訓的最敏銳的工具。關於 Kubernetes 叢集故障中常見的模式主題,出現了一些模式。 ![reddit-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xml8lmgs8g9e36624td5.png) DNS、網路和預設資源分配是一些關鍵的罪魁禍首。 ![reddit-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ijimseogd4nn43k5sni.png) 在這篇文章中,我們將分析其中的一些事後分析,並盡力吸收其他人經過艱苦的努力才學到的東西。 故障嚴重程度等級 -------- 並非每次中斷都會產生相同的影響,因此我建立了一個非常科學的分類系統來了解每次 Kubernetes 中斷的影響: **🤷 - 有點糟糕:**微不足道的 Kubernetes 故障 **😅 - 非正式機,但仍然令人煩惱:**我們沒有影響任何客戶,但我們學到了教訓 **🤬 - 休士頓,我們在生產中遇到了問題:**客戶受到影響,職業選擇受到質疑。 ![你被開除了](https://media1.giphy.com/media/xT4uQ7N8UNsoeFAjVS/200.webp?cid=790b76115lk6lg7hzua5e4qexoocj2f0sltdsw5l4ggfcsln&ep=v1_gifs_search&rid=200.webp&ct=g) --- 在我忘記之前,讓我感謝[Glasskube](https://github.com/glasskube/glasskube)讓我花時間建立這樣的內容。如果這是您第一次聽說我們,我們正在努力`Package Manager for Kubernetes` 。 如果您願意支持我們完成這項任務,我們將不勝感激 [⭐️ GitHub 上的 Star Glasskube 🙏](https://github.com/glasskube/glasskube) [![感謝您的支持](https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHZxc3Nxbjdyem9kY24xd3k5M3EwY2Q1dmQ3OTA0aTh4c3cycmpkdyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/l3q2wJsC23ikJg9xe/200.webp)](https://github.com/glasskube/glasskube) --- 有點糟糕🤷 ----- 如果你不能笑自己,你還能笑誰? ### 叢集和節點群組 第一個故事來自您謙虛的記者,他最近使用 AWS 控制台啟動了一個測試 Kubernetes 集群,以快速驗證概念。我已經有一段時間沒有使用 EKSCTL 或某種形式的基礎設施即程式碼定義檔來建立叢集了。 因此,我登入並存取 EKS 控制台,命名我的 Kubernetes 集群,然後點擊「建立」。然後,我按照 CLI 說明配置 kubeconfig 檔案並透過終端連接到我新建立的叢集。 由於渴望測試最新版本的 Glasskube,我將其安裝在叢集中。然而,令我驚訝的是 Pod 的安排時間如此之長。現在回想起來,我很尷尬地承認我花了多長時間才意識到我沒有配置節點組,難怪 Pod 沒有被調度。 ![不為所動](https://media4.giphy.com/media/v1.Y2lkPTc5MGI3NjExNm9mdzVweWc1cDljdjM3MWpmeTRqcm1sejltZXhzZmZlYzFtMmNtMSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/c5FhF1waAJ5wk/giphy.webp) ### 打電話給消防隊,我忘了加入資源限制。 另一個真實的故事來自另一位Glasskube 成員,由於在本地Minikube 集群中安裝了許多元件(GitLab),他的本地筆記型電腦超載了,筆記型電腦幾乎在他的辦公桌上燒了一個洞,這是一個很好的提醒,要使用資源限制和請求 ![筆記型電腦起火](https://media0.giphy.com/media/dbtDDSvWErdf2/200.webp?cid=ecf05e4775sy7d66ores8c10w1hrw77311mm7m323lkkkqym&ep=v1_gifs_search&rid=200.webp&ct=g) 非正式機,但仍然很煩人😅 ----------- 轉向一些真實的事件,幸運的是這些事件僅限於不會影響付費客戶的叢集。 ### 事件#1:Venafi 的 Webhooks 無回應 [Venafi](https://venafi.com/)是機器身分的控制平面,最近被[Cyberark](https://www.cyberark.com/)收購,Cyberark 在 OPA 方面存在一些問題。完整的屍檢[在這裡](https://venafi.com/blog/gke-webhook-outage/)。 ![快點](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5mnqgz5998ynmk3rpipg.png) > **影響:**間歇性 API 伺服器逾時導致節點不健康。 > **涉及:**開放策略代理、節點準備 **逐場比賽** 在計劃的叢集升級期間,儘管有警告並且之前升級成功,但主升級失敗,導致 API 伺服器逾時和節點不穩定。**根本原因是 ConfigMap 更新期間逾時**,由無回應的[OPA](https://www.openpolicyagent.org/) Webhook 觸發。刪除 webhook 恢復了服務,此後他們將其限制在特定的命名空間,加入了 OPA 的活性探針,並更新了文件。 他們強調需要 API 回應時間警報、工作負載探測,並可能使用 Helm 圖表進行部署,以避免將來出現類似問題。他們繼續監控功能的改進並透過 Flightdeck 服務提供見解。 **學習內容:** - 需要對 API 伺服器回應時間發出警報。 - 增加所有工作負載所需的`livenessProbes` 。 - 使用套件管理進行更精細的配置。 > 💡 這事件凸顯了[Glasskube](https://github.com/glasskube/glasskube)旨在解決的用例之一。雖然 Glasskube 尚不支援 OPA 運算符,但我們相信透過強大的 Kubernetes 套件管理器可以避免這個問題。 Glasskube 可輕鬆配置關鍵功能,協助升級,並將 GitOps 方法應用於套件操作員管理,包括回溯和特定命名空間分配。[在這裡](https://github.com/glasskube/glasskube)嘗試一下。 ### 事件#2:當加密貨幣礦工潛入時 [JW Player](https://jwplayer.com/)成為比特幣挖礦惡意軟體的目標,請[在此處](https://medium.com/jw-player-engineering/how-a-cryptocurrency-miner-made-its-way-onto-our-internal-kubernetes-clusters-9b09c4704205)查看完整的事後分析。 ![JW-玩家](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/do39mgvqt5e01ndnk9aw.png) > **影響:**非生產集群被比特幣礦工滲透 > **涉及:** Root存取利用 **逐場比賽** 在 Datadog 向 JW Player 的 DevOps 團隊發出其臨時和開發環境中的平均負載較高的警報後,JW Player 的 DevOps 團隊在其 Kubernetes 叢集上發現了一個加密貨幣挖礦程式。**初步調查發現,有一個gcc進程佔用了100%的CPU,經檢查發現該進程是監控工具Weave Scope發起的礦機**。該礦工利用了面向公眾的 Weave Scope 負載平衡器,允許在容器中執行命令。 立即採取的行動包括停止 Weave Scope、隔離受影響的節點並將其輪換出去。該事件導致 CPU 使用率較高,但沒有服務中斷或資料外洩。該團隊將 Kubernetes 覆蓋的手動安全群組編輯確定為關鍵問題,並強調需要採取適當的配置實踐來防止此類漏洞。 **學習內容:** - 監控負載並不是檢測叢集問題的最佳方法。 - 可能需要`falcon`或`sysdig`等工具 - 需要更強大的 Docker 映像和容器掃描。 - 架構的某些區域需要重新檢視。 - 需要更多的跨團隊資料共享和溝通。 ### 事件 #3:GKE 耗盡 IP 位址 ![愛情假期](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2e5fh4u5u8hxwse1az0s.png) > **影響:**高節點數叢集耗盡了 IP 位址,無法調度新的 Pod。 > **涉及:**子網路、每個節點的預設 IP 分配 **逐場比賽** 當一名團隊成員報告其應用程式的部署時間異常長時,就發生了一起事件。他們很快就發現,雖然一些新部署的 Pod 正在提供流量,但其餘的 Pod 仍處於`pending`狀態。**分析顯示`FailedScheduling`警告顯示資源不足。**儘管部署了叢集自動縮放器,但問題仍然存在,因為他們看到了令人震驚的**「0/256 個節點可用」**訊息。進一步檢查發現,GKE為每個節點預先分配了110個IP,導致IP消耗意外高。了解這一點後,他們調整了每個節點的 Pod 分配,將整體 IP 使用量減少了 30%。此外,他們還探索了子網擴展和增加節點大小等選項以緩解 IP 耗盡,最終優化節點池實例大小以更好地利用資源。 **學習內容:** - 了解 GKE 設定的預設值的重要性。 - [子網路擴充功能](https://cloud.google.com/vpc/docs/create-modify-vpc-networks#expand-subnet)是一個可供您使用的實用工具(儘管關於次要範圍的文件不多)。 - 增加節點池執行個體大小也可以完成這項工作(每個節點執行更多 Pod,然後需要更少的節點)。 休士頓,我們的生產遇到問題了🤬 --------------- 這些類型的中斷**會讓 SRE 徹夜難眠**,當客戶受到影響並且業務價值岌岌可危時,這些都是最重要的經驗教訓和英雄的誕生地。 ### 事件 #1 Skyscanner 只需要幾個字元就可以關閉他們的網站 在這裡我們看到,針對彈性進行了最佳化的架構仍然容易因為一行程式碼而故障。完整的屍檢[在這裡](https://medium.com/@SkyscannerEng/how-a-couple-of-characters-brought-down-our-site-356ccaf1fbc3)。 ![天巡](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zma05ic4v2m88e05y797.png) > **影響:**全球 Skyscanner 網站和行動應用程式無法存取 > **涉及:** IaC清單 **逐場比賽** 2021 年 8 月,由於無意中更改了基礎設施配置系統中的根文件,Skyscanner 面臨持續四個多小時的全球中斷。**由於缺少`{{ }}` ,這項變更意外地觸發了全球範圍內關鍵微服務的刪除**,導致網站和行動應用程式無法存取。 ![致命線](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ohytkjb4v3p1c0ekvno.png) 他們迅速解決了這個問題,利用 GitOps 恢復配置並確定關鍵服務的優先順序。 **學習內容:** - 不要進行全域配置部署。 - 需要更徹底的「最壞情況」規劃。 - 驗證備份/復原過程。 - 保持操作手冊最新。 - 超越自動化的潛力。 ### 事件#2 Monzo Bank 的 linkerd 慘敗 英國數位[銀行](https://monzo.com/)艱難地發現了 Kubernetes 的一個嚴重錯誤。完整的屍檢[在這裡](https://community.monzo.com/t/resolved-current-account-payments-may-fail-major-outage-27-10-2017/26296/95)。 ![蒙佐銀行](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tjblle4py5mifmv1s1e.png) > **影響:**預付卡和新活期帳戶下降約1.5小時 > **涉及:** Linkerd、kube-apiserver、etcd **逐場比賽:** 此事件始於例行部署導致支付處理失敗。嘗試回滾變更未成功,導致內部中斷聲明。工程師發現並重新啟動了不健康的`linkerd`實例,但`kube-apiserver`的配置問題導致新的`linkerd`實例無法啟動,從而將中斷升級為整個平台故障。**根本原因可追溯到 Kubernetes 和 etcd 中的錯誤,該錯誤是由最近的叢集重新配置觸發的。**這導致`linkerd`無法接收網路更新,再加上 Kubernetes 和 linkerd 之間的相容性問題。該事件已透過更新 linkerd 並刪除空的 Kubernetes 服務得到解決。 **學習內容:** - 需要新版本的 Linkerd。 - k8s bug 需要修復(現已[修復](https://github.com/kubernetes/kubernetes/issues/47131))。 - 改進執行狀況檢查、儀表板和警報。 - 改進程序以改善停電期間的內部溝通。 ### 事件 #3 Redis 操作員丟了一個曲線球 Palark 是一家 DevOps 服務供應商,曾試圖保護其 Redis 集群,但最終卻後悔了。[這](https://blog.palark.com/failure-with-redis-operator-and-redis-data-analysis-tools/)是完整的移植剖析 ![帕拉克](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09fk9z0exq8006orscwm.png) > **影響:**加入副本後的生產 Redis 資料 > **涉及:** Redis算子 **逐場比賽** 他們遇到了一個涉及眾所周知的記憶體鍵值儲存 Redis 的事件,他們透過[Redis Operator](https://github.com/spotahome/redis-operator)安裝該儲存來執行 Redis 故障轉移。最初部署了一個 Redis 副本,後來擴展到兩個副本以增強資料庫可靠性。**然而,這個看似微小的變化在部署過程中被證明是災難性的,導致資料遺失。**該事件揭露了 Redis Operator 中的缺陷,主要是其`readiness probe` ,引發了意外的主升級和隨後的資料破壞。使用`Redis-memory-analyzer`等工具進行進一步分析,揭示了對資料庫大小和元素的洞察,從而幫助開發人員優化資料庫和應用程式程式碼,以防止未來發生事件。 **學習內容:** - 使用 Kubernetes Operator 時要非常小心(確保它們成熟且經過充分測試)。 - 他們發現了與 Redis Operators 就緒性探測相關的關鍵錯誤,該錯誤使副本橫向擴展容易導致資料遺失(已[修復](https://github.com/spotahome/redis-operator/releases/tag/v1.0.0-rc.3))。 - `Redis-memory-analyzer`是Redis資料庫故障排除的最佳工具。 事件 #4 Datadog 的多區域噩夢 -------------------- 多個[Datadog](https://www.datadoghq.com/)區域宕機`systemd-networkd`強制刪除了容器網路介面 (CNI) 插件管理的路由。完整的屍檢 [在這裡](https://www.datadoghq.com/blog/2023-03-08-multiregion-infrastructure-connectivity-issue/)。 ![資料狗](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcobaticca62tpuk7nwq.png) > **影響:**多個地區的使用者無法存取 API 和平台。 > **涉及:** systemd更新、Cilium **逐場比賽** 從 2023 年 3 月 8 日開始,Datadog 經歷了一次影響多個區域的重大中斷,導致用戶無法存取平台、API 和監視器,並影響資料提取。這個問題是由眾多虛擬機器上的 systemd 自動安全性更新觸發的,導致網路中斷,導致數萬個節點離線。恢復涉及恢復運算能力、解決特定於服務的問題以及為客戶提供持續更新。**根本原因被確定為允許自動更新的錯誤配置,該更新已停用。** **學習內容:** - 更強大的混沌測試。 - 需要在停電期間改善與客戶的溝通 - 停電期間狀態頁面不充分。 - 自動更新本身就有風險,應謹慎使用。 ### 事件#5 Reddit 的圓周率日中斷 Reddit 遭受了快速有機成長的後果,他們面臨著殘酷的現實,即許多關鍵的 Kubernetes 叢集不標準化,很容易出現中斷,[這裡是](https://www.reddit.com/r/RedditEng/comments/11xx5o0/you_broke_reddit_the_piday_outage/)完整的 Pi-Day 中斷事後分析。 ![紅迪網](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5s1vi0fdjwzps01hgnpj.png) > **影響:**嚴重的跨平台中斷持續 314 分鐘 > **涉及:** Calico、Kubernetes版本更新 **逐場比賽** 2023 年 3 月,Reddit 經歷了一次持續 314 分鐘的嚴重中斷,巧合的是,這發生在圓周率日。嘗試存取網站的用戶要么遇到不堪重負的 Snoo 吉祥物、錯誤訊息,要么看到空的主頁。這次中斷是由 Kubernetes 1.23 升級到 1.24 引發的,這引入了一個以前從未見過的微妙問題。工程團隊近年來一直強調可用性的改進,但發現自己處於一個充滿挑戰的境地,回滾雖然有風險,但卻成為了最佳選擇。 在復原過程中,由於 TLS 憑證和 AWS 容量限制不匹配,因此出現了一些複雜情況,但團隊設法克服了這些挑戰並重新建立了高可用性控制平面。 **進一步調查顯示,根本原因與 Calico 過時的路由反射器配置有關**,由於刪除了「master」節點標籤,此配置與 Kubernetes 1.24 不相容。 **學習內容:** - 出於測試目的改進預生產集群的重要性。 - 需要改進 Kubernetes 元件生命週期管理工具。 - 需要更同質的環境。 - 此外,還需要增加他們的 IaC 和內部技術文件。 結論 -- 正如您所看到的,熵定律很容易適用於 Kubernetes 叢集——破壞它們比讓它們滿意要容易得多。升級、部署、擴展和部署等變更通常會引發中斷,因此您可能傾向於盡量減少中斷。但對於那些努力引領細分市場並滿足不斷變化的客戶需求的組織來說,這不是一個選擇。我們所能期望的最好的結果就是從實踐中學習,並從失敗中學習。從好的方面來說,科技業普遍樂於學習,並能坦然面對失敗( [在大多數情況下](https://apnews.com/article/cellular-att-verizon-tmobile-outage-02d8dfd93019e79e5e2edbeed08ee450))。事實上,許多大型企業公開分享事後總結供更大的社區學習,這是一種最佳實踐,其基礎是這樣的假設:故障和中斷是「何時」而不是「是否」的問題。保護我們自己的最好方法就是在他們過去後向他們學習。 > 🫵 那你呢?您是否經歷過任何特別困難的停電並從另一邊講述了這個故事?如果是這樣,請在下面的評論中分享您的經驗。我相信我們很多人都想聽聽這個。 --- 幫助我們製作更多這樣的內容! -------------- 在[Glasskube,](https://github.com/glasskube/glasskube)我們在此類內容上投入了大量精力,並`next generation package manager for Kubernetes` 。 如果您從我們所做的工作中獲得價值,我們將不勝感激 [⭐️ GitHub 上的 Star Glasskube 🙏](https://github.com/glasskube/glasskube) [![github 上的明星](https://media2.giphy.com/media/v1.Y2lkPTc5MGI3NjExdnhibjU3MnRqeDVydm83ZXNiMHF1YXQ3NW9iMTEwcjFuZmhqcG8ydSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/XaFhFM2lVRoVa/giphy.gif)](https://github.com/glasskube/glasskube) --- 原文出處:https://dev.to/glasskube/kubernetes-fail-compilation-but-they-keep-getting-worse-12n2

建立出色的 GitHub 開發人員作品集。

在軟體開發領域,有效地展示您的工作以及您編寫的程式碼至關重要。作品集網站是開發人員展示其技能、專案和貢獻的絕佳方式。增強您的作品集的一種創新方法是整合 GitHub 統計資料,它可以提供有關您的編碼活動和貢獻的即時見解。 為了幫助其他開發人員實現這一目標,我從頭開始建立了一個新網站,重點介紹您的 GitHub 作品。該網站是使用 NextJS 和 Tailwind CSS 建立的,它從您的 GitHub 個人資料和工作中獲取所有資料。 *本文將逐步引導您完成設定過程,並且還將為您提供 GitHub 連結。* **這是即時預覽:**[即時預覽網址](https://github.abusaid.me/) ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fi8nc8kwy5vn42vk70zr.png) **步驟01:** 使用[GitHub 連結複製](https://github.com/said7388/github-portfolio.git)儲存庫並將目錄變更為 github-portfolio。 ``` git clone https://github.com/said7388/github-portfolio.git cd github-portfolio ``` **步驟02:** 現在使用`npm`或`yarn`安裝所有套件。 ``` npm install # or yarn ``` 安裝完所有套件後,現在根據您的情況更改`data/user-data.js`上的所有資料。例如: ``` export const userData = { githubUser: 'said7388', devUsername: "said7388", github: 'https://github.com/said7388', facebook: 'https://www.facebook.com/abusaid.riyaz/', linkedIn: 'https://www.linkedin.com/in/abu-said-bd/', twitter: 'https://twitter.com/said7388', stackOverflow: 'https://stackoverflow.com/users/16840768/abu-said', leetcode: "https://leetcode.com/said3812/", resume: "https://drive.google.com/file/d/1eyutpKFFhJ9X-qpQGKhUNnVRkB5Wer00/view?usp=sharing", skills: ['React', 'NextJS', 'Redux', 'Express', 'NestJS', 'MySql', 'MongoDB', 'Postgres', 'Docker', 'AWS'], timezone: '+6' }; ``` **步驟03:** 如果您想使用 Google Analytics,請從`.env.example`檔案建立新的`.env`檔案並提供值。 `.env`文件如下: ``` NEXT_PUBLIC_GTM = "" ``` **步驟04:** 現在 GitHub 作品集網站已準備好運作。您可以使用`npm`或`yarn`執行它。 ``` npm run dev # or yarn dev ``` 如果您喜歡這個 GitHub 組合專案,您可以考慮在[GitHub 儲存庫](https://github.com/said7388/github-portfolio)上給它一顆星。 您可以在 Linkedin 上與我聯絡: <https://www.linkedin.com/in/abu-said-bd/> > 免責聲明:在這個儲存庫中,我使用了一些開源 API。所有積分均歸這些儲存庫的擁有者所有。 --- 原文出處:https://dev.to/said7388/build-an-awesome-github-developer-portfolio-54ka

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

關於 laravel 多語系 model 的小研究

在研究 TwillCMS 的時候 發現他的多語系 model 功能很好用 比方說 `posts` 的資料表 可以建立 `post_translations` 資料表 然後多語系資料存裡面 就能用一般存取 eloquent attribute 的方式取得翻譯 這是怎麼做到的呢? --- 首先 使用多語的 model 要先使用 Trait `A17\Twill\Models\Behaviors\HasTranslation` 然後要在 `$translatedAttributes` 裡面設定好 查看那個 Trait 的原始碼 會發現要使用 另一個 Trait `Astrotomic\Translatable\Translatable` 原來,底層其實用到了另一個套件 https://github.com/Astrotomic/laravel-translatable --- 繼續翻閱那個套件的原始碼 `Astrotomic\Translatable\Translatable` 會看到 `public function getAttribute` 實際上的功能,就是實作在這邊! 因為在 laravel eloquent 的原始碼 `Illuminate\Database\Eloquent\Model` 有下面這段 ``` public function __get($key) { return $this->getAttribute($key); } ``` 也就是讀取 model attribute 時,其實有經過 php magic function `__get()` 所以 `Translatable` 這個 Trait 就是擴充了這個函數 ``` public function getAttribute($key) { [$attribute, $locale] = $this->getAttributeAndLocale($key); if ($this->isTranslationAttribute($attribute)) { if ($this->getTranslation($locale) === null) { return $this->getAttributeValue($attribute); } // 這邊省略 } return parent::getAttribute($key); } ``` 然後會去呼叫 `public function getTranslation` 這樣,答案揭曉! --- 題外話,翻閱 eloquent model source code 的時候 我發現 `getAttribute` 不是直接寫在 model 內 而是在 `Illuminate\Database\Eloquent\Concerns\HasAttributes` 裡面 eloquent 因為功能太豐富 所以打散在 `Concerns` 資料夾內 其實就是 Traits 的意思 只是因為 `Seperation of Concerns` 原則太有名 所以用 Concerns 來命名 其實也有道理 就好像我們不會把放了一堆類別的資料夾 命名為 `Classes` 這樣 在 laravel source code 放了一堆 interface 的資料夾也是命名為 `Contracts` 的

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

🚀 利用這些資源加速您的發展! 🚀 👋大家好! 👋 我很高興能分享我多年來收集的這些資源,這些資源在我從事的許多專案中都是救星。該編譯匯集了從使用者介面建立到效能最佳化等各種工具和函式庫。希望您也能充分利用這些精彩資源。讓我們開始吧! 請隨意評論您使用或感興趣的任何其他資源,以便我可以將它們加入到帖子中! ### 使用者介面: - [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

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

首次嘗試安裝 Twill CMS

在開始研究模組之前 先來安裝 twill 官方有一份簡易教材 https://twillcms.com/guides/page-builder-with-blade/index.html 安裝 twill 可以分成三步驟: - 安裝 laravel - 安裝 twill 套件 - 跑 twill 初始指令 我開了一個 githun repo 可以在前三個 commits 分別看到對應的檔案變化 https://github.com/howtomakeaturn/twill-play/commits/main/ --- 在本機裝好之後 twill admin 面板看到的是 紀錄 `All activity` `My activity` 的面板首頁 以及 `Media Library` 功能 僅此而已 可以說是非常乾淨 也就是在新增模組之前 admin 面板可說是啥都沒有 很好的極簡哲學 資料庫方面 初始會出現的資料表如下 ``` activity_log app_settings failed_jobs migrations password_reset_tokens personal_access_tokens twill_blocks twill_features twill_fileables twill_files twill_mediables twill_medias twill_password_resets twill_related twill_settings twill_setting_translations twill_tagged twill_tags twill_users users ``` 可以看到 twill 開頭的資料表 都是 twill 提供的 cms 功能 其餘都是 laravel 原生提供的功能 這邊我有些不懂的是 activity_log 與 app_settings 也是 twill 提供的 怎麼不加上 twill 開頭呢? 沒關係,瑕不掩瑜! 新增的檔案可以在這邊看到 https://github.com/howtomakeaturn/twill-play/commit/60d420d283aaa37e96ee29c72077292261b1383b 我認為切分得非常漂亮:屬於 twill 的都有獨立路徑 屬於你 app 的就用 laravel 慣例路徑 這樣在替客戶開發網站的時候 非常放心 客戶的 domain 與 twill 的 domain 不會混在一起! 接著來 看看怎麼新增模組吧!

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

人工智慧時代已經來臨。身為開發者,要想取得成功,在你的投資組合中加入一些人工智慧驅動的專案是很棒的。 今天,我們將建立一個由人工智慧驅動的部落格平台,該平台具有一些很棒的功能,例如研究、自動完成和 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

50 個最佳免費 HTML 範本網站

您可以在其中找到和下載使用普通 CSS 以及每個主要框架建立的免費 HTML 模板。這些高品質的專案將為您的網站、登陸頁面、部落格、作品集、電子商務和儀表板專案提供支援。 在線空間中有許多模板建立者。以下是使下面提到的那些脫穎而出的原因。 - 模板免費提供給個人和商業用途 - 專案看起來很現代,並提供強制性的即時預覽 - 您只需提供電子郵件地址或註冊即可下載 本文分為兩部分。第一個展示了網站和登陸頁面模板提供者。第二部分重點介紹儀表板和 UI 套件建立者。 HTML 修訂版 -------- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/08tufzx4fdyi5drm42i8.jpg)](https://htmlrev.com/) [HTMLrev](https://htmlrev.com/)展示免費的 HTML vanilla CSS、Bootstrap、Tailwind、Bulma、Angular、React、Vue、Nextjs、Nuxt、Svelte、Astro、Laravel、Django、Gatsby、Hugo、Jekyll 和 BCMS 模板。可以肯定地說,它是面向 Web 開發人員的最大的免費 HTML 模板庫。您會發現來自世界各地頂級製造商的最佳商品。 **特徵** - 為 Web 開發人員提供的最大的免費範本庫 - 展示頂級創客的最佳作品 - 不斷更新 --- HTML5 升級 -------- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k82m0f3tk6f6tduc3vfk.jpg)](https://html5up.net/) [HTML5 UP](https://html5up.net/)提供免費的 HTML vanilla CSS 模板。可能是同一製造商建立的最大的精心設計的 HTML 模板集合。這意味著所有專案的程式碼品質和設計風格都是一致的。讓設計脫穎而出的是影像背景、漸層疊加、彩色部分和流暢佈局之間的組合。 **特徵** - 由設計驅動的開發人員提供的大量收藏 - 獨特的風格和大量的性格 - 無需註冊即可輕鬆下載 --- 風格吶喊 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttal7mqy1owbufmdr54j.jpg)](https://styleshout.com/) [StyleShout](https://styleshout.com/)提供免費的 HTML 普通 CSS 範本。這些物品美麗、多樣、精美,無需電子郵件或註冊即可下載。所有模板的風格都遵循相同的線條,但絕不感覺重複或無聊。正確的字詞是一致且原創的。主題涵蓋 SaaS、行動應用程式、部落格、即將推出、投資組合和代理商。 **特徵** - 美麗優雅的模板 - 廣泛的用例 - 無需註冊即可輕鬆下載 --- 一頁的愛 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kgdw49kyxcr48nsi4p68.jpg)](https://onepagelove.com/) [One Page Love](https://onepagelove.com/)提供免費+付費的 HTML vanilla CSS 範本。除了他們自己的專案之外,OPL 還具有許多來自其他製造商的針對不同技術的模板 Bootstrap、Nextjs、Tailwind、Carrd、Framer。該演示網站看起來像一個藝術畫廊,使用起來很愉快。您在用例方面的選擇太多了。 **特徵** - 精心製作、專業打磨的模板 - 無需註冊即可輕鬆下載 --- 克魯普 --- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxxvy0xwzzp4znvlv749.jpg)](https://cruip.com/free-templates/) [Cruip](https://cruip.com/free-templates/)提供免費 + 付費的 Tailwind、React、Vue、Nextjs 和 Laravel 範本。它們的獨特之處在於設計的獨創性和對細節的關注。他們提高了標準,我在瀏覽其他商品時經常發現自己在想「這看起來像克魯普風格」。這就是它們的獨特之處。 **特徵** - 獨特而有個性的設計 - 無需註冊即可輕鬆下載 --- 範本 -- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dc4kepier5gix9yznevt.jpg)](https://templatemo.com/) [Templatemo](https://templatemo.com/)提供免費的 Bootstrap 模板。商品數量之多令人驚嘆,而且品質也很棒。在列出的專案中很難不為您的專案找到堅實的基礎。除了看起來不錯之外,模板還以行銷為導向。 **特徵** - 豐富的海量模板集合 - 無需註冊即可輕鬆下載 --- 創意提姆 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2750dlh3rzf6y20v7clk.jpg)](https://www.creative-tim.com) [Creative Tim](https://www.creative-tim.com)提供免費+付費的 Bootstrap、Tailwind、Angular、React、Vue、Nextjs、Nuxt、Svelte、Laravel、Django 和 Astro 專案。絕對是模板和 UI 套件的強大工具。它受到開發人員的喜愛,因為免費專案與高級專案相當。設計精良、打磨光滑、文件齊全。 **特徵** - 設計精美且一致 - 具有進階功能的元件 - 文件自成一體 --- 泰梅斯貝格 ----- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zmhosp1knzec5aql5n4y.jpg)](https://themesberg.com/) [Themesberg](https://themesberg.com/)提供免費+付費的 Bootstrap、Tailwind、React、Laravel、Django 和 Astro 模板。這些資源包括儀表板、登陸頁面、設計系統和 UI 套件。設計品質和精緻程度處於行業領先水平。除了看起來令人驚嘆之外,這些專案的結構和文件都很好。 **特徵** - 很棒的儀表板模板和 UI 套件 - 用於複雜功能的高階元件 --- 模板甲板 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2obnfisjfwrfz42fmqt.jpg)](https://templatedeck.com/) [TemplateDeck](https://templatedeck.com/)提供免費的 Bootstrap 模板。這是一個很棒的資源,提供少量但高品質的物品。描述它們的正確詞彙是極簡主義、創造性和令人印象深刻。公司、個人和創業網站模板均按照最高設計和程式碼標準精心製作。 **特徵** - 示範網站很漂亮且易於瀏覽 - 模板皆經過專業設計與編碼 --- 嘲笑使用者介面 ------- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1h7s8vfp33yquuw49k2.jpg)](https://floatui.com/) [Float UI](https://floatui.com/)提供免費的 Nextjs 範本。它實際上是一個 Tailwind 元件庫,還提供完整的網站模板。用例多種多樣,佈局看起來非常好。它們製作精良,甚至具有微妙的滾動動畫。 **特徵** - SaaS、新創公司、數位產品、課程模板 - 精心設計,具有令人印象深刻的黑暗主題 - 無需註冊即可輕鬆下載 --- 麥可·安德烈扎 ------- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ezbwmkeodvaglh4dx7h.jpg)](https://www.michaelandreuzza.com/resources/) [Michael Andreuzza](https://www.michaelandreuzza.com/resources/)提供免費的 Astro 範本。他是一位極具創意的模板製作者,在他的[列剋星敦主題](https://lexingtonthemes.com/)網站上提供了一系列令人印象深刻的優質專案。他個人網站上列出的免費 Astro 模板因其簡約而時尚的設計而脫穎而出。 **特徵** - 獨特且令人難忘的設計 - 大量的部分和元素 --- 剛剛好的使用者介面 --------- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kyif9plag7l51csjxc3c.jpg)](https://justgoodui.com/) [Just Good UI](https://justgoodui.com/)提供免費 + 付費的 Astro 模板。這是一個有前途的模板建立者,提出了新的願景和設計。網站上提供的免費專案是為部落格和作品集製作的。很高興看到軟體包包含多個頁面和額外元素來盡可能地支援開發人員。 **特徵** - 美麗的簡約設計 - 多個頁面和部分 --- 創業登陸 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvrn4qbh1z1natjqg07r.jpg)](https://startuplanding.redq.io/) [Startup Landing](https://startuplanding.redq.io/)提供免費的 Nextjs 和 Gatsby 模板。它可能是您能找到的最好的完全免費登陸頁面集合。在撰寫本文時,有 18 個可用。設計現代且引人注目。它們混合了圖像背景和精美的彩色插圖。 **特徵** - 設計適用於創意和商業專案 - 廣泛的用例可供選擇 --- Web3模板 ------ [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpz7x6tln49s3jm2ewrt.jpg)](https://web3templates.com/) [Web3Templates](https://web3templates.com/)提供免費 + 付費的 Tailwind、Astro 和 Nextjs 範本。建立者對細節投入了大量精力,為網頁開發人員建立真正有用的資源。設計美觀、富有創意,並且針對轉換進行了最佳化。為您的專案奠定堅實的現成基礎。 **特徵** - 基於插圖的精美創意設計 - 程式碼結構良好,易於定制 --- 蘭化 -- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1on9qnjq84pi8bi2uvl.jpg)](https://www.landify.design) [Landify](https://www.landify.design)提供免費 + 付費的 Gatsby 模板。他們是漂亮的 UI 套件、元件和模板的後起之秀的創造者。他們的免費套裝是為成功的登陸頁面精心製作的。這些設計對於每個用例來說都是現代且一致的。 **特徵** - 令人驚嘆的美麗模板 - 為您的專案奠定良好的基礎 --- Nextjs 模板 --------- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7y3kucjtz6k6elb2qzq9.jpg)](https://nextjstemplates.com/) [Nextjs Templates](https://nextjstemplates.com/)提供免費+付費的 Nextjs 範本。這是一個模板庫,展示了他們自己的和其他製造商的專案。他們自己的免費 Nextjs 範本是綜合包,包含多個頁面、部分和元件,適用於各種用例。設計簡潔、現代且一致。 **特徵** - SaaS、新創公司、商業、軟體、部落格用例 - 令人印象深刻的設計提供多個頁面 - 無需註冊即可輕鬆下載 --- 佈局流程 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sudi6m8q7bnbukyyou8q.jpg)](https://layoutflow.com/) [LayoutFlow](https://layoutflow.com/)提供免費+付費的 HTML vanilla CSS 範本。它們經過專業設計,將為您節省大量創意精力。讓它們脫穎而出的是對負空間和大於平均字體大小的明智使用。代理商、投資組合和服務網站的絕佳資源。 **特徵** - 來自優質製造商的精美模板 - 尖銳的邊緣設計和大膽的排版 --- 模板基礎 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48vqy3i8juxhzcp3y6s3.jpg)](https://www.templatefoundation.com/) [Template Foundation](https://www.templatefoundation.com/)提供免費的 HTML vanilla CSS 範本。物品在佈局、顏色和排版方面都非常現代。他們更關注令人回味的圖像而不是向量插圖。如果您選擇這些範本之一作為您的專案的基礎,您就不會出錯。 **特徵** - 現代時尚的設計引人注目 - 面向作品集和個人網站 - 無需註冊即可輕鬆下載 --- 模板化 --- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6iv9mgzuiq4ppbyy79p.jpg)](https://templated.co/) [Templated](https://templated.co/)提供免費的 HTML vanilla CSS 和 Bootstrap 模板。設計精良、一致且永恆。我認為即使再過幾年它們也不會顯得過時。有很多可用的用例。從企業和新創公司到部落格和投資組合。 **特徵** - 學科範圍廣泛 - 美觀永恆的設計 - 無需註冊即可輕鬆下載 --- 免費贈品bug ------- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1r5lbexk8rad43ikp84o.jpg)](https://freebiesbug.com/) [Freebiesbug](https://freebiesbug.com/)提供免費的 HTML vanilla CSS Bootstrap、Tailwind 和 React 模板。高品質的設計注重細節。除了 Cruip 團隊自己的作品外,他們還展示了其他頂級製造商製作的現成包裝。 **特徵** - 精美的營銷優化佈局 - 自己的專案,還有範本庫 - 無需註冊即可輕鬆下載 --- 啟動引導程式 ------ [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ra8bxapn981gmumstqdx.jpg)](https://startbootstrap.com/) [Start Bootstrap](https://startbootstrap.com/)提供免費+付費的Bootstrap模板。它是新創公司、代理商、投資組合、個人和部落格的優質專案的既定來源。它甚至提供功能豐富的管理儀表板模板。它們的建置標準非常高,人們甚至可以向它們學習 Web 開發。 **特徵** - 令人難以置信的精心建置和多樣化的模板 - 設計遵循形式遵循功能原則 - 無需註冊即可輕鬆下載 --- 怪物一號 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/676v0czfivfinfvbobux.jpg)](https://monsterone.com/html-templates/free-website-templates/) [MonsterOne](https://monsterone.com/html-templates/free-website-templates/)提供免費+付費的 HTML vanilla CSS 和 Bootstrap 模板。它實際上是 Template Monster 的基於訂閱的模板庫。如果您註冊免費帳戶,您無需支付訂閱費用即可存取免費物品。它們的品質很高,但您需要手動檢查哪些是普通 CSS,哪些是 Bootstrap。 **特徵** - 具有多個頁面的現代模板 - 由於製造商眾多,品質參差不齊 --- 範本叢林 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mvfietep6jonyv9bidn.jpg)](https://templatesjungle.com/) [TemplatesJungle](https://templatesjungle.com/)提供免費+付費的 HTML vanilla CSS 和 Bootstrap 模板。設計很棒,以行銷為導向,涵蓋多種用例。商業、代理商、服務、投資組合、電子商務。您會找到適合您能想像到的幾乎任何主題的模板。 **特徵** - 大量精心設計的模板可供選擇 - 設計令人印象深刻,讓您的專案脫穎而出 --- 第三波媒體 ----- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/le1r0xzgu167v6ggdq9q.jpg)](https://themes.3rdwavemedia.com/freebies/) [3rd Wave Media](https://themes.3rdwavemedia.com/freebies/)提供免費+付費的 Bootstrap 模板。它們是清單中對開發人員最友善的資源之一。它是由開發者為開發者製作的,體現在設計效率和程式碼結構上。模板結構良好且以結果為導向。您會找到適合各種主題的專案。 **特徵** - 有大量用例可供選擇 - 無需註冊即可輕鬆下載 --- 車頂板 --- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rz09nou89dnn3cutgzbf.jpg)](https://www.tooplate.com/) [Tooplate](https://www.tooplate.com/)提供免費的 Bootstrap 模板。它是一個巨大的精心設計的 Bootstrap 模板庫。設計現代且精美。每個模板都經過精心設計,可在所有裝置上呈現良好效果。廣告有時可能會造成乾擾,但好的一面是下載不受限制且不需要註冊。 **特徵** - 各種 Bootstrap 模板的大集合 - 高級產品專用的高級元件 - 無需註冊即可輕鬆下載 --- 像素火箭 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ubqga6p7ox5innn3532.jpg)](https://pixelrocket.store/free-templates) [Pixel Rocket](https://pixelrocket.store/free-templates)提供免費的 Bootstrap 和 Tailwind 範本。這個小系列的現代配色看起來令人驚嘆。每個專案都包含許多基本和高級部分和元件。涵蓋的用例包括電子商務、儀表板、作品集和商業網站。 **特徵** - 高品質模板小集合 - 無需註冊即可輕鬆下載 --- HTML 法典 ------- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axduylz8rghwm6umiztd.jpg)](https://htmlcodex.com/) [HTML Codex](https://htmlcodex.com/)提供免費+付費的 Bootstrap 模板。這些專案看起來不錯,並且可以不受任何限制地下載。多個用例之間存在巨大差異。業務、課程、產品、代理商、服務、作品集、履歷等等。適合每個人的東西。 **特徵** - 針對各種用例的以結果為導向的設計 - 基於微妙滾動的動畫,帶來更好的使用者體驗 - 無需註冊即可輕鬆下載 --- W3佈局 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x85jgxjgly0zj8nn53gm.jpg)](https://w3layouts.com/) [W3Layouts](https://w3layouts.com/)提供免費+付費的 Bootstrap 模板。基本上他們網站上的所有模板都是免費提供的,但為了刪除歸屬連結,您必須支付少量費用。要免費取得它們,只需檢查試玩版下方的「免費下載」按鈕即可。有點難發現。 **特徵** - 大量的商業風格模板 - 涵蓋廣泛的用例 --- 引導帶 --- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d5f28ecptq06wr0ihvc7.jpg)](https://bootstrapious.com/) [Bootstrapious](https://bootstrapious.com/)提供免費+付費的 Bootstrap 模板。 Web 開發人員可以從各種現成的程式碼和設計套件中進行選擇。設計看起來不錯,有些免費物品包含高級元件。唯一的小缺點是您需要提供電子郵件地址才能下載專案。 **特徵** - 各種主題的大量免費物品 - 有些設計特別好 --- 溫樹 -- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysunwzk28eg703cwxki8.jpg)](https://untree.co/) [Untree](https://untree.co/)提供免費的 Bootstrap 模板。它們幫助開發人員節省時間和金錢。物品設計精美,非常注重細節。模板具有許多特色,並帶有多個頁面和高級元件。下拉導覽、滑桿和微妙的動畫等功能將使您的工作更加輕鬆。 **特徵** - 設計有個性,不重複 - 無需註冊即可輕鬆下載 --- 順風工具箱 ----- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1gnbs90ot43hn96ekkk.jpg)](https://www.tailwindtoolbox.com/) [Tailwind Toolbox](https://www.tailwindtoolbox.com/)提供免費 + 付費的 Tailwind 範本。專案是他們自己的,並由其他頂級模板製作者展示。設計結構良好,涵蓋最受歡迎的用例,如新創公司、SaaS、行動應用程式、部落格和管理儀表板。 **特徵** - 漂亮的專案,結構良好,程式碼乾淨 - 專案涵蓋廣泛的用例 - 無需註冊即可輕鬆下載 --- 像素洞穴 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1qg3tmq1f2xbbihol89c.jpg)](https://pixelcave.com/) [Pixelcave](https://pixelcave.com/)提供免費 + 付費的 Tailwind 模板。軟體包專用於建立網站和管理介面。免費的網站和儀表板模板具有現代的配色方案和以結果為導向的佈局。由於它們是由同一作者製作的,所以一致性很普遍。 **特徵** - 獨特的設計可幫助您的專案脫穎而出 - 乾淨的展示網站,沒有廣告 - 無需註冊即可輕鬆下載 --- 主題漁夫 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dl89v5po9st2ad83io98.jpg)](https://themefisher.com/) [Themefisher](https://themefisher.com/)提供免費 + 付費的 Nextjs 和 Astro 模板。它基本上是一個模板市場,為 Web 開發人員提供基於各種框架類別建構的套件。專案經過創意設計,並為商業、SaaS 和部落格網站提供多個頁面。 **特徵** - 精心設計的多頁面模板 - 易於瀏覽的示範網站 --- 尾火 -- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9dduazx5klc5wibm5fkt.jpg)](https://tailspark.co/) [Tailspark](https://tailspark.co/)提供免費 + 付費的 Tailwind 模板。即使它們的專案編號不足,它們也可以透過提供的元件來彌補。這些模板是該系列中最複雜、功能最豐富的資源之一。您將獲得許多採用華麗設計的元件、部分和頁面。 **特徵** - SaaS 網站和登陸頁面的最佳選擇 - 幾個巨大的、功能豐富的模板 --- 紅色像素主題 ------ [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mg2xmdb5jhouypat66ul.jpg)](https://redpixelthemes.com/) [紅色像素主題](https://redpixelthemes.com/)提供免費+付費的Tailwind模板。開發者專注於簡化 Web 開發工作。設計很棒,佈局包含大量有用的元件。基本上有 2 個模板,一個用於作品集,另一個用於部落格。為您的專案提供良好的起點。 **特徵** - 幾個好看的免費模板 - 部落格和作品集用例 --- 阿里·布丁 ----- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zmmt2ppmz1qoje0r35b.jpg)](https://aribudin.gumroad.com/) [Ari Budin](https://aribudin.gumroad.com/)提供免費 + 付費的 Tailwind 模板。免費物品集合雖小但很有用。設計獨特,將幫助您的專案脫穎而出。主題涵蓋代理商、作品集、雜誌和設計系統。作品集模板具有豐富的特色,一定會帶給您啟發。 **特徵** - 精選免費優質物品 - 投資組合和代理模板脫穎而出 --- 特雷克特 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8dzak35uivlm48ps8nol.jpg)](https://treact.owaiskhan.me/) [Treact](https://treact.owaiskhan.me/)提供免費的 React 模板。它擁有令人印象深刻的網站和登陸頁面模板集合。這個圖書館雖小但內容豐富,為新創公司、SaaS 和服務提供設計精美的現成物品。配色方案使用了許多現代技術佈局特有的藍色調。 **特徵** - 帶有額外頁面的登陸頁面模板 - 易於自訂的元件塊 --- 程式碼設計 ----- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jgm9wwgaxrvgeiz11a2p.jpg)](https://designtocodes.com/) [DesignToCodes](https://designtocodes.com/)提供免費+付費的 Bootstrap 和 Tailwind 範本。涵蓋的用例包括新創公司、代理商和投資組合網站。您也可以找到結構良好的管理儀表板範本。設計經過精心設計和建置,並牢記行銷目標。 **特徵** - 很棒的網站和儀表板模板 - 針對行銷結果優化佈局 --- 使用者介面庫 ------ [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2i1gk5ui7b3o1f02yf3y.jpg)](https://ui-lib.com/) [UI Lib](https://ui-lib.com/)提供免費 + 付費的 Bootstrap、Tailwind、Angular、React 和 Vue 模板。它涵蓋了從即將推出的專案和登陸頁面到管理儀表板和 UI 工具包的整個範圍。專案設計精良,易於自訂,包裝中附有用的文件。 **特徵** - 模板涵蓋多種用例 - 有些帶有有用的高級元件 --- 管理市場 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2yhvhu68eoj080wwivc.jpg)](https://adminmart.com/) [AdminMart](https://adminmart.com/)提供免費+付費的 Bootstrap、Tailwind、Angular、React、Vue、Nextjs 和 Nuxt 模板。使用案例涵蓋 SaaS 登陸頁面、教育、課程、代理商、服務網站和管理儀表板。物品經過專業設計,並配有許多部分和元件。 **特徵** - 多個框架的多個用例 - 物品可用於商業專案 --- 包裹像素 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7kwvjgp027tiqije3fiu.jpg)](https://www.wrappixel.com/) [WrapPixel](https://www.wrappixel.com/)提供免費 + 付費的 Bootstrap、Tailwind、Angular、React、Vue、Nextjs 和 Nuxt 模板。它們的與眾不同之處在於對儀表板和 UI 套件的一貫關注。在設計和結構方面有很多選擇。您可以選擇經典佈局或更富有創意的佈局。 **特徵** - 儀表板模板和 UI 套件的可靠集合 - 不同的設計和配色可供選擇 --- 桌子 -- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qjlhiy7n7tyoxp2gjjqv.jpg)](https://tabler.io/) [Tabler](https://tabler.io/)提供免費的 Bootstrap 模板。專注於儀表板,因為 Tabler 本身是專門用於建立 Web 應用程式的管理儀表板 UI 套件。如此大而精美的軟體包竟然可以免費取得,真是令人難以置信。設計很棒,文件很全面,程式碼結構很好。這個資源是寶石。 **特徵** - 專注於儀表板的引導模板 - 頂級的設計和程式碼品質 - 許多優質的先進元件 --- 敏銳的主題 ----- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1hauyits355t5dw5ied.jpg)](https://keenthemes.com/) [KeenThemes](https://keenthemes.com/)提供免費 + 付費的 Bootstrap、React 和 Vue 模板。該建立者專門研究儀表板模板。每個包都配有多個採用現代設計的節省時間的元件。有不同的風格可供選擇,適應多種可能的場景。 **特徵** - 在網頁應用程式管理儀表板上佔有一席之地 - 乾淨的網站,沒有廣告或其他煩惱 --- BootstrapDash ------------- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yl1ymof4pdxzmangcy4v.jpg)](https://www.bootstrapdash.com/) [BootstrapDash](https://www.bootstrapdash.com/)提供免費+付費的 Bootstrap 模板。有用的集合集中在管理儀表板上。軟體包包含的頁面和元件非常豐富。設計始終保持現代感,並針對效果進行了最佳化。網站沒有廣告,瀏覽起來很愉快。 **特徵** - 很棒的儀表板模板 - 廣泛的設計風格 --- 編碼主題 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3u1oseo5vj4g5mnnn6q.jpg)](https://codedthemes.com/) [CodedThemes](https://codedthemes.com/)提供免費+付費的 Bootstrap、Angular、React 和 Vue 模板。製造商專注於管理儀表板和完整的 UI 套件。他們的工藝水平透過產品品質而閃耀。包裝經過精心組裝,採用精美的設計,給人一種準備就緒的感覺。 **特徵** - 設計精美的物品具有先進的元件 - 網站瀏覽很愉快,沒有煩人的廣告 --- 丹參套件 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpy8f28sb9gbkw9kz5ol.jpg)](https://www.salvia-kit.com) [Salvia Kit](https://www.salvia-kit.com)提供免費的 Angular、React、Vue、Nuxt 和 Svelte 範本。它是您可以免費下載的最好的管理儀表板集合之一。套件使用戶能夠為各種 Web 應用程式建立美觀且高效的介面。有不同的視覺風格和多個元件可用。 **特徵** - 高度關注管理儀表板模板 - 同一開發商打造的品質一致 --- 煮沸 -- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0dl17974czs5ru0eg2s2.jpg)](https://justboil.me/) [JustBoil](https://justboil.me/)提供免費 + 付費的 Tailwind、React、Vue、Nextjs、Nuxt 和 Laravel 模板。在這裡,您將找到一些用於建立出色的 Web 應用程式介面的最佳儀表板範本。佈局是為了可用性而精心設計的,設計是以效率為導向的。 **特徵** - 不斷更新的專業模板 - 以結果為導向的高效佈局 --- 主題選擇 ---- [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tiizky4chnasi713lck.jpg)](https://themeselection.com/) [ThemeSelection](https://themeselection.com/)提供免費 + 付費的 Vue、Nextjs、Nuxt 和 Laravel 模板。製造商專注於管理儀表板和 UI 套件。免費物品設計精良,與優質物品不相上下。很棒的現成包可幫助開發人員更快地啟動專案。 **特徵** - 結構良好的美麗物品 - 模組化且易於定製程式碼 --- 愛康尼克設計 ------ [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vngpaoo80t2gcaysk7uh.jpg)](https://iqonic.design/) [Iqonic Design](https://iqonic.design/)提供免費 + 付費的 React 和 Vue 模板。儘管製造商在 HTML 專案方面建立了 Flutter 和 WordPress 主題,但他們專注於管理儀表板。有一些免費的軟體包可以幫助網頁開發人員建立現代介面。 **特徵** - 精心設計的儀表板模板 --- 為了整理這篇綜述,我瀏覽了所有可以想像的可以找到模板的線上資源。我希望它能讓你的工作更輕鬆。 --- 原文出處:https://dev.to/devluc/50-best-websites-for-free-html-templates-1i2l

17 個值得嘗試的最佳開發人員生產力工具

效率和生產力不僅是開發人員的目標,也是必需品。我們製作了大量的工具並編寫了日常任務的腳本,所有這些都是為了騰出時間來處理真正重要的事情。在當今龐大的開發者生態系中,一系列[生產力工具](https://www.devzero.io/blog/ai-tools-for-software-developers-in-2023-to-boost-dev-productivity)隨時可以簡化我們的工作流程。 生產力工具的作用不僅僅是減少重複性任務的[時間](https://www.devzero.io/blog/time-management-tools-and-tips-boosting-productivity-for-software-developers)。它們在管理程式碼和促進團隊協作方面至關重要。借助正確的工具包,開發人員可以將注意力從平凡轉向創新,以新的自由度來應對創意挑戰。讓我們深入了解頂級開發者生產力工具,以在 2024 年提升您的遊戲水平。 衡量開發人員的生產力 ---------- 首先,讓我們解決一個基本問題:我們如何衡量開發人員的生產力?開發人員的日常生活不僅包括編寫程式碼,因此衡量生產力需要廣泛審視整個軟體開發過程的效率和有效性。 我們可以追蹤熟悉的指標,例如程式碼行數、開發的功能、修復的錯誤和交付時間表。然而,真正理解生產力需要一種整體方法,一種權衡軟體開發的有形和無形方面的方法。因此,考慮品質、影響和協作也很重要。 了解生產力工具 ------- 接下來,我們來詳細分析開發人員可以使用的不同類型的生產力工具: - IDE、程式碼編輯器和助手是任何開發人員武器庫的基石,為編碼、編輯、測試和除錯提供整合平台。 - 開發環境確保開發人員可以專注於編寫程式碼,而不是管理基礎架構。 - 專案管理和協作工具對於組織任務、追蹤進度和確保團隊溝通順暢至關重要。 - 設計和原型工具使開發人員能夠製作引人注目的視覺設計並改進其應用程式的 UI/UX。 - 偵錯工具對於快速辨識和修復錯誤和其他程式碼問題至關重要。 - 框架和抽象可以幫助開發人員透過重複使用通用元件更快地交付程式碼。 - 部署應用程式是最後一步,但確保效能和穩定性是關鍵。 從編碼的基礎工作到使用者介面和團隊協作的微調,每個類別在提高生產力方面都發揮著至關重要的作用。 IDE、程式碼編輯器和助手 ------------- 讓我們來看看 2024 年一些流行的 IDE 和程式碼編輯器。 1. IntelliJ IDEA --------- [IntelliJ IDEA](https://www.jetbrains.com/idea/)是 Java 和 Kotlin 開發人員的首選 IDE,提供的綜合[開發環境](https://www.devzero.io/blog/why-software-development-environments-are-important-and-how-to-manage-them-effectively)遠遠超出 Atom 等簡單程式碼編輯器所提供的功能。此 IDE 具有出色的高級功能,例如深入程式碼理解以實現卓越的導航和重構。與基本編輯器不同,IntelliJ 整合了資料庫和版本控制的基本工具,透過讓您所需的一切觸手可及來簡化您的工作流程。 IntelliJ 社群版免費提供,並提供對其功能的廣泛探索,但存取權限僅限於學生、BootCamp 成員和特定焦點小組。對於其他人來說,專業版的價格約為每月 20 美元,並且可以完全存取 IntelliJ 強大的工具套件。 2. Visual Studio Code -------------------- Microsoft 的[Visual Studio Code](https://code.visualstudio.com/)是跨所有框架、語言和程式庫的開發人員的首選程式碼編輯器。其突出的特點是一個龐大的擴展庫,旨在提高生產力。想像一下,利用 TabNine 進行 AI 驅動的程式碼補全,或整合 GitHub Copilot,利用其 AI 輔助功能將編碼速度提高十倍。除此之外,Visual Studio Code 還提供內建的 Git 控制、用於 shell 命令的整合終端以及用於無縫程式碼分析的專用偵錯器。 最重要的是,它完全免費,並且與 Windows、Mac 和 Linux 平台普遍相容。 3. AppMap ------- [AppMap](https://www.appmap.io/)是一種視覺化工具,可提供應用程式程式碼庫內互動的詳細概述。它為開發人員提供了整個應用程式中資料流和控制的圖形表示,幫助他們更直觀地理解複雜的系統。透過 AppMap,開發人員可以輕鬆瀏覽不同的元件,了解模組之間的依賴關係,並確定潛在的最佳化或重構領域。透過直觀地繪製應用程式的內部工作原理,AppMap 增強了開發團隊之間的協作,並有助於在開發過程中做出更好的決策。 Appmap 最近推出了 Navie。 Navie 是一種生成編碼 AI,具有 API 和資料庫感知能力,因此它可以為整個程式碼庫中的複雜變更提供程式碼建議。 Navies 回答並建議針對開發人員問題進行程式碼更改,例如「我的資料庫查詢效能很慢。我如何解決它?或“我需要更改令牌系統以提高身份驗證安全性,我該如何進行?” ‍ 海軍的建議針對每位開發人員及其正在開發的軟體進行高度個人化,同時確保您的 IP 安全。 4.Copilot ----- 向無可爭議的版本控制統治者屈服:GitHub。憑藉其一系列強大的功能,包括透過 GitHub 工作流程進行自動化部署、 [GitHub Copilot](https://github.com/features/copilot)的人工智慧驅動協助以及 Dependabot 的主動安全修補,GitHub 處於開發創新的前沿。就像 Visual Studio Code 是編碼的首選一樣,GitHub 是開發人員進行版本控制的首選平台。 GitHub 的免費套餐包含豐富的產品,非常適合小型團隊、獨立開發人員、自由工作者和新創公司。但對於大型組織和企業來說,Teams 計劃(每位使用者每月3.67 美元)和Enterprise 計劃(每位使用者每月19.25 美元)解鎖了一系列高級功能,例如GitHub Codespaces,這是與GitHub 無縫整合的虛擬IDE,可直接在平台內進行編碼。此外,付費方案還提供增強的協作功能,例如能夠任命多個拉取請求審閱者和指定程式碼擁有者,從而簡化開發流程並確保程式碼品質。 ‍ 此類別中出現的另外兩個工具是[SuperMaven](https://supermaven.com/)和[TabbyML](https://github.com/TabbyML/tabby) ,兩者都使用快速且安全的 LLM 來完成程式碼完成和建議。 開發環境 ---- 在當今的微服務和複雜的基於雲端的服務和第三方庫的世界中,本地主機無法提供所需的適當環境。這會導致整個 SLDC 不斷重構並減慢部署週期。 5.DevZero --------- [DevZero](https://www.devzero.io/)是一個為開發人員在雲端提供一致的、類似生產的開發環境的平台。開發人員可以在他或她的本機電腦上工作,但仍然體驗生產環境的所有細微差別,例如資料庫、雲端原生服務等。到生產都是一致的。新開發人員只需幾分鐘即可入職,而不是幾天。這使工程組織具有一致性和易於管理。不再除錯本機。 DevZero 的一個顯著優勢是縮短了 CI 時間。開發人員可以節省重構和編譯基礎架構處理所花費的寶貴時間,因為現在他們可以立即在生產環境中執行本機程式碼。這也提高了整體發布頻率並消除了在不同環境中進行測試的障礙。 協作和專案管理 ------- 開發人員經常處理無數的選項卡,並且可能會跨多個顯示器進行操作,但切換平台以進行協作和任務管理的想法可能是一個真正的痛點。讓我們深入研究一些旨在提高開發人員生產力和促進無縫團隊協作的關鍵工具。 6. Slack ----- Slack 徹底改變了遠端協作,使公司能夠即時通訊和共享文件。對於開發人員來說,它是協作的動力源泉,可與 GitHub 等工具無縫集成,以即時更新程式碼推送或部署。這種整合確保每個人都能及時了解專案狀態,而無需不斷地來回訊息。您可以透過 Slack 的整合使用任何專案管理工具,例如 Trello、JIRA 等。 Slack 透過可自訂的工作流程和應用程式進一步發展,讓平台內任務和問題管理。雖然免費計劃支援基本通訊和最多十個集成,但要擴展到自訂自動化及其他功能,需要升級到專業計劃(每人每月 8.25 歐元)或商業計劃(每人每月 14.10 歐元)。這種靈活性使 Slack 成為追求效率和簡化工作流程的開發團隊不可或缺的工具。 7. Height ----- 在管理專案和維持組織性方面,擁有可靠的工作追蹤工具至關重要。 [Height](http://height.app/)是一款功能強大的專案管理工具,提供廣泛的功能,旨在簡化協作並最大限度地提高效率。借助 Height,開發人員可以輕鬆分配任務、設定截止日期、追蹤進度並監控團隊績效。其直覺的收件匣式介面和強大的分析功能使其成為希望掌控工作量並按時交付專案的團隊的首選。 8. Linear ----- [Linear.app](https://linear.app/)是一個專案管理和問題追蹤工具,旨在幫助團隊更有效地協作和管理工作。 Linear 提供了一個用於組織任務、追蹤進度和促進團隊成員之間溝通的平台。該工具以其時尚且用戶友好的介面而聞名。 9. Pullflow ----- 審查 PR 很多時候是工程組織的瓶頸。它不像編寫程式碼那樣有回報,並且需要上下文切換。 [Pullflow](https://pullflow.com/)旨在透過其人工智慧增強的程式碼審查協作功能來減少上下文切換並改善溝通和公關管理。 Pullflow 整合了 VSCode、Github 和 Slack 之間的 PR 通信,因此開發人員無需進行上下文切換。 設計和原型製作工具 --------- 開發人員從頭開始精心設計設計並仔細考慮每個佈局、顏色和字體選擇的時代已經演變。今天的 UI/UX 開發人員享受 Figma 等工具的重大飛躍,其中設計與程式碼相結合。讓我們詳細探討一下。 10. Figma ------- [Figma](https://www.figma.com/)透過提供可無縫整合到專案中的現成程式碼片段,徹底改變了設計到開發流程。在過去的一年裡,Figma 推出了許多插件,為 React、Vue 甚至 HTML 等流行框架提供樣板元件,並支援 Figma 設計直接轉換為 Webflow。 FigJam 是一項出色的功能,事實證明,它對於規劃和確定建造和發布的範圍、衝刺規劃和製作架構圖非常有價值。它在協作和策略規劃階段的效用怎麼強調都不為過。 由於其基於網路的特性,Figma 提供了無與倫比的易用性,並輔以適用於 Windows 和 macOS 的專用桌面應用程式。您需要加入其中一項付費方案才能使用開發模式並存取所有設計元素的程式碼。如果您使用組織計劃,您甚至可以使用私人插件。 11.Whimsical和Excalidraw ------------------ 在解釋複雜概念或設計系統架構時,圖表和視覺化通常是必不可少的。 [Excalidraw](https://excalidraw.com/)和[Whimsical](https://whimsical.com/)是兩種流行的快速繪圖工具,可讓開發人員輕鬆建立圖表。憑藉其簡單而強大的介面,開發人員可以立即建立線框、流程圖和其他視覺表示。這些工具非常適合集思廣益並向利害關係人展示概念,使它們成為開發人員工具包的寶貴補充。 偵錯工具 ---- 除錯是軟體開發生命週期中最具挑戰性和最耗時的部分之一。然而,正確的警報和監控系統可以節省無數時間。讓我們深入研究可以顯著簡化除錯過程、提高效率並減少開發工作流程中的停機時間的基本工具。 12.Postman ----- [Postman](https://www.postman.com/)已成為測試和記錄 API 的基礎 API 開發工具,因其在除錯生產和本地 API 方面的強大能力而贏得了開發人員的廣泛認可。它使用戶能夠發送和模擬 HTTP 請求,這項功能對於等待後端 API 準備就緒的前端開發人員特別有利,可確保持續進展。 除了在測試中的實用性之外,Postman 還充當 API 文件的集中儲存庫,促進團隊內的無縫共享和協作。其基本計劃(每個用戶每月 14 美元)對於大多數開發人員來說應該足夠了。 13.Sentry ----- [Sentry](https://sentry.io/)是效能監控和錯誤追蹤領域的強大工具,擅長自動辨識程式碼庫中的錯誤和錯誤。 Sentry 的 SDK 適用於幾乎所有廣泛使用的框架和技術(包括 JavaScript、PHP、Python 和 Ruby),可無縫整合到您的專案中。 檢測到錯誤後,Sentry 會提供全面的見解,例如堆疊追蹤、來源頁面和使用者訊息,這些對於有效診斷和解決問題非常寶貴。此外,程式碼覆蓋率和會話重播等功能被證明是不可或缺的,尤其是在面臨重現難以捉摸的錯誤的艱鉅任務時。 Sentry 的功能確保開發人員可以花更少的時間進行故障排除,而將更多的時間用於開發,從而提高整體生產力和程式碼品質。 您可以嘗試 Sentry 及其免費的單獨開發者計畫。然而,為了充分利用它,我建議嘗試團隊計劃(每月 26 美元),您可以將隊友加入到 Sentry 工作區。您還需要每月支付 29 美元購買程式碼覆蓋率。 框架和抽象 ----- 當今的許多元件在應用程式中都很常見:身份驗證、授權、資料庫存取、UI 元件等。寫內容從頭開始。 14.Vercel ------ 建置和部署 Web 應用程式可能是一項複雜的任務,尤其是當專案規模不斷擴大時。 Web 應用程式部署框架(例如 Vercel)為開發人員提供了簡化且可擴展的解決方案來部署其 Web 應用程式。 [Vercel](https://www.vercel.com/)是一個雲端平台,旨在簡化 Web 應用程式的部署和託管。它以專注於透過提供自動部署、無伺服器功能和全球內容交付等功能為開發人員提供無縫體驗而聞名。 15. Neurelo ------ [Neurelo](https://www.neurelo.com)為您的資料 API 提供了一個與資料庫無關的程式設計介面。 Neurelo 無需學習 MongoDB 或 PostgreSQL 的查詢語言並為它們建立 API,而是在幾分鐘內為您提供優化的自動生成的 API,包括模式建置器,以及使用 Git 管理開發、登台和生產環境的界面類似版本控制來管理追蹤更改。最後,它使用人工智慧提供自動生成的文件以及透過點擊生成和測試複雜查詢的能力。 許多公司最終會產生自己的抽象層來管理開發人員的資料庫存取或使用 SQLAlchemy 或 Hibernate 等物件關係映射器 (ORM)。 Neurelo 建立了一個通用的強大且與資料庫無關的替代方案。 部署應用程式 ------ 16. Fly.io --------- 部署應用程式可能是一個複雜且耗時的過程。應用程式部署工具(例如[Fly.io](http://fly.io/) )旨在透過提供一個用於輕鬆部署和管理應用程式的平台來簡化此流程。 ‍ Fly.io是一個提供全球應用部署網路的平台。它允許開發人員在跨越全球多個地點的分散式基礎設施上部署和執行他們的應用程式。 Fly.io 專注於透過將應用程式執行個體分佈在更靠近最終用戶的位置來優化應用程式效能,減少延遲並改善整體用戶體驗。 ‍ 該平台支援各種程式語言和框架,使開發人員能夠部署各種應用程式,包括Web應用程式、API和微服務。 Fly.io 使用邊緣運算和全球選播網路的組合來最佳化路由並確保使用者要求定向到最近的可用應用程式實例。 17. Tigris ----------- [Tigris](https://www.tigrisdata.com/)是一種與 S3 相容的全球分散式物件儲存服務,它將資料儲存為物件儲存桶中。物件是一個文件和描述該文件的任何元資料。桶子是存放物件的容器。 ‍ 哪個才是最好的開發工具? ------------ 只要您的武器庫中擁有每個類別中的任何一種工具,您就可以開始使用了。但如果我必須為您選擇一種工具,我會選擇 Visual Studio Code。它因其多功能性、對語言和框架的廣泛支援以及強大的擴展生態系統而脫穎而出,使其成為首選。 工程生產力工具 ------- 工程生產力工具支援軟體開發的特定工程方面。這可能包括分析、自動化測試、部署、容器化或靜態程式碼分析。使用這些工具,您可以確保程式碼品質和效能,並在開發週期的早期發現潛在問題。一些常見的工程生產力工具包括Docker、Jenkins、Confluence、JIRA等。 結論 我很想知道 2024 年您會從這個[清單](https://www.devzero.io/blog/how-to-calculate-developer-productivity-metrics-using-mergestat-and-devzero)中選擇哪種工具。從本質上講,GitHub 和 Visual Studio Code 是 2024 年的必備工具。我仍在研究它們,誰知道呢,它們可能會出現在 2025 年的清單中。 本文原刊於 https://www.devzero.io/blog/best-developer-productivity-in-2024 --- 原文出處:https://dev.to/shohams/17-best-developer-productivity-tools-to-try-1a2a

使用 NextJS 和 Wing 建立您自己的 ChatGPT 圖形客戶端 🤯

--- 標題:使用 NextJS 和 Wing 建立您自己的 ChatGPT 圖形客戶端 🤯 描述:使用 Winglang 和 NextJS 建立的 ChatGPT 客戶端應用程式 canonical\_url:https://www.winglang.io/blog/2024/05/16/chatgpt-client-with-nextjs-and-wing 發表:真實 --- 長話短說 ---- 在本文結束時,您將使用 Wing 和 Next.js 建置並部署 ChatGPT 用戶端。 該應用程式可以在本地執行(在本地雲端模擬器中)或將其部署到您自己的雲端提供者。 ![舞蹈](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1sm2cj4sbcm4skp0ho23.gif) --- 介紹 -- 建置 ChatGPT 用戶端並將其部署到您自己的雲端基礎架構是確保對資料進行控制的好方法。 將 LLM 部署到您自己的雲端基礎架構可為您的專案提供隱私和安全性。 有時,在使用 OpenAI 的 ChatGPT 等專有 LLM 平台時,您可能會擔心資料在遠端伺服器上儲存或處理,這可能是由於輸入平台的資料的敏感度或其他隱私原因。 在這種情況下,將 LLM 自託管到您的雲端基礎架構或在您的電腦上本地執行可以讓您更好地控制資料的隱私和安全性。 > [Wing](https://git.new/wing-repo)是一種面向雲端的程式語言,可讓您建置和部署基於雲端的應用程式,而無需擔心底層基礎架構。 它允許您使用相同的語言定義和管理雲端基礎架構和應用程式程式碼,從而簡化了您在雲端上建置的方式。 Wing 與雲端無關——用它建置的應用程式可以編譯並部署到各種雲端平台。 > {% cta https://git.new/wing-repo %} 看 ⭐ Wing {% endcta %} [![給我們一顆星星](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rg63klimgm7s0aw72rn2.png)](https://git.new/wing-repo) --- 讓我們開始吧! ------- 要繼續操作,您需要: - 對 Next.js 有一定了解 - 在您的機器上[安裝 Wing](https://www.winglang.io/docs/) 。如果您不知道如何操作,請不要擔心。我們將在這個專案中一起討論它。 - 取得您的 OpenAI API 金鑰。 建立您的專案 ------ 首先,您需要在電腦上安裝 Wing。執行以下命令: ``` npm install -g winglang ``` 透過檢查版本確認安裝: ``` wing -V ``` ### 建立您的 Next.js 和 Wing 應用程式。 ``` mkdir assistant cd assistant npx create-next-app@latest frontend mkdir backend && cd backend wing new empty ``` 我們已在 Assistant 目錄中成功建立了 Wing 和 Next.js 專案。我們的 ChatGPT 用戶端的名稱是 Assistant。聽起來很酷,對吧? 前端和後端目錄分別包含我們的 Next 和 Wing 應用程式。 `wing new empty`建立三個檔案: `package.json` 、 `package-lock.json`和`main.w` 。後者是應用程式的入口點。 ### 在 Wing 模擬器中本地執行您的應用程式 Wing 模擬器可讓您在本機電腦內執行程式碼、編寫單元測試和偵錯程式碼,而無需部署到實際的雲端供應商,從而幫助您更快地進行迭代。 使用以下命令在本機上執行您的 Wing 應用程式: ``` wing it ``` 您的 Wing 應用程式將在`localhost:3000`上執行。 ![安慰](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5ytrntrz7lc5225w8w8.png) 設定您的後端 ------ - 讓我們安裝 Wing 的 OpenAI 和 React 函式庫。 OpenAI 庫提供了與 LLM 互動的標準介面。 React 程式庫可讓您將 Wing 後端連接到 Next 應用程式。 ``` npm i @winglibs/openai @winglibs/react ``` - 將這些套件匯入到`main.w`檔案中。我們還導入需要的所有其他庫。 ``` bring openai bring react bring cloud bring ex bring http ``` `bring`是 Wing 中的導入語句。這樣想,Wing 使用`bring`來實現與 JavaScript 中`import`相同的功能。 `cloud`是 Wing 的雲端庫。它公開了雲端 API、儲存桶、計數器、網域、端點、函數和更多雲端資源的標準介面。 `ex`是用於與表格和雲端 Redis 資料庫介面的標準庫, `http`用於呼叫不同的 HTTP 方法 - 從遠端資源發送和檢索資訊。 取得您的 OpenAI API 金鑰 ------------------ 我們將在我們的應用程式中使用`gpt-4-turbo`但您可以使用任何 OpenAI 模型。 - 如果您還沒有[OpenAI](https://platform.openai.com/signup)帳戶,請建立一個。若要建立新的 API 金鑰,請前往[platform.openai.com/api-keys](http://platform.openai.com/api-keys)並選擇**建立新金鑰。** ![OpenAI 金鑰](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9645jxsf1fj8902iwnr7.png) - 設定**名稱**、**專案**和**權限,**然後按一下**建立金鑰。** ![OpenAI Key2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yng28wns7esezf94t3uq.png) 初始化 OpenAI ---------- 建立一個`Class`來初始化您的 OpenAI API。我們希望它可以重複使用。 我們將向`Assistant`類別加入`personality` ,以便在向 AI 助手傳遞提示時可以指定 AI 助手的個性。 ``` let apiKeySecret = new cloud.Secret(name: "OAIAPIKey") as "OpenAI Secret"; class Assistant { personality: str; openai: openai.OpenAI; new(personality: str) { this.openai = new openai.OpenAI(apiKeySecret: apiKeySecret); this.personality = personality; } pub inflight ask(question: str): str { let prompt = `you are an assistant with the following personality: ${this.personality}. ${question}`; let response = this.openai.createCompletion(prompt, model: "gpt-4-turbo"); return response.trim(); } } ``` Wing 分別使用`preflight`和`inflight`概念來統一基礎設施定義和應用程式邏輯。 **預檢**程式碼(通常是基礎設施定義)在編譯時執行一次,而執行**中**程式碼將在執行時執行以實現應用程式的行為。 雲端儲存桶、佇列和 API 端點是預檢的一些範例。定義預檢時不需要新增預檢關鍵字,Wing 預設知道這一點。但對於飛行塊,您需要在其中加入“飛行”一詞。 > 上面的程式碼中有一個飛行中的區塊。 Inflight 區塊是您編寫非同步執行時間程式碼的地方,這些程式碼可以透過其 inflight API 直接與資源互動。 > 測試和儲存雲端秘密 --------- 讓我們來看看如何保護我們的 API 金鑰,因為我們肯定要[考慮安全性](https://techhq.com/2022/09/hardcoded-api-keys-jeopardize-data-in-the-cloud/)。 讓我們在後端的根目錄中建立一個`.env`檔案並傳入我們的 API 金鑰: ``` OAIAPIKey = Your_OpenAI_API_key ``` 我們可以在本地引用 .env 檔案來測試 OpenAI API 金鑰,然後由於我們計劃部署到 AWS,因此我們將逐步設定[AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 。 ![AWS 主控台](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2a1nbh0egmjkckxnaov.png) 首先,我們前往 AWS 並登入控制台。如果您沒有帳戶,可以免費建立一個。 ![AWS平台](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n937801fzs0lajf2knaq.png) 導覽至 Secrets Manager,讓我們儲存 API 金鑰值。 ![AWS 秘密管理器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scbb1snyzjdoip2nvdpl.png) ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lf79xzn6vfhqylao8iuo.png) 我們已將 API 金鑰儲存在名為`OAIAPIKey`的雲端機密中。複製您的金鑰,我們將跳到終端並連接到現在儲存在 AWS 平台中的金鑰。 ``` wing secrets ``` 現在將您的 API 金鑰貼上為終端中的值。您的密鑰現已正確存儲,我們可以開始與我們的應用程式互動。 --- 將人工智慧的回應儲存在雲端。 -------------- 將人工智慧的回應儲存在雲端可以讓您控制資料。它駐留在您自己的基礎設施上,與 ChatGPT 等專有平台不同,您的資料位於您無法控制的第三方伺服器上。您也可以在需要時檢索這些回應。 讓我們建立另一個類,使用 Assistant 類來傳遞 AI 的個性和提示。我們還將每個模型的回應作為`txt`檔案儲存在雲端儲存桶中。 ``` let counter = new cloud.Counter(); class RespondToQuestions { id: cloud.Counter; gpt: Assistant; store: cloud.Bucket; new(store: cloud.Bucket) { this.gpt = new Assistant("Respondent"); this.id = new cloud.Counter() as "NextID"; this.store = store; } pub inflight sendPrompt(question: str): str { let reply = this.gpt.ask("{question}"); let n = this.id.inc(); this.store.put("message-{n}.original.txt", reply); return reply; } } ``` --- 我們為我們的助理設定了「受訪者」的個性。我們希望它能夠回答問題。您也可以讓前端使用者在發送提示時指定此個性。 每次產生回應時,計數器都會遞增,並且計數器的值會傳遞到用於在雲端中儲存模型回應的`n`變數中。然而,我們真正想要的是建立一個資料庫來儲存來自前端的使用者提示和模型的回應。 讓我們定義我們的資料庫。 定義我們的資料庫 -------- Wing 內建了`ex.Table` - 一個用於儲存和查詢資料的 NoSQL 資料庫。 ``` let db = new ex.Table({ name: "assistant", primaryKey: "id", columns: { question: ex.ColumnType.STRING, answer: ex.ColumnType.STRING } }); ``` --- 我們在資料庫定義中新增了兩列 - 第一列用於儲存使用者提示,第二列用於儲存模型的回應。 建立 API 路由和邏輯 ------------ 我們希望能夠在後端發送和接收資料。讓我們建立 POST 和 GET 路由。 ``` let api = new cloud.Api({ cors: true }); api.post("/assistant", inflight((request) => { // POST request logic goes here })); api.get("/assistant", inflight(() => { // GET request logic goes here })); ``` --- ``` let myAssistant = new RespondToQuestions(store) as "Helpful Assistant"; api.post("/assistant", inflight((request) => { let prompt = request.body; let response = myAssistant.sendPrompt(JSON.stringify(prompt)); let id = counter.inc(); // Insert prompt and response in the database db.insert(id, { question: prompt, answer: response }); return cloud.ApiResponse({ status: 200 }); })); ``` 在 POST 路由中,我們希望將從前端收到的使用者提示傳遞到模型中並獲得回應。提示和回應都將儲存在資料庫中。 `cloud.ApiResponse`可讓您傳送對使用者要求的回應。 新增前端發出 GET 請求時檢索資料庫專案的邏輯。 --- 新增前端發出 GET 請求時檢索資料庫專案的邏輯。 ``` api.get("/assistant", inflight(() => { let questionsAndAnswers = db.list(); return cloud.ApiResponse({ body: JSON.stringify(questionsAndAnswers), status: 200 }); })); ``` 我們的後端已經準備好了。我們在本地雲端模擬器中測試一下。 跑`wing it` 。 讓我們轉到`localhost:3000`並向我們的助理詢問一個問題。 ![助理回應](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ox67623b9vye7o6quqe.png) 我們的問題和助理的回答都已儲存到資料庫中。看一看。 ![表資料](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ajd94ywkhjw04yb21e2.png) 向前端公開您的 API URL --------------- 我們需要將後端的 API URL 公開給 Next 前端。這就是之前安裝的 React 函式庫派上用場的地方。 ``` let website = new react.App({ projectPath: "../frontend", localPort: 4000 }); website.addEnvironment("API_URL", api.url); ``` 將以下內容加入 Next 應用程式的`layout.js`中。 ``` import { Inter } from "next/font/google"; import "./globals.css"; const inter = Inter({ subsets: ["latin"] }); export const metadata = { title: "Create Next App", description: "Generated by create next app", }; export default function RootLayout({ children }) { return ( <html lang="en"> <head> <script src="./wing.js" defer></script> </head> <body className={inter.className}>{children}</body> </html> ); } ``` 我們現在可以在 Next 應用程式中存取`API_URL` 。 實作前端邏輯 ------ 讓我們實作前端邏輯來呼叫後端。 ``` import { useEffect, useState, useCallback } from 'react'; import axios from 'axios'; function App() { const [isThinking, setIsThinking] = useState(false); const [input, setInput] = useState(""); const [allInteractions, setAllInteractions] = useState([]); const retrieveAllInteractions = useCallback(async (api_url) => { await axios ({ method: "GET", url: `${api_url}/assistant`, }).then(res => { setAllInteractions(res.data) }) }, []) const handleSubmit = useCallback(async (e)=> { e.preventDefault() setIsThinking(!isThinking) if(input.trim() === ""){ alert("Chat cannot be empty") setIsThinking(true) } await axios({ method: "POST", url: `${window.wingEnv.API_URL}/assistant`, headers: { "Content-Type": "application/json" }, data: input }) setInput(""); setIsThinking(false); await retrieveAllInteractions(window.wingEnv.API_URL); }) useEffect(() => { if (typeof window !== "undefined") { retrieveAllInteractions(window.wingEnv.API_URL); } }, []); // Here you would return your component's JSX return ( // JSX content goes here ); } export default App; ``` `retrieveAllInteractions`函數取得後端資料庫中的所有問題和答案。 `handSubmit`函數將使用者的提示傳送到後端。 讓我們加入 JSX 實作。 ``` import { useEffect, useState } from 'react'; import axios from 'axios'; import './App.css'; function App() { // ... return ( <div className="container"> <div className="header"> <h1>My Assistant</h1> <p>Ask anything...</p> </div> <div className="chat-area"> <div className="chat-area-content"> {allInteractions.map((chat) => ( <div key={chat.id} className="user-bot-chat"> <p className='user-question'>{chat.question}</p> <p className='response'>{chat.answer}</p> </div> ))} <p className={isThinking ? "thinking" : "notThinking"}>Generating response...</p> </div> <div className="type-area"> <input type="text" placeholder="Ask me any question" value={input} onChange={(e) => setInput(e.target.value)} /> <button onClick={handleSubmit}>Send</button> </div> </div> </div> ); } export default App; ``` 在本地執行您的專案 --------- 導航到您的後端目錄並使用以下命令在本地執行您的 Wing 應用程式 ``` cd ~assistant/backend wing it ``` 也執行您的 Next.js 前端: ``` cd ~assistant/frontend npm run dev ``` 讓我們看一下我們的應用程式。 ![聊天應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97g8kikxfwwb7ephfdni.png) 讓我們透過 Next 應用程式向 AI 助理詢問幾個開發人員問題。 ![聊天應用程式2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uoz1y9czt0nwwtsesrz.png) 將您的應用程式部署到 AWS -------------- 我們已經了解了我們的應用程式如何在本地執行。 Wing 也允許您部署到包括 AWS 在內的任何雲端提供者。要部署到 AWS,您需要使用您的憑證來設定[Terraform](https://terraform.io/downloads)和[AWS CLI](https://docs.aws.amazon.com/cli/) 。 - 使用`tf-aws`編譯到 Terraform/AWS 。此指令指示編譯器使用 Terraform 作為配置引擎,將所有資源綁定到預設的 AWS 資源集。 ``` cd ~/assistant/backend wing compile --platform tf-aws main.w ``` --- - 執行 Terraform 初始化並應用 ``` cd ./target/main.tfaws terraform init terraform apply ``` --- 注意: `terraform apply`需要一些時間才能完成。 您可以[在此處](https://github.com/NathanTarbert/chatgpt-client-wing-nextjs)找到本教程的完整程式碼。 總結一下 ---- 正如我之前提到的,我們都應該關心我們的應用程式的安全性,建立您自己的 ChatGPT 用戶端並將其部署到您的雲端基礎設施可以為您的應用程式提供一些非常好的[保障](https://docs.aws.amazon.com/whitepapers/latest/aws-overview/security-and-compliance.html#:~:text=Keep%20Your%20data%20safe%20%E2%80%94%20The,compliance%20programs%20in%20its%20infrastructure.)。 我們在本教程中演示了[Wing](https://git.new/wing-repo)如何提供一種簡單的方法來建置可擴展的雲端應用程式,而無需擔心底層基礎設施。 如果您有興趣建立更酷的東西,Wing 擁有一個活躍的開發人員社區,他們可以合作建立雲端願景。我們很高興在那裡見到你。 只需前往我們的[Discord](https://t.winglang.io/discord)打個招呼即可! --- 原文出處:https://dev.to/winglang/building-your-own-chatgpt-graphical-client-with-nextjs-and-wing-29jj