🔍 搜尋結果:後端

🔍 搜尋結果:後端

給中級開發人員的建議

序幕 == 我五年前寫了[這個博客](https://dev.to/rampa2510/3-tips-for-new-developers-49hj),當時我還是一名初級開發人員。我當時分享的技巧至今仍然是我遵循的規則,並且已經成為我不可或缺的一部分。作為一名開發人員,我已經成長了很多,所以現在我想作為中級開發人員回饋社區。 這裡提到的建議是針對那些熱愛自己的手藝並希望做得更好的人,不是為了更好的報酬,而是為了享受程式設計的樂趣。 1)熱愛你的工作 -------- 我看過人們把程式設計當作只是一份工作,只是為了錢。他們透過程式設計謀生並過上日常生活。這種生活方式很好,這是你的選擇。但如果你的技能沒有提高並且你變得停滯不前,請不要感到驚訝。要擅長編程,你必須熱愛你的工作。你一天的大部分時間都花在日常工作上編程,如果你不喜歡它,你就不會在工作的同時主動提高你的技能。 我有一個個人故事可以分享。我曾經在一家我討厭的公司工作過。我沒有主動改進程式碼庫或學習新東西來增強應用程式架構。現在,我從事著自己熱愛的工作,並將其視為自己的產品。這通常會引導我學習新事物並以結構良好的方式開發程式碼庫,因為我不想破壞它。如果你做你不喜歡的事,弊大於利。你可以在下班後學習,但你一天會浪費大約六個小時,但收效甚微。 2)成為多面手 ------- 永遠不要把自己放在一個盒子裡。不要認為自己只是前端開發人員或後端開發人員。將自己視為軟體開發人員。優秀的開發人員不會將自己局限於特定的技術,他們專注於解決問題,而不僅僅是問題的一部分。如果你將自己限制在某個堆疊上,你就不會成為一個偉大的問題解決者。軟體開發就是解決問題,如果你不了解如何建立端到端產品,你就不會成為一個好的問題解決者。 在職業生涯開始時,您可能必須選擇特定的堆疊來證明自己是一名出色的軟體開發人員。但不要讓它限制你。如果您在一家優秀的公司工作,請與資深或其他開發人員交談,以深入了解不同的團隊並學習新事物。開始負責公司程式碼庫的其他部分,以轉變為更全端的開發人員角色。這樣,您將開始更多地考慮解決整個問題,而不僅僅是解決部分問題。如果不歡迎您與其他堆疊一起工作,我建議您從事另一份工作。公司永遠不應該限制工程師的學習。 所以,做個多面手。不要將自己限制在堆疊的某一部分。學習作為軟體開發人員解決問題。通才發現更容易擅長解決特定問題,因為他們已經有了廣泛的理解,因此可以更快地掌握新技術。 3)永遠不要停止學習新技術(當修補匠) ------------------- 這是許多開發人員忽略的關鍵點。要成為優秀的問題解決者,您必須隨時了解科技的最新進展。我在嗜好專案中找到了很多樂趣,這幫助我發展了許多技能。當你修補新東西時,你會學到很多東西,而且你永遠不知道它什麼時候會變得有用。 例如,假設您的任務是為您的公司建立一個部落格應用程式。他們想要一個客製化的解決方案,而不是使用 Webflow 和其他類似服務的解決方案。如果您跟上了最新的進步,您可以使用 Supabase 或 Pocketbase 等現代 CMS 工具來快速開發後端。為您的部落格網站設定 CMS 可能只需要 30 分鐘,使您無需建立和管理資料庫和後端程式碼。然後你就可以根據你公司的需求專注於前端。 這是一個個人例子:我已經業餘學習了一個月的 Go。最近,我必須寫一個 cron 作業來每 30 分鐘更新一次使用者指標。我知道 Go 對於此類任務來說非常出色且速度非常快,因此我在 Go 中建立了 cron 作業,建置了二進位文件,並每 30 分鐘安排一個帶有計時器的系統守護程序任務。它工作效率高,消耗的資源更少。如果我沒有在業餘時間修修補補,只在日常工作中編寫程式碼,我就不會在合理的時間內想出最好的解決方案。 cron 作業將以 Node 編寫,隨著使用者群的成長,這將需要更多時間。 因此,永遠不要停止學習和創造。最好的學習方法是創造和修補。我一直在業餘學習 Ruby on Rails 和 Go,並且開始欣賞各種生態系統提供的不同功能。這幫助我將新想法融入我的工作流程中。 4)取得所有權 ------- 我最近觀看了 ThePrimagen 的一段[影片](https://www.youtube.com/watch?v=5i_O6NLXYsM&t=1586s),這激發了我寫這個博客的靈感。他提到解決問題或成為優秀軟體開發人員的最佳方法是擁有產品。他談到《毀滅戰士》是如何由四個人創造出來的,他們因為擁有所有權而交付瞭如此好的產品。他們知道自己沒有其他人可以依賴,因此他們將開發最好的軟體作為自己的責任。沒有備用計劃。 他們從未感到倦怠或放棄,因為他們擁有產品,而不僅僅是任務。 為了提高軟體開發人員的技能,您需要開始掌控您正在建立的產品,而不僅僅是功能或任務。當您將任何功能或錯誤視為您要解決的問題,而不僅僅是其他人的另一項任務時,您會發現開發產品會更加有趣。這是戰勝倦怠的最好方法。當您擁有所有權時,您會發現改進產品並使產品更有效率的樂趣。 如果你正在開發一個產品,當使用者發現它們時,你不能將出現的任何錯誤歸咎於其他人。如果出現問題,你就是問題的一部分,所以你必須承擔起解決問題的責任並創造出出色的產品。好的、可擴展的產品是由團隊建立的,如果你不承擔責任,你就不是一個好的團隊成員。當您擁有所有權時,您可以編寫最好的程式碼來建立最好的軟體,而不僅僅是另一個軟體產品。 就像製作《毀滅戰士》的四個人一樣,他們投入了大量的時間來創造屬於他們的東西,他們從不滿足於只是另一款遊戲,他們創造了一款定義時代的遊戲。其餘的,正如他們所說,是歷史。這同樣適用於你,如果你想製作最好的軟體,你必須開始擁有所有權並將該產品視為你自己的產品。 結語 == 寫完這個部落格並與社區分享我的想法後,我感覺很好。我們可能會爭論框架、語言和工具,但這些爭論有助於我們改進。他們推動技術進步,使我們的社區極具競爭力。讓我們保持激情! --- 原文出處:https://dev.to/rampa2510/advice-for-intermediate-developers-4777

使用 NextJS 建立電子商務商店

在本教程中,您將學習如何建立電子商務商店,客戶可以在其中透過 Stripe 購買產品並付款。成功付款後,將向客戶發送電子郵件通知,並向管理員用戶發送應用程式內通知。管理員用戶也可以在應用程式中建立和刪除產品。 為了建立這個應用程式,我們將使用以下工具: - [Appwrite](https://appwrite.io/) - 用於驗證使用者身份,以及保存和檢索產品詳細資訊。 - [Next.js](https://nextjs.org/) - 用於建立應用程式的使用者介面和後端。 - [Novu](https://docs.novu.co/getting-started/introduction) - 用於發送電子郵件和應用程式內通知。 - [React Email](https://react.email/docs/introduction) - 用於建立電子郵件範本。 - [Stripe](https://docs.stripe.com/) - 用於將付款結帳整合到應用程式中。 ![應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t02iyysrqjfqw8imuqxn.png) --- 使用 Next.js 建立應用程式介面 ------------------- 應用程式頁面根據指派給使用者的角色分為兩部分。客戶可以在付款前存取主頁並登入應用程式。管理員使用者可以存取所有頁面,包括登入頁面和儀表板頁面,他們可以在其中新增和刪除產品。 現在,讓我們建立應用程式。 ![https://media1.giphy.com/media/iopxsZtW2QVRs4poEC/giphy.gif?cid=7941fdc6aot3qt7vvq4voh5c1iagyusdpuga713m8ljqcqmd&ep=v1_gifs_searchiagyusdpuga713m8ljqcqmd&ep=v1_gifs_searchiagyusdpugagif&ct](https://media1.giphy.com/media/iopxsZtW2QVRs4poEC/giphy.gif?cid=7941fdc6aot3qt7vvq4voh5c1iagyusdpuga713m8ljqcqmd&ep=v1_gifs_search&rid=giphy.gif&ct=g) 透過執行以下程式碼片段來建立一個新的 Next.js Typescript 專案: ``` npx create-next-app novu-store ``` 接下來,安裝[React Icons](https://react-icons.github.io/react-icons)和[Headless UI](https://headlessui.com/)包。 React Icons 允許我們在應用程式中使用各種圖標,而 Headless UI 則提供易於使用的現代 UI 元件。 ``` npm install react-icons @headlessui/react ``` 將此程式碼片段從[GitHub 儲存庫](https://github.com/dha-stix/ecom-store-with-nextjs-appwrite-novu-and-stripe/blob/main/src/app/page.tsx)複製到`app/page.tsx`檔案中。它在螢幕上呈現產品列表,並允許用戶選擇購物車中的商品,類似於下圖。 ![1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dj69givzhqfapgsg12rk.gif) 建立登入路由,使用戶能夠使用其 GitHub 帳戶進行簽署。將下面的程式碼片段複製到`app/login/page.tsx`檔案中。 ``` //👉🏻 create a login folder containing a page.tsx file export default function Home() { const handleGoogleSignIn = async () => {}; return ( <main className='w-full min-h-screen flex flex-col items-center justify-center'> <h2 className='font-semibold text-3xl mb-2'>Customer Sign in</h2> <p className='mb-4 text-sm text-red-500'> You need to sign in before you can make a purchase </p> <button className='p-4 border-[2px] border-gray-500 rounded-md hover:bg-black hover:text-white w-2/3' onClick={() => handleGoogleSignIn()} > Sign in with GitHub </button> </main> ); } ``` ![客戶登入](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nh2rowpfg4hgksj5diy.png) 當使用者點擊「登入」按鈕時,會將他們重新導向到 GitHub 驗證頁面並提示他們登入應用程式。您很快就會了解如何使用[Appwrite](https://appwrite.io/)執行此操作。 接下來,讓我們建立管理頁面。在`app`資料夾中新增包含`login`和`dashboard`路由的`admin`資料夾。 ``` cd app mkdir admin && cd admin mkdir dashboard login ``` 在`dashboard`和`login`資料夾中新增`page.tsx`文件,並將下面的程式碼片段複製到`login/page.tsx`檔案中。 ``` "use client"; import Link from "next/link"; import { useState } from "react"; export default function Login() { const [email, setEmail] = useState<string>(""); const [password, setPassword] = useState<string>(""); const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); console.log({ email, password }); }; return ( <main className='w-full min-h-screen flex flex-col items-center justify-center'> <h2 className='font-semibold text-3xl mb-4'> Admin Sign in</h2> <form className='w-2/3' onSubmit={handleLogin}> <label htmlFor='email' className='block'> Email </label> <input type='email' id='email' className='w-full px-4 py-3 border border-gray-400 rounded-sm mb-4' required value={email} placeholder='[email protected]' onChange={(e) => setEmail(e.target.value)} /> <label htmlFor='password' className='block'> Password </label> <input type='password' id='password' className='w-full px-4 py-3 border border-gray-400 rounded-sm mb-4' required value={password} placeholder='admin123' onChange={(e) => setPassword(e.target.value)} /> <button className='p-4 text-lg mb-3 bg-blue-600 text-white w-full rounded-md'> Sign in </button> <p className='text-sm text-center'> Not an Admin?{" "} <Link href='/login' className='text-blue-500'> Sign in as a Customer </Link> </p> </form> </main> ); } ``` 上面的程式碼片段呈現一個表單,該表單接受管理員的電子郵件和密碼,驗證憑證,然後將使用者登入應用程式中。 ![管理員登入](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gjd9wsi63t96d5cls9om.png) 管理儀表板頁面呈現可用的產品,並允許管理員使用者在應用程式中新增和刪除產品。將此[程式碼片段複製](https://github.com/dha-stix/ecom-store-with-nextjs-appwrite-novu-and-stripe/blob/main/src/app/admin/dashboard/page.tsx)到`dashboard/page.tsx`檔案中以建立使用者介面。 ![2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1gd1uq1eq6n76fesjxu.gif) 恭喜!您已經建立了應用程式介面。在接下來的部分中,您將了解如何將應用程式連接到 Appwrite 後端並在客戶端和伺服器之間發送資料。 --- 如何將 Appwrite 新增到 Next.js 應用程式 ----------------------------- Appwrite 是一項開源後端服務,可讓您建立安全且可擴展的軟體應用程式。它提供多種身份驗證方法、安全性資料庫、文件儲存、雲端訊息傳遞等功能,這些對於建立全端應用程式至關重要。 在本部分中,您將了解如何設定 Appwrite 專案,包括身份驗證、資料庫和檔案儲存等功能。 首先,請造訪[Appwrite Cloud](https://cloud.appwrite.io/register) ,並為您的專案建立一個帳戶和組織。 接下來,建立一個新專案並選擇您的首選區域來託管該專案。 ![應用程式寫入1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/as6302olk60oklfo70x5.png) 選擇`Web`作為應用程式的平台 SDK。 ![應用程式編寫2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bb5ae82i9fyoyrowsy96.png) 請依照螢幕上顯示的步驟進行操作。由於您目前正在開發模式下建置,因此您可以使用通配符 ( `*` ) 作為主機名,並在部署應用程式後將其變更為您的網域名稱。 ![應用程式寫入3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y5ccs0hzgs9ujf5lzh83.png) 在 Next.js 專案中安裝 Appwrite 用戶端 SDK。 ``` npm install appwrite ``` 最後,在 Next.js 應用程式資料夾中建立一個`appwrite.ts`文件,並將下面的程式碼片段複製到該文件中以初始化 Appwrite。 ``` import { Client, Account, Databases, Storage } from "appwrite"; const client = new Client(); client .setEndpoint("https://cloud.appwrite.io/v1") .setProject(<YOUR_PROJECT_ID>); export const account = new Account(client); export const db = new Databases(client); export const storage = new Storage(client); ``` ### 使用 Appwrite 設定 GitHub 身份驗證 在這裡,您將了解如何使用 Appwrite 設定 GitHub 和電子郵件/密碼驗證。預設已配置電子郵件/密碼身份驗證,因此我們專注於設定 GitHub 身份驗證。 在繼續之前,您需要使用您的 GitHub 帳戶建立[GitHub OAuth 應用程式](https://github.com/settings/developers)。 Appwrite 將需要客戶端 ID 和金鑰來設定 GitHub 身份驗證。 ![GitHub 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9znk1yr7tffus7soitq2.png) 透過從側邊欄選單中選擇`Auth`並導覽至`Settings`選項卡,啟用 Appwrite 的 GitHub 驗證方法。 ![應用程式編寫4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43uo6nho1bz9su14zsno.png) 將您的 GitHub 用戶端 ID 和金鑰複製到 Appwrite 的 GitHub OAuth 設定中。 最後,確保將 Appwrite 產生的 URI 複製到 GitHub 應用程式設定中。 ![GitHub 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g75q5r5hc6l5pi09k88m.png) ### 設定 Appwrite 資料庫 從側邊欄選單中選擇資料庫並建立新資料庫。您可以將其命名為`novu store` 。 ![應用程式寫入5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y7kn1llmu7olqirfcrpa.png) 接下來,建立`products`集合。它將包含應用程式中的產品清單。 ![應用程式寫入 6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7p8laty6z37x0q1g6az4.png) 將名稱、價格和圖像屬性新增至集合。 ![應用程式寫入 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzom3ptlz8t1rh9dtt1k.png) 在「設定」標籤下,更新權限以允許每個使用者執行 CRUD 操作。但是,您可以在部署應用程式後變更此設置,以確保只有經過身份驗證的使用者才能執行各種操作。 ![應用程式寫入 8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/37cqr8s0crtcttocjagk.png) 最後,將專案、資料庫和集合 ID 複製到**`.env.local`**檔案中。這可以確保您的憑證安全,並允許您引用其環境變數中的每個值。 ``` NEXT_PUBLIC_PROJECT_ID=<YOUR_PROJECT_ID> NEXT_PUBLIC_DB_ID=<YOUR_DATABASE_ID> NEXT_PUBLIC_PRODUCTS_COLLECTION_ID=<YOUR_DB_COLLECTION_ID> ``` ### 設定應用程式寫入存儲 從側邊欄選單中選擇`Storage` ,然後建立新儲存桶來儲存所有產品影像。 ![應用程式編寫 9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b84t9mk3k0wrkgiy4uca.png) 在`Settings`標籤下,更新「權限」以暫時允許任何使用者。 ![應用程式寫入 10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zi3iozkaera7fohkwanm.png) 設定可接受的文件格式。由於我們上傳的是圖像,因此您可以選擇**`.jpg`**和**`.png`**檔案格式。 ![應用寫入 11](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzxqpoq5dcpokkvdcsce.png) 最後,將您的儲存桶 ID 複製到`.env.local`檔案中。 ``` NEXT_PUBLIC_BUCKET_ID=<YOUR_BUCKET_ID> ``` 恭喜!您已成功配置 Appwrite。我們現在可以開始與其各種功能進行互動。 --- 如何使用Appwrite執行CRUD操作 -------------------- 在本部分中,您將了解如何從 Appwrite 建立、檢索和刪除產品。用戶需要能夠在購買前查看現有產品,而管理員用戶應有權在應用程式中新增和刪除產品。 首先,在 Next.js **`app`**資料夾中建立一個**`utils.ts`**檔案。該文件將包含所有 Appwrite 資料庫交互,然後您可以將其導入到必要的頁面中。 ``` cd app touch utils.ts ``` ### 將產品儲存到 Appwrite 回想一下, `products`集合有三個屬性:名稱、圖像和價格。因此,在將產品新增至資料庫時,您需要先上傳產品的圖像,從回應中檢索其 URL 和 ID,然後將 URL 作為產品的圖像屬性上傳,使用圖像的儲存 ID 作為產品資料。 這是解釋這一點的程式碼片段: ``` import { db, storage } from "@/app/appwrite"; import { ID } from "appwrite"; export const createProduct = async ( productTitle: string, productPrice: number, productImage: any ) => { try { //👇🏻 upload the image const response = await storage.createFile( process.env.NEXT_PUBLIC_BUCKET_ID!, ID.unique(), productImage ); //👇🏻 get the image's URL const file_url = `https://cloud.appwrite.io/v1/storage/buckets/${process.env.NEXT_PUBLIC_BUCKET_ID}/files/${response.$id}/view?project=${process.env.NEXT_PUBLIC_PROJECT_ID}&mode=admin`; //👇🏻 add the product to the database await db.createDocument( process.env.NEXT_PUBLIC_DB_ID!, process.env.NEXT_PUBLIC_PRODUCTS_COLLECTION_ID!, response.$id, //👉🏻 use the image's ID { name: productTitle, price: productPrice, image: file_url, } ); alert("Product created successfully"); } catch (err) { console.error(err); } }; ``` 上面的程式碼片段將圖像上傳到 Appwrite 的雲端存儲,並使用儲存桶 ID、圖像 ID 和專案 ID 檢索準確的圖像 URL。圖片成功上傳後,其 ID 將用於產品資料中,以便輕鬆檢索和參考。 ### 從 Appwrite 檢索產品 若要從 Appwrite 取得產品,您可以在頁面載入時在 React **`useEffect`**掛鉤中執行下列函數。 ``` export const fetchProducts = async () => { try { const products = await db.listDocuments( process.env.NEXT_PUBLIC_DB_ID!, process.env.NEXT_PUBLIC_PRODUCTS_COLLECTION_ID! ); if (products.documents) { return products.documents; } } catch (err) { console.error(err); } }; ``` `fetchProducts`函數傳回`products`集合中的所有資料。 ### 從 Appwrite 中刪除產品 管理員使用者也可以透過產品 ID 刪除產品。 **`deleteProduct`**函數接受產品的 ID 作為參數,並從資料庫中刪除所選產品(包括其圖像),因為它們使用相同的 ID 屬性。 ``` export const deleteProduct = async (id: string) => { try { await db.deleteDocument( process.env.NEXT_PUBLIC_DB_ID!, process.env.NEXT_PUBLIC_PRODUCTS_COLLECTION_ID!, id ); await storage.deleteFile(process.env.NEXT_PUBLIC_BUCKET_ID!, id); alert("Product deleted successfully"); } catch (err) { console.error(err); } }; ``` --- 如何使用 Appwrite 驗證使用者身份 --------------------- 在前面的部分中,我們已經設定了 GitHub 身份驗證方法。在這裡,您將了解如何處理使用者登入應用程式。 若要使客戶能夠使用其 GitHub 帳戶登入應用程式,請在按一下`Sign in`按鈕時執行以下功能。該函數將使用者重定向到 GitHub,在那裡他們可以向應用程式授權或授予權限,然後登入應用程式: ``` import { account } from "../appwrite"; import { OAuthProvider } from "appwrite"; const handleGoogleSignIn = async () => { try { account.createOAuth2Session( OAuthProvider.Github, "http://localhost:3000", "http://localhost:3000/login" ); } catch (err) { console.error(err); } }; ``` 管理員使用者可以使用電子郵件和密碼登入應用程式。 Appwrite 在授予對應用程式儀表板的存取權之前會驗證憑證。 ``` import { account } from "@/app/appwrite"; const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); try { await account.createEmailPasswordSession(email, password); alert(`Welcome back 🎉`); router.push("/admin/dashboard"); } catch (err) { console.error(err); alert("Invalid credentials ❌"); } }; ``` Appwrite 還允許您取得目前使用者的資料。例如,如果只有經過身份驗證的使用者才能付款,您可以透過執行下面的程式碼片段來完成此操作。它會檢索目前使用者的資料,如果使用者未登錄,則傳回 null。 ``` import { account } from "@/app/appwrite"; useEffect(() => { const checkAuthStatus = async () => { try { const request = await account.get(); setUser(request); } catch (err) { console.log(err); } }; checkAuthStatus(); }, []); ``` --- 如何將 Stripe 付款結帳新增至 Next.js -------------------------- 在本節中,您將了解如何在應用程式中實現 Stripe 付款結帳。 Stripe 是一種流行的線上支付處理平台,可讓您建立產品並將一次性和定期支付方式整合到您的應用程式中。 首先,您需要[建立一個 Stripe 帳戶](https://dashboard.stripe.com/login)。您可以在本教學中使用測試模式帳戶。 ![條紋1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nibs7bxb09i167mxm918.png) 點擊頂部選單中的`Developers` ,然後從 API 金鑰選單中複製您的金鑰。 ![條紋2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/up8757knbquc3k0577ps.png) 將您的 Stripe 金鑰貼到`.env.local`檔案中。 ``` STRIPE_SECRET_KEY=<your_secret_key> ``` 安裝[Stripe Node.js SDK](https://docs.stripe.com/libraries) 。 ``` npm install stripe ``` 接下來,在 Next.js `app`資料夾中建立一個`api`資料夾。 `api`資料夾將包含應用程式的所有 API 路由和端點。 ``` cd app mkdir api ``` 透過在`api`資料夾中新增`checkout`資料夾來建立`checkout`端點。 ``` cd api mkdir checkout && cd checkout touch route.ts ``` 將下面的程式碼片段複製到`route.ts`檔中。 ``` import { NextRequest, NextResponse } from "next/server"; import Stripe from "stripe"; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!); export async function POST(req: NextRequest) { //👇🏻 accepts the customer's cart const cart = await req.json(); try { //👇🏻 creates a checkout session const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: cart.map((product: Product) => ({ price_data: { currency: "usd", product_data: { name: product.name, }, unit_amount: product.price * 100, }, quantity: 1, })), mode: "payment", cancel_url: `http://localhost:3000/?canceled=true`, success_url: `http://localhost:3000?success=true&session_id={CHECKOUT_SESSION_ID}`, }); //👇🏻 return the session URL return NextResponse.json({ session: session.url }, { status: 200 }); } catch (err) { return NextResponse.json({ err }, { status: 500 }); } } ``` 上面的程式碼片段建立了一個接受 POST 請求的結帳端點。它為客戶建立結帳會話並傳回會話 URL。 **`cancel_url`**和**`success_url`**確定完成或取消付款後將用戶重新導向到何處。 最後,當用戶決定為產品付款時,您可以透過執行以下程式碼片段將客戶的購物車發送到`/checkout`端點: ``` const processPayment = async (cart: Product[]) => { try { if (user !== null) { //👇🏻 saves cart to local storage localStorage.setItem("cart", JSON.stringify(cart)); //👇🏻 sends cart to /checkout route const request = await fetch("/api/checkout", { method: "POST", body: JSON.stringify(cart), headers: { "Content-Type": "application/json" }, }); //👇🏻 retrieves the session URL const { session } = await request.json(); //👇🏻 redirects the user to the checkout page window.location.assign(session); } else { //👇🏻 redirects unauthenticated users router.push("/login"); } } catch (err) { console.error(err); } }; ``` 上面的程式碼片段將購物車儲存到瀏覽器的本機儲存體並將其傳送到 API 端點,然後從後端伺服器檢索回應(會話 URL)並將使用者重新導向至 Stripe 結帳頁面。 ![條紋3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i5hokf2qyqyey3kwsg9x.gif) --- 使用 Novu 發送應用程式內通知和電子郵件通知 ------------------------ [Novu](https://github.com/novuhq/novu)是第一個提供統一 API 的通知基礎架構,用於透過多種管道(包括應用程式內、推播、電子郵件、簡訊和聊天)發送通知。 在本部分中,您將了解如何將 Novu 加入到您的應用程式,以便您能夠發送電子郵件和應用程式內訊息。 首先,安裝所需的 Novu 軟體包: ``` npm install @novu/node @novu/echo @novu/notification-center ``` 當用戶進行購買時,他們將收到一封付款確認電子郵件,管理員用戶也會收到一條應用程式內通知。 為此,您需要[在 Novu 上建立帳戶](https://web.novu.co/auth/login)並設定主要電子郵件提供者。在本教程中,我們將使用[“重新發送”](https://resend.com/docs/introduction) 。 在 Novu 上建立帳戶後,建立一個[重新傳送帳戶](https://resend.com/docs/introduction),然後從儀表板上的側邊欄選單中選擇`API Keys`來建立帳戶。 ![重新發送 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhehx7s45x180zpir1ti.png) 接下來,回到 Novu 儀表板,從側邊欄選單中選擇`Integrations Store` ,然後新增 Resend 作為電子郵件提供者。您需要將重新傳送 API 金鑰和電子郵件地址貼到必填欄位中。 ![新 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f03vb6nftyi8g790vg7m.png) 從側邊欄選單中選擇**「設定」** ,然後將您的`Novu API`金鑰和`App ID`複製到**`.env.local`**檔案中,如下所示。另外,將您的`subscriber ID`複製到其欄位中 - 您可以從`Subscribers`部分獲取此資訊。 ``` NOVU_API_KEY=<YOUR_API_FOR_NEXT_SERVER> NEXT_PUBLIC_NOVU_API_KEY=<YOUR_API_FOR_NEXT_CLIENT> NEXT_PUBLIC_NOVU_APP_ID=<YOUR_API_ID> NOVU_SUBSCRIBER_ID=<YOUR_API_FOR_NEXT_SERVER> NEXT_PUBLIC_NOVU_SUBSCRIBER_ID=<YOUR_API_FOR_CLIENT> ``` ![新2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/voeofvvtv88pex9rpr1s.png) 最後,將 Novu 通知鈴新增至管理儀表板,以使管理員使用者能夠在應用程式內接收通知。 ``` import { NovuProvider, PopoverNotificationCenter, NotificationBell, } from "@novu/notification-center"; export default function AdminNav() { return ( <NovuProvider subscriberId={process.env.NEXT_PUBLIC_NOVU_SUBSCRIBER_ID!} applicationIdentifier={process.env.NEXT_PUBLIC_NOVU_APP_ID!} > <PopoverNotificationCenter colorScheme='light'> {({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />} </PopoverNotificationCenter> </NovuProvider> ); } ``` ![儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m62ft87ue9orse2yww9z.png) --- 如何使用 Novu Echo 建立通知工作流程 ----------------------- [Novu](https://docs.novu.co/echo/quickstart)提供程式碼優先的工作流程引擎,讓您能夠在程式碼庫中建立通知工作流程。它允許您將電子郵件、簡訊、聊天範本和內容產生器(例如[React Email](https://react.email/docs/introduction)和[MJML](https://mjml.io/) )整合到 Novu 中,以建立高級且強大的通知。 在本部分中,您將了解如何在應用程式中建立通知工作流程、如何使用 Novu 的電子郵件通知範本以及如何使用 Novu 發送應用程式內通知和電子郵件通知。 透過執行以下命令安裝[React Email](https://react.email/docs/introduction) : ``` npm install react-email @react-email/components -E ``` 將以下腳本包含在您的 package.json 檔案中。 `--dir`標誌使 React Email 能夠存取位於專案內的電子郵件範本。在本例中,電子郵件範本位於`src/emails`資料夾中。 ``` { "scripts": { "email": "email dev --dir src/emails" } } ``` 接下來,在 Next.js `app`資料夾中建立一個包含`email.tsx`的`emails`資料夾,並將以下程式碼片段複製到該檔案中: ``` import { Body, Column, Container, Head, Heading, Hr, Html, Link, Preview, Section, Text, Row, render, } from "@react-email/components"; import * as React from "react"; const EmailTemplate = ({ message, subject, name, }: { message: string; subject: string; name: string; }) => ( <Html> <Head /> <Preview>{subject}</Preview> <Body style={main}> <Container style={container}> <Section style={header}> <Row> <Column style={headerContent}> <Heading style={headerContentTitle}>{subject}</Heading> </Column> </Row> </Section> <Section style={content}> <Text style={paragraph}>Hey {name},</Text> <Text style={paragraph}>{message}</Text> </Section> </Container> <Section style={footer}> <Text style={footerText}> You&apos;re receiving this email because your subscribed to Newsletter App </Text> <Hr style={footerDivider} /> <Text style={footerAddress}> <strong>Novu Store</strong>, &copy;{" "} <Link href='https://novu.co'>Novu</Link> </Text> </Section> </Body> </Html> ); export function renderEmail(inputs: { message: string; subject: string; name: string; }) { return render(<EmailTemplate {...inputs} />); } const main = { backgroundColor: "#f3f3f5", fontFamily: "HelveticaNeue,Helvetica,Arial,sans-serif", }; const headerContent = { padding: "20px 30px 15px" }; const headerContentTitle = { color: "#fff", fontSize: "27px", fontWeight: "bold", lineHeight: "27px", }; const paragraph = { fontSize: "15px", lineHeight: "21px", color: "#3c3f44", }; const divider = { margin: "30px 0", }; const container = { width: "680px", maxWidth: "100%", margin: "0 auto", backgroundColor: "#ffffff", }; const footer = { width: "680px", maxWidth: "100%", margin: "32px auto 0 auto", padding: "0 30px", }; const content = { padding: "30px 30px 40px 30px", }; const header = { borderRadius: "5px 5px 0 0", display: "flex", flexDireciont: "column", backgroundColor: "#2b2d6e", }; const footerDivider = { ...divider, borderColor: "#d6d8db", }; const footerText = { fontSize: "12px", lineHeight: "15px", color: "#9199a1", margin: "0", }; const footerLink = { display: "inline-block", color: "#9199a1", textDecoration: "underline", fontSize: "12px", marginRight: "10px", marginBottom: "0", marginTop: "8px", }; const footerAddress = { margin: "4px 0", fontSize: "12px", lineHeight: "15px", color: "#9199a1", }; ``` 上面的程式碼片段使用 React Email 建立了一個可自訂的電子郵件範本。您可以找到更多[易於編輯的靈感或模板](https://demo.react.email/preview/notifications/vercel-invite-user)。該元件還接受訊息、主題和名稱作為屬性,並將它們填入元素中。 最後,您可以在終端機中執行`npm run email`來預覽範本。 接下來,讓我們將電子郵件範本整合到 Novu Echo 中。首先,關閉 React Email 伺服器,然後執行下面的程式碼片段。它會在瀏覽器中開啟[Novu Dev Studio](https://docs.novu.co/echo/concepts/studio) 。 ``` npx novu-labs@latest echo ``` 在 Next.js 應用程式資料夾中建立一個包含`client.ts`檔案的`echo`資料夾,並將此程式碼片段複製到該檔案中。 ``` import { Echo } from "@novu/echo"; import { renderEmail } from "@/app/emails/email"; interface EchoProps { step: any; payload: { subject: string; message: string; name: string; totalAmount: string; }; } export const echo = new Echo({ apiKey: process.env.NEXT_PUBLIC_NOVU_API_KEY!, devModeBypassAuthentication: process.env.NODE_ENV === "development", }); echo.workflow( "novu-store", async ({ step, payload }: EchoProps) => { //👇🏻 in-app notification step await step.inApp("notify-admin", async () => { return { body: `${payload.name} just made a new purchase of ${payload.totalAmount} 🎉`, }; }); //👇🏻 email notification step await step.email( "email-customer", async () => { return { subject: `${payload ? payload?.subject : "No Subject"}`, body: renderEmail(payload), }; }, { inputSchema: { type: "object", properties: {}, }, } ); }, { payloadSchema: { type: "object", properties: { message: { type: "string", default: "Congratulations! Your purchase was successful! 🎉", }, subject: { type: "string", default: "Message from Novu Store" }, name: { type: "string", default: "User" }, totalAmount: { type: "string", default: "0" }, }, required: ["message", "subject", "name", "totalAmount"], additionalProperties: false, }, } ); ``` 此程式碼片段定義了一個名為`novu-store` Novu 通知工作流程,該工作流程接受包含電子郵件主題、訊息、客戶姓名和總金額的有效負載。 此工作流程有兩個步驟:應用程式內通知和電子郵件通知。應用程式內通知使用通知鈴聲向管理員發送訊息,而電子郵件則向客戶的電子郵件發送訊息。 接下來,您需要為 Novu Echo 建立 API 路由。在`api`資料夾中,建立一個包含`route.ts`檔案的`email`資料夾,並將下面提供的程式碼片段複製到該檔案中。 ``` import { serve } from "@novu/echo/next"; import { echo } from "@/app/echo/client"; export const { GET, POST, PUT } = serve({ client: echo }); ``` 在終端機中執行`npx novu-labs@latest echo` 。它將自動開啟 Novu Dev Studio,您可以在其中預覽工作流程並將其與雲端同步。 ![新3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ed2sl38m7zrlgjoj4a6y.gif) `Sync to Cloud`按鈕會觸發一個彈出窗口,其中提供有關如何將工作流程推送到 Novu 雲端的說明。 ![新4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ch8ba7y9klyudmmv9jz.png) 若要繼續,請在終端機中執行以下程式碼片段。這將產生一個唯一的 URL,表示您的開發環境和雲端環境之間的本機隧道。 ``` npx localtunnel --port 3000 ``` 將產生的連結與 Echo API 端點一起複製到 Echo Endpoint 欄位中,按一下`Create Diff`按鈕,然後部署變更。 ``` https://<LOCAL_TUNNEL_URL>/<ECHO_API_ENDPOINT (/api/email)> ``` 恭喜!您剛剛從程式碼庫建立了 Novu 工作流程。 ![新5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6bdugs6g15y1e7xeixux.png) 最後,讓我們建立在用戶付款時發送電子郵件和應用程式內通知的端點。建立一個`api/send`路由並將下面的程式碼片段複製到檔案中: ``` import { NextRequest, NextResponse } from "next/server"; import { Novu } from "@novu/node"; const novu = new Novu(process.env.NOVU_API_KEY!); export async function POST(req: NextRequest) { const { email, name, totalAmount } = await req.json(); const { data } = await novu.trigger("novu-store", { to: { subscriberId: process.env.NOVU_SUBSCRIBER_ID!, email, firstName: name, }, payload: { name, totalAmount, subject: `Purchase Notification from Novu Store`, message: `Your purchase of ${totalAmount} was successful! 🎉`, }, }); console.log(data.data); return NextResponse.json( { message: "Purchase Completed!", data: { novu: data.data }, success: true, }, { status: 200 } ); } ``` 端點接受客戶的電子郵件、姓名和支付總額,並在付款成功後觸發 Novu 通知工作流程發送所需的通知。 --- 結論 -- 到目前為止,您已經學會如何執行以下操作: - 實施多種身份驗證方法,從 Appwrite 儲存和檢索資料和檔案。 - 使用 React Email 建立電子郵件模板,並使用 Novu 發送應用程式內和電子郵件通知。 如果您希望在應用程式中發送通知,Novu 是您的最佳選擇。使用 Novu,您可以為應用程式加入多個通知管道,包括聊天、簡訊、電子郵件、推播和應用程式內通知。 本教學的源程式碼可在此處取得: <https://github.com/novuhq/ecom-store-with-nextjs-appwrite-novu-and-stripe> 感謝您的閱讀! --- 原文出處:https://dev.to/novu/building-an-e-commerce-store-with-nextjs-49m

使用 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

適用於 React 和 NodeJS 的最佳免費開源 SaaS 模板

展示開放 SaaS 🎉 ----------- 我們非常高興推出[Open SaaS](https://opensaas.sh) ,這是適用於 React、NodeJS 和 Prisma 的完全免費、開源、生產級 SaaS 樣板。 在這裡查看它的實際效果: https://www.youtube.com/watch?v=rfO5SbLfyFE Open SaaS 擁有您最近看到的那些付費 SaaS 入門者的所有功能,除了它完全**免費**且**開源**。 **我們覺得為一些需要自己管理的樣板程式碼支付 300-2,000 美元是瘋狂的**。最重要的是,許多樣板文件嚴重依賴第三方服務。再加上託管和其他費用,您需要花費大量資金才能將您的想法推向世界。 **這就是為什麼透過開放 SaaS,我們有意識地決定盡可能嘗試使用開源和免費服務。**例如,我們在[OpenSaaS.sh](http://OpenSaaS.sh)上託管的演示應用程式及其管理儀表板由 Plausible 分析的自架版本提供支援。希望您的 SaaS 具有相同的功能嗎?那麼,Open SaaS 已為您預先配置好! 此外,Open SaaS 使用的[Wasp 框架](https://wasp.sh)可以為您建立許多功能,例如 Auth 和 Cron 作業,這樣您就不必支付第三方服務費用或完全自己編寫程式碼(我們稍後會更詳細地解釋這一點)。 人們已經在使用開放 SaaS 建置什麼... ---------------------- 自正式發布以來,已有大量人員使用 Open SaaS 建立了令人驚嘆的應用程式並推出了超級創意業務。因此,我們首先要強調其中的一些內容。 以下是我們社區中一些應用程式的精選清單: 1. [Solon](https://trysolon.co) :Instagram/whatsapp 賣家的人工智慧銷售代理,幫助客戶探索產品。 ![梭倫](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j32pl4a078c587jffsin.png) 2. [Captn.ai](https://captn.ai) :人工智慧代理團隊協作,自動建立、監控和優化 Google Ads 廣告活動。 ![船長](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzygxmy4iu1yi9r758nc.png) 3. [Bleepify](https://bleepify.me) :在人工智慧的幫助下,自動配音或立即從影片中刪除某些單字。對於快速使 YouTube 影片符合其行為準則非常有幫助。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eqdqbvjwvfpv2rmmaypn.png) 4. [取得 AI 部落格文章](https://getaiblogarticles.com/):以 Markdown 格式提供的高品質、專注於 SEO 的部落格文章產生器 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qyzpg3gbipgyuy7g6lh.png) 如果上面的這些範例還沒有激發您的建造靈感,請繼續閱讀下面的內容,我們將討論為什麼建立開源 SaaS 模板、我們使用的堆疊以及它的工作原理。 為什麼我們要建造它......然後免費贈送它 ---------------------- 自從我們正式發布以來,反饋非常積極。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/subbtpb2syehdtuuof0r.png) 很多人對它讚不絕口,並且已經用它建置了許多 SaaS 應用程式,但我們也收到了一些問題,例如: - “它會保持免費嗎?” - “您開源這個的動機是什麼?” 所以我們認為我們應該先回答這些問題。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5rac9o1rxgrwfx51mc50.png) 首先,是的,它是 100% 免費和開源的,並將保持這種狀態。 其次,我們相信,開發者、獨立駭客和個人企業家社群的集體知識將比個人或小團體產生更好的樣板。當您從某些開發人員那裡購買SaaS 入門版時,您已經獲得了一個固執己見的堆棧,然後除此之外,您還獲得了按照他們認為最好的方式建置的應用程式- 但這可能並不總是最適合*您。* 第三, [Open SaaS](https://opensaas.sh)是[Wasp](https://wasp.sh)的一個專案,一個超強的開源React + NodeJS + Prisma全端框架。我們 Wasp 團隊相信 Wasp 非常適合快速且有效率地建立 SaaS 應用程式,我們希望這個模板能夠證明這一點。另外,身為開發人員,我們從其他開源專案中學到了很多東西,而 Wasp 本身就是一個開源專案。 基本上,我們熱愛開源理念,並且希望將其發揚光大。 🙏 因此,我們希望能夠為開發者社群提供非常有價值的資產,同時宣傳我們的開源全端框架。我們很高興看到社區為其做出貢獻,以便它不斷發展並成為最好的 SaaS 樣板。 開放 SaaS 是由什麼組成的 --------------- 我們在 Open SaaS 上投入了大量的精力,包括[文件](https://docs.opensaas.sh),以便開發人員可以自信、輕鬆地啟動 SaaS 應用程式。 我們還花了一些時間檢查其他免費的開源 SaaS 啟動器,並希望確保 Open SaaS 具有可立即投入生產的啟動器的所有正確功能,而不顯得臃腫。我們認為我們已經在很大程度上實現了這一點,儘管我們將繼續加入功能並隨著時間的推移進行改進。 目前的主要特點如下: - 🔐 身份驗證(電子郵件驗證、Google、github) - 📩 電子郵件(sendgrid、emailgun、SMTP) - 📈 管理儀表板(合理或谷歌分析) - 🤑 Stripe 付款(只需加入您的訂閱產品 ID) - ⌨️ 端對端類型安全性(無需配置) - 🤖 OpenAI 整合(AI 驅動的範例應用程式) - 📖 Astro 博客 - 🧪 與劇作家進行端到端測試 - 🚀 部署在任何地方 - 📄 完整的文件和社群支持 值得深入了解其中每個功能的細節,所以讓我們開始吧。 ### 授權 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wbistoghxrxft9zxxra1.png)](https://www.producthunt.com/posts/open-saas) 感謝 Wasp,Open SaaS 附帶了許多可能的身份驗證方法: - 使用者名稱和密碼(最簡單/最容易進行開發測試) - 已驗證電子郵件並重設密碼 - Google 和/或 Github 社群登入 這就是 Wasp 真正發揮作用的地方,因為設定全端 Auth 並取得預先配置的 UI 元件所需要做的就是: ``` //main.wasp app SaaSTemplate { auth: { userEntity: User, methods: { usernameAndPassword: {}, google: {}, gitHub: {}, } } } ``` 嚴重地。就是這樣! 只需確保您已設定社交身份驗證並擁有 API 金鑰以及定義的`User`和`ExternalAuth`實體,就可以開始了。不用擔心,這部分內容已在[Open SaaS Docs](https://docs.opensaas.sh)中詳細記錄和解釋。 最重要的是,Open SaaS 預先配置了一些範例,說明如何自訂和建立一些真正強大的身份驗證流程。 ### 管理儀表板和分析 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4mm6s1c3txxgm49e2k7w.png)](https://www.producthunt.com/posts/open-saas) 透過利用[Wasp 的工作功能](https://wasp-lang.dev/docs/advanced/jobs),Open SaaS 每小時從 Plausible 或 Google 的網站分析(您的選擇!)和 Stripe 的資料 API 中提取資料,並將其保存到我們的資料庫中。然後,該資料將顯示在我們的管理儀表板上(前往[OpenSaaS.sh](https://OpenSaaS.sh)查看其實際情況)。好的部分是,要為您自己的應用程式存取這些資料,您所要做的就是按照我們的指南獲取分析 API 金鑰,插入提供的腳本,然後就可以開始了! 再次強調,Wasp 讓整個過程變得非常簡單。透過已經為您定義的查詢 API 和取得我們需要的資料的功能,Open SaaS 然後在`main.wasp`設定檔中使用 Wasp 作業: ``` job dailyStatsJob { executor: PgBoss, perform: { fn: import { calculateDailyStats } from "@server/workers/calculateDailyStats.js" }, schedule: { cron: "0 * * * *" }, entities: [User, DailyStats, Logs, PageViewSource] } ``` 就是這樣! Wasp 負責為您設定和執行 cron 作業。 ### 條紋支付 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugy3mx9xo1d9i9vfysr7.png)](https://www.producthunt.com/posts/open-saas) 如果您是以前從未建立過自己的 SaaS 的開發人員,那麼與 Stripe 這樣的支付處理器整合可能是您將面臨的少數挑戰之一。 當我建立第一個 SaaS [CoverLetterGPT.xyz](https://coverlettergpt.xyz)時,我的情況就是如此。這實際上是我建造它的主要動機之一;了解如何將 Stripe 支付整合到應用程式以及 OpenAI API 中。 儘管 Stripe 因擁有豐富的文件而聞名,但這個過程仍然令人畏懼。你必須: - 建立正確的產品類型 - 設定 webhook 端點 - 告訴 Stripe 將正確的 Webhook 事件傳送給您 - 正確使用事件 - 處理重複付款和失敗付款 - 在上線之前透過 CLI 進行正確測試 這就是為什麼為您設定 Stripe 訂閱付款是一個巨大的勝利。 但比這更重要的是,為您方便地記錄整個過程!這就是為什麼 Open SaaS[在我們的文件中為您提供方便的 Stripe 指南](https://docs.opensaas.sh)🙂 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uehwot350u3dl02s4w7r.png)](https://www.producthunt.com/posts/open-saas) ### 端對端類型安全 Open SaaS 是使用 Typescript 建置的,因為它是一個全棧應用程式,所以從後端到前端的類型安全可以成為真正的救星。我的意思是,一些[固執己見的堆疊](https://create.t3.gg/)在此基礎上變得非常流行。 幸運的是,Wasp 為您提供開箱即用的端到端類型安全性(無需配置!),因此 Open SaaS 可以輕鬆利用它。 這是一個例子: 1. 讓 Wasp 了解您的伺服器操作: ``` // main.wasp action getResponse { fn: import { getResponse } from "@server/actions.js", entities: [Response] } ``` 2. 輸入並實施您的伺服器操作。 ``` // src/srever/actions.ts type RespArgs = { hours: string; }; const getResponse: GetResponse<RespArgs, string> = async ({ hours }) => { } ``` 3. 導入並在客戶端呼叫。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fah81r1g4bg3vdqapju.png) 客戶端類型將被正確推斷! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7n04yh6de9slhhnjrgf3.png) ### AI 驅動的範例應用程式(附有 OpenAI API) [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zbbc2gkxbxjl3q2y01a3.png)](https://www.producthunt.com/posts/open-saas) 人工智慧正在使新的應用程式創意成為可能,這也是我們看到開發人員對建立 SaaS 應用程式的興趣重新抬頭的部分原因。正如我上面提到的,我建造的第一個 SaaS 應用程式[CoverLetterGPT](https://coverlettergpt.xyz)是「GPT 包裝器」之一,我很自豪地說它帶來了約350 美元MRR(每月經常性收入)的可觀被動收入。 我個人認為,我們在軟體開發方面處於最佳狀態,開發新的、有利可圖的人工智慧應用程式有很大的潛力,尤其是「獨立駭客」和「個人企業家」。 這就是 Open SaaS 推出 AI 調度助手演示應用程式的原因。您輸入任務及其分配的時間,AI Scheduler 會為您的一天建立詳細的計劃。 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j4suf7g9jm5w93ri3bqx.png)](https://www.producthunt.com/posts/open-saas) 在幕後,這是使用 OpenAI 的 API 為每個任務分配優先級,並將它們分解為詳細的子任務,包括喝咖啡休息時間!它還利用 OpenAI 的函數呼叫功能以使用者定義的 JSON 物件回傳回應,以便客戶端每次都能正確使用它。此外,我們計劃在未來加入開源法學碩士,敬請期待! 示範版 AI Scheduler 可協助開發人員學習如何有效使用 OpenAI API,並激發一些 SaaS 應用程式創意! ### 隨處部署。容易地。 許多流行的 SaaS 新創公司都使用依賴託管的框架,這意味著您只能依賴一個提供者進行部署。雖然這些都是簡單的選擇,但它可能並不總是最適合您的應用程式。 Wasp 為您提供了部署全端應用程式的無限可能性: - 使用`wasp deploy`一鍵部署到[Fly.io](http://Fly.io) - 使用`wasp build`並部署 Dockerfiles 和客戶端,無論您喜歡什麼! `wasp deploy`的優點在於它會自動產生和部署您的資料庫、伺服器和用戶端,並為您設定環境變數。 Open SaaS 還內建了環境變數和常數驗證器,以確保您已正確設定部署所需的所有內容,以及文件中的部署指南 [![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fihbij250xtbdtjbjoks.png)](https://www.producthunt.com/posts/open-saas) 最後,您擁有自己的程式碼,並且可以自由地將其部署到任何地方,而無需受供應商鎖定。 幫助我們,幫助你 -------- 想支持我們的免費開源計畫嗎?然後[在 GitHub 上為我們加註星標以向](https://github.com/wasp-lang/open-saas/)我們表示支持🙏 ![https://media1.giphy.com/media/ZfK4cXKJTTay1Ava29/giphy.gif?cid=7941fdc6pmqo30ll0e4rzdiisbtagx97sx5t0znx4lk0auju&ep=v1_gifs_searchx97sx5t0znx4lk0auju&ep=v1_gifs_search}&ridgi.](https://media1.giphy.com/media/ZfK4cXKJTTay1Ava29/giphy.gif?cid=7941fdc6pmqo30ll0e4rzdiisbtagx97sx5t0znx4lk0auju&ep=v1_gifs_search&rid=giphy.gif&ct=g) <https://www.github.com/wasp-lang/wasp> ⭐️ 給 Open SaaS 一顆星 🙏 現在就開始建立您的 SaaS! --------------- 我們希望 Open SaaS 能夠讓更多的開發人員能夠發布他們的想法和副專案。我們也希望從開發人員那裡獲得一些回饋和意見,以便我們能夠使其成為最好的 SaaS 樣板啟動器。 因此,如果您有任何意見或發現任何錯誤,請[在此處提交問題](https://github.com/wasp-lang/open-saas/issues)。 如果您發現 Open SaaS 和/或 Wasp 很有用,最簡單的支援方法就是給我們一顆星: - 為[Open SaaS 儲存庫](https://github.com/wasp-lang/open-saas)加註星標 - 給[黃蜂倉庫](https://github.com/wasp-lang/wasp)加註星標 --- 原文出處:https://dev.to/wasp/the-best-free-open-source-saas-template-for-react-nodejs-263

提升你的技能

介紹 -- 學習如何成為更好的開發人員需要不斷提升自己的技能。一個人如何學習成長並成為更好的開發人員?讓我們探討幾個總體上適用於大多數開發人員的想法。程式碼範例全部採用 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

編寫 SOLID React Hooks

SOLID 是較常用的設計模式之一。它在許多語言和框架中都很常用,也有一些文章介紹如何在 React 中使用它。 每篇關於 SOLID 的 React 文章都以稍微不同的方式介紹該模型,有些將其應用於元件,有些將其應用於 TypeScript,但很少有人將這些原理應用於鉤子。 由於 hooks 是 React 基礎的一部分,我們將在這裡看看 SOLID 原則如何應用於這些。 單一職責原則(SRP) ----------- Solid 中的第一個字母 S 是最容易理解的。本質上,它的意思是,讓一個鉤子/元件做一件事。 ``` // Single Responsibility Principle ``` ``` A module should be responsible to one, and only one, actor ``` 例如,看看下面的 useUser 鉤子,它會取得使用者和待辦事項,並將任務合併到使用者物件中。 ``` import { useState } from 'react' import { getUser, getTodoTasks } from 'somewhere' const useUser = () => { const [user, setUser] = useState() const [todoTasks, setTodoTasks] = useState() useEffect(() => { const userInfo = getUser() setUser(userInfo) }, []) useEffect(() => { const tasks = getTodoTasks() setTodoTasks(tasks) }, []) return { ...user, todoTasks } } ``` 這個鉤子並不牢固,它不遵守單一責任原則。這是因為它有責任獲取用戶資料和待辦任務,這是兩件事。 相反,上面的程式碼應該分為兩個不同的鉤子,一個用於獲取有關用戶的資料,另一個用於獲取任務。 ``` import { useState } from 'react' import { getUser, getTodoTasks } from 'somewhere' // useUser hook is no longer responsible for the todo tasks. const useUser = () => { const [user, setUser] = useState() useEffect(() => { const userInfo = getUser() setUser(userInfo) }, []) return { user } } // Todo tasks do now have their own hook. // The hook should actually be in its own file as well. Only one hook per file! const useTodoTasks = () => { const [todoTasks, setTodoTasks] = useState() useEffect(() => { const tasks = getTodoTasks() setTodoTasks(tasks) }, []) return { todoTasks } } ``` 這個原則適用於所有的鉤子和元件,它們都應該只做一件事。要問自己的事情是: 1. 這是一個應該顯示 UI(演示性)或處理資料(邏輯性)的元件嗎? 1. 這個鉤子應該處理什麼單一類型的資料? 1. 這個鉤子/元件屬於哪一層?它是處理資料儲存還是 UI 的一部分? 如果您發現自己建造的鉤子對上述每個問題都沒有單一答案,那麼您就違反了單一責任原則。 這裡值得注意的一件有趣的事情是第一個問題。這實際上意味著渲染 UI 的元件不應該處理資料。這意味著,要真正嚴格遵循這項原則,每個顯示資料的 React 元件都應該有一個鉤子來處理其邏輯和資料。換句話說,不應在顯示資料的相同元件中取得資料。 ### 為什麼在 React 中使用 SRP? 這種單一責任原則其實非常適合 React。 React 遵循基於元件的架構,這意味著它由組合在一起的小元件組成,因此它們一起可以建構並形成一個應用程式。元件越小,可重複使用的可能性就越大。這適用於元件和鉤子。 因此,React 或多或少是建立在單一職責原則上的。如果你不遵循它,你會發現自己總是在編寫新的鉤子和元件,並且很少重複使用它們中的任何一個。 違反單一責任原則將使您的程式碼難以測試。如果不遵循這個原則,您經常會發現您的測試文件有數百行,甚至可能多達 1000 行程式碼。 {% 嵌入 https://dev.to/perssondennis/how-to-use-mvvm-in-react-using-hooks-and-typescript-3o4m %} 開閉原理 (OCP) ---------- 讓我們繼續遵循開閉原則,畢竟這是 SOLID 中的下一個字母。 OCP 和 SRP 一樣是較容易理解的原則之一,至少其定義是如此。 ``` // Open/Closed Principle ``` ``` Software entities (classes, modules, functions, etc.) should ``` ``` be open for extension, but closed for modification ``` 對於最近開始使用 React 的傻瓜來說,這句話可以翻譯為: ``` Write hooks/component which you never will have a reason to ``` ``` touch again, only re-use them in other hooks/components ``` 回想一下本文前面所說的單一責任原則;在 React 中,您需要編寫小元件並將它們組合在一起。讓我們看看為什麼這有幫助。 ``` import { useState } from 'react' import { getUser, updateUser } from 'somewhere' const useUser = ({ userType }) => { const [user, setUser] = useState() useEffect(() => { const userInfo = getUser() setUser(userInfo) }, []) const updateEmail = (newEmail) => { if (user && userType === 'admin') { updateUser({ ...user, email: newEmail }) } else { console.error('Cannot update email') } } return { user, updateEmail } } ``` 上面的鉤子獲取用戶並返回它。如果使用者的類型是管理員,則允許該使用者更新其電子郵件。普通使用者不允許更新其電子郵件。 上面的程式碼絕對不會讓你被解僱。但這會惹惱你團隊中的後端人員,他會為他的孩子閱讀設計模式書籍作為睡前故事。我們就叫他皮特吧。 皮特會抱怨什麼?他會要求你重寫該元件,如下所示。將管理功能提升到它自己的 useAdmin 掛鉤,並讓 useUser 掛鉤除了那些應該可供普通用戶使用的功能之外沒有其他功能。 ``` import { useState } from 'react' import { getUser, updateUser } from 'somewhere' // useUser does now only return the user, // without any function to update its email. const useUser = () => { const [user, setUser] = useState() useEffect(() => { const userInfo = getUser() setUser(userInfo) }, []) return { user } } // A new hook, useAdmin, extends useUser hook, // with the additional feature to update its email. const useAdmin = () => { const { user } = useUser() const updateEmail = (newEmail) => { if (user) { updateUser({ ...user, email: newEmail }) } else { console.error('Cannot update email') } } return { user, updateEmail } } ``` 皮特為什麼要求更新?因為那個無禮挑剔的混蛋皮特寧願希望你現在花時間重寫那個鉤子,然後明天回來進行新的程式碼審查,而不是將來可能需要用一個微小的新 if 語句更新程式碼,如果有的話成為另一種類型的使用者。 好吧,這是消極的說法...樂觀的說法是,使用這個新的useAdmin 掛鉤,當您打算實現僅影響管理員用戶的功能時,或者當您打算實現僅影響管理員用戶的功能時,您不必更改useUser 掛鉤中的任何內容。 當新增新的使用者類型或更新 useAdmin 掛鉤時,無需弄亂 useUser 掛鉤或更新其任何測試。這意味著,當您新增的使用者類型(例如假使用者)時,您不必意外地將錯誤傳送給普通使用者。相反,您只需加入一個新的 userFakeUser 鉤子,您的老闆就不會在周五晚上 9 點給您打電話,因為客戶在發薪週末會遇到銀行帳戶顯示虛假資料的問題。 ![床下的前端開發人員](https://www.perssondennis.com/images/articles/write-solid-react-hooks/frontend-developer-under-the-bed.webp) *皮特的兒子知道要小心義大利麵式程式碼開發人員* ### 為什麼在 React 中使用 OCP? 一個 React 專案應該有多少個 hooks 和元件是有爭議的。每一個都需要渲染效果圖的代價。 React 不是 Java,其中 22 種設計模式導致 422 個類別用於簡單的 TODO 清單實作。這就是狂野西部網絡 (www) 的魅力所在。 然而,開放/封閉原則顯然也是在 React 中使用的少數模式。上面的鉤子範例是最小的,鉤子沒有做太多事情。隨著更多實質的掛鉤和更大的專案,這項原則變得非常重要。 這可能會花費您一些額外的鉤子,並且需要稍長的時間來實現,但是您的鉤子將變得更加可擴展,這意味著您可以更頻繁地重複使用它們。您將不必經常重寫測試,從而使掛鉤更加牢固。最重要的是,如果您從不接觸舊程式碼,則不會在舊程式碼中產生錯誤。 ![沒有破損的東西不要碰](https://www.perssondennis.com/images/articles/write-solid-react-hooks/dont-touch-what-is-not-broken.webp) *天知道不要碰沒有破損的東西* {% 嵌入 https://dev.to/perssondennis/react-anti-patterns-and-best-practices-dos-and-donts-3c2g %} 里氏替換原理 (LSP) ------------ 啊啊,這個名字……誰是利斯科夫?而誰來代替她呢?而這個定義,難道就沒有意義嗎? ``` If S subtypes T, what holds for T holds for S ``` 這個原則顯然是關於繼承的,在 React 或 JavaScript 中,繼承的實踐並不像大多數後端語言中那麼多。 JavaScript 在 ES6 之前甚至沒有類,ES6 是[在 2015/2016 年左右引入的,](https://caniuse.com/?search=class)作為基於原型的繼承的語法糖。 考慮到這一點,該原則的用例實際上取決於您的程式碼的外觀。類似 Liskov 的原則在 React 中有意義,可能是: ``` If a hook/component accepts some props, all hooks and components ``` ``` which extends that hook/component must accept all the props the ``` ``` hook/component it extends accepts. The same goes for return values. ``` 為了說明這一點,我們可以看一下兩個儲存鉤子:useLocalStorage 和 useLocalAndRemoteStorage。 ``` import { useState } from 'react' import { getFromLocalStorage, saveToLocalStorage, getFromRemoteStorage } from 'somewhere' // useLocalStorage gets data from local storage. // When new data is stored, it calls saveToStorage callback. const useLocalStorage = ({ onDataSaved }) => { const [data, setData] = useState() useEffect(() => { const storageData = getFromLocalStorage() setData(storageData) }, []) const saveToStorage = (newData) => { saveToLocalStorage(newData) onDataSaved(newData) } return { data, saveToStorage } } // useLocalAndRemoteStorage gets data from local and remote storage. // I doesn't have callback to trigger when data is stored. const useLocalAndRemoteStorage = () => { const [localData, setLocalData] = useState() const [remoteData, setRemoteData] = useState() useEffect(() => { const storageData = getFromLocalStorage() setLocalData(storageData) }, []) useEffect(() => { const storageData = getFromRemoteStorage() setRemoteData(storageData) }, []) const saveToStorage = (newData) => { saveToLocalStorage(newData) } return { localData, remoteData, saveToStorage } } ``` 透過上面的鉤子,useLocalAndRemoteStorage 可以被視為 useLocalStorage 的子類型,因為它與 useLocalStorage 執行相同的操作(保存到本地存儲),而且還通過將資料保存到其他位置來擴展 useLocalStorage 的功能。 這兩個鉤子有一些共享的屬性和回傳值,但是 useLocalAndRemoteStorage 缺少 useLocalStorage 接受的 onDataSaved 回呼屬性。傳回屬性的名稱也有不同的命名,本地資料在useLocalStorage中命名為data,而在useLocalAndRemoteStorage中命名為localData。 如果你問利斯科夫,這就違背了她的原則。實際上,當她嘗試更新Web 應用程式以在伺服器端保留資料時,她會非常憤怒,只是意識到她不能簡單地用useLocalAndRemoteStorage 鉤子替換useLocalStorage,只是因為一些懶惰的開發人員從未為useLocalAndRemoteStorage 鉤子實現onDataSaved回調。 利斯科夫會痛苦地更新鉤子來支持這一點。同時,她也會更新 useLocalStorage 掛鉤中的本地資料名稱,以符合 useLocalAndRemoteStorage 中的本地資料名稱。 ``` import { useState } from 'react' import { getFromLocalStorage, saveToLocalStorage, getFromRemoteStorage } from 'somewhere' // Liskov has renamed data state variable to localData // to match the interface (variable name) of useLocalAndRemoteStorage. const useLocalStorage = ({ onDataSaved }) => { const [localData, setLocalData] = useState() useEffect(() => { const storageData = getFromLocalStorage() setLocalData(storageData) }, []) const saveToStorage = (newData) => { saveToLocalStorage(newData) onDataSaved(newData) } // This hook does now return "localData" instead of "data". return { localData, saveToStorage } } // Liskov also added onDataSaved callback to this hook, // to match the props interface of useLocalStorage. const useLocalAndRemoteStorage = ({ onDataSaved }) => { const [localData, setLocalData] = useState() const [remoteData, setRemoteData] = useState() useEffect(() => { const storageData = getFromLocalStorage() setLocalData(storageData) }, []) useEffect(() => { const storageData = getFromRemoteStorage() setRemoteData(storageData) }, []) const saveToStorage = (newData) => { saveToLocalStorage(newData) onDataSaved(newData) } return { localData, remoteData, saveToStorage } } ``` 透過為鉤子提供通用介面(傳入的 props、傳出的返回值),它們可以變得非常容易交換。如果我們遵循里氏替換原則,繼承另一個鉤子/元件的鉤子和元件應該可以用它繼承的鉤子或元件替換。 ![擔心的利斯科夫](https://www.perssondennis.com/images/articles/write-solid-react-hooks/worried-liskov.webp) *當開發人員不遵循她的原則時,利斯科夫感到失望* ### 為什麼在 React 中使用 LSP? 儘管繼承在 React 中並不是很突出,但它肯定在幕後使用。 Web 應用程式通常可以有幾個外觀相似的元件。文字、標題、連結、圖示連結等都是類似類型的元件,可以從繼承中受益。 IconLink 元件可能會也可能不會包裝 Link 元件。無論哪種方式,它們都會受益於使用相同的介面(使用相同的 props)實作。這樣,您可以隨時在應用程式中的任何位置將 Link 元件替換為 IconLink 元件,而無需編輯任何其他程式碼。 鉤子也是如此。 Web 應用程式從伺服器取得資料。他們也可能使用本地儲存或狀態管理系統。這些最好可以共享道具以使它們可以互換。 應用程式可能會從後端伺服器取得使用者、任務、產品或任何其他資料。類似的函數也可以共享接口,從而更容易重複使用程式碼和測試。 {% 嵌入 https://dev.to/perssondennis/the-20-most-common-use-cases-for-javascript-arrays-2j8j %} 介面隔離原則(ISP) ----------- 另一個更明確的原則是介面隔離原則。定義很短。 ``` No code should be forced to depend on methods it does not use ``` 顧名思義,它與介面有關,基本上意味著函數和類別應該只實現它明確使用的介面。最容易實現這一點的方法是保持介面整潔,讓類別選擇其中的一些來實現,而不是被迫用它不關心的幾種方法來實現一個大介面。 例如,代表擁有網站的人的類別應該實現兩個接口,一個稱為 Person 的接口,描述有關此人的詳細訊息,另一個用於網站的接口,其中包含有關其擁有的網站的元資料。 ``` interface Person { firstname: string familyName: string age: number } interface Website { domain: string type: string } ``` 如果相反,建立一個單一介面網站,包括有關所有者和網站的訊息,則將違反介面隔離原則。 ``` interface Website { ownerFirstname: string ownerFamilyName: number domain: string type: string } ``` 你可能會想,上面的介面有什麼問題嗎?它的問題是它使介面不太可用。想想看,如果公司不是人,而是公司,你會怎麼做?公司其實沒有姓氏。然後您會修改介面以使其對人類和公司都可用嗎?或者您會建立一個新介面 CompanyOwnedWebsite 嗎? 然後,您最終會得到一個具有許多可選屬性的接口,或分別稱為 PersonWebsite 和 CompanyWebsite 的兩個接口。這些解決方案都不是最佳的。 ``` // Alternative 1 // This interface has the problem that it includes // optional attributes, even though the attributes // are mandatory for some consumers of the interface. interface Website { companyName?: string ownerFirstname?: string ownerFamilyName?: number domain: string type: string } // Alternative 2 // This is the original Website interface renamed for a person. // Which means, we had to update old code and tests and // potentially introduce some bugs. interface PersonWebsite { ownerFirstname: string ownerFamilyName: number domain: string type: string } // This is a new interface to work for a company. interface CompanyOwnedWebsite { companyName: string domain: string type: string } ``` ISP 遵循的解決方案如下所示。 ``` interface Person { firstname: string familyName: string age: number } interface Company { companyName: string } interface Website { domain: string type: string } ``` 透過上述適當的接口,代表公司網站的類別可以實現接口 Company 和 Website,但不需要考慮 Person 接口中的 firstname 和 familyName 屬性。 ### React 中使用 ISP 嗎? 所以,這個原則顯然適用於接口,這意味著它只應該在您使用 TypeScript 編寫 React 程式碼時才有意義,不是嗎? 當然不是!不輸入介面並不意味著它們不存在。到處都有,只是你沒有明確地輸入它們。 在 React 中,每個元件和鉤子都有兩個主要接口,輸入和輸出。 ``` // The input interface to a hook is its props. const useMyHook = ({ prop1, prop2 }) => { // ... // The output interface of a hook is its return values. return { value1, value2, callback1 } } ``` 使用 TypeScript,您通常會鍵入輸入接口,但輸出接口通常會被跳過,因為它是可選的。 ``` // Input interface. interface MyHookProps { prop1: string prop2: number } // Output interface. interface MyHookOutput { value1: string value2: number callback1: () => void } const useMyHook = ({ prop1, prop2 }: MyHookProps): MyHookOutput => { // ... return { value1, value2, callback1 } } ``` 如果鉤子不會將 prop2 用於任何用途,那麼它不應該成為其 props 的一部分。對於單一道具,可以輕鬆地將其從道具清單和介面中刪除。但是,如果 prop2 是物件類型,例如上一章不正確的 Website 介面範例,該怎麼辦? ``` interface Website { companyName?: string ownerFirstname?: string ownerFamilyName?: number domain: string type: string } interface MyHookProps { prop1: string website: Website } const useMyCompanyWebsite = ({ prop1, website }: MyHookProps) => { // This hook uses domain, type and companyName, // but not ownerFirstname or ownerFamilyName. return { value1, value2, callback1 } } ``` 現在我們有一個 useMyCompanyWebsite 鉤子,它有一個 website 屬性。如果鉤子中使用了網站介面的部分內容,我們不能簡單地刪除整個網站道具。我們必須保留 website 屬性,因此也保留ownerFirstname 和ownerFamiliyName 的介面屬性。這也意味著,該針對公司的掛鉤可以由人類擁有的網站所有者使用,即使該掛鉤可能不適用於該用途。 ### 為什麼在 React 中使用 ISP? 我們現在已經了解了 ISP 的含義,以及它如何應用於 React,即使不使用 TypeScript。透過查看上面的小例子,我們也看到了一些不遵循 ISP 的問題。 在更複雜的專案中,可讀性是最重要的。介面隔離原則的目的之一是避免混亂,避免不必要的程式碼的存在,這些程式碼只會破壞可讀性。不要忘記可測試性。您是否應該關心您實際未使用的道具的測試覆蓋率? 實現大型介面也迫使您將 props 設定為可選。導致更多的 if 語句來檢查函數的存在和潛在的誤用,因為在介面上顯示該函數將處理此類屬性。 {% 嵌入 https://dev.to/perssondennis/answers-to-common-nextjs-questions-1oki %} 依賴倒置原則(DIP) ----------- 最後一個原則,即 DIP,包括一些被廣泛誤解的術語。令人困惑的地方在於依賴反轉、依賴注入和控制反轉之間的差異。所以我們先聲明一下。 **依賴倒置** 依賴倒置原則(DIP)表示高階模組不應該從低階模組導入任何內容,兩者都應該依賴抽象。這意味著任何高階模組自然可能依賴它所使用的模組的實作細節,但不應該具有這種依賴性。 高級模組和低階模組的編寫方式應使它們都可以在不了解其他模組內部實現的任何細節的情況下使用。只要介面保持不變,每個模組都應該可以用它的替代實作來替換。 **控制反轉** 控制反轉(IoC)是用來解決依賴反轉問題的原理。它指出模組的依賴關係應由外部實體或框架提供。這樣,模組本身只需使用依賴項,而不必建立依賴項或以任何方式管理它。 **依賴注入** 依賴注入(DI)是實現 IoC 的常見方法。它透過建構函數或 setter 方法注入模組來提供對模組的依賴關係。這樣,模組就可以使用依賴項而無需負責建立它,這符合 IoC 原則。值得一提的是,依賴注入並不是實現控制反轉的唯一方法。 ### React 中使用 DIP 嗎? 澄清了這些術語,並知道 DIP 原則是關於依賴倒置的,我們可以再次看看這個定義是怎樣的。 ``` High-level modules should not import anything from low-level modules. ``` ``` Both should depend on abstractions ``` 這如何適用於 React? React 不是一個通常與依賴注入相關的函式庫,那我們該如何解決依賴倒置的問題呢? 這個問題最常見的解決方案是鉤子。鉤子不能算作依賴注入,因為它們被硬編碼到元件中,並且不可能在不更改元件實現的情況下用另一個鉤子替換鉤子。相同的鉤子將在那裡,使用相同的鉤子實例,直到開發人員更新程式碼。 但請記住,依賴注入並不是實現依賴倒置的唯一方法。 Hooks 可以被視為 React 元件的外部依賴,它有一個介面(它的 props),可以抽像出 hook 中的程式碼。這樣,鉤子就實現了依賴倒置的原則,因為元件依賴抽象接口,而不需要知道有關鉤子的任何細節。 React 中 DIP 的另一個更直觀的實作(實際上使用依賴注入)是 HOC 和上下文的使用。請參閱下面的 withAuth HOC。 ``` const withAuth = (Component) => { return (props) => { const { user } = useContext(AuthContext) if (!user) { return <LoginComponent> } return <Component {...props} user={user} /> } } const Profile = () => { // Profile component... } // Use the withAuth HOC to inject user to Profile component. const ProfileWithAuth = withAuth(Profile) ``` 上面顯示的 withAuth HOC 使用依賴項注入為使用者提供 Profile 元件。這個範例的有趣之處在於,它不僅顯示了依賴注入的一種用法,而且實際上包含了兩個依賴注入。 將使用者註入到設定檔元件並不是此範例中的唯一注入。 withAuth 鉤子實際上也透過 useContext 鉤子透過依賴注入來獲取使用者。在程式碼中的某個地方,有人聲明了一個將使用者註入上下文的提供者。該用戶實例甚至可以在執行時透過更新上下文中的用戶來更改。 ### 為什麼在 React 中使用 DIP? 儘管依賴注入不是與 React 相關的常見模式,但它實際上與 HOC 和上下文相關。鉤子從 HOC 和上下文中佔據了大量市場份額,也很好地證實了依賴倒置原則。 因此,DIP 已經內建到 React 庫本身中,當然應該使用。它既易於使用,又具有模組之間的鬆散耦合、鉤子和元件的可重複使用性和可測試性等優點。它也使得實現其他設計模式(例如單一職責原則)變得更加容易。 我不鼓勵的是,當確實有更簡單的解決方案可用時,請嘗試實施智慧解決方案並過度使用該模式。我在網路和書籍中看到了使用 React 上下文的建議,其唯一目的是實現依賴注入。像下面這樣的東西。 ``` const User = () => { const { role } = useContext(RoleContext) return <div>{`User has role ${role}`}</div> } const AdminUser = ({ children }) => { return ( <RoleContext.Provider value={{ role: 'admin' }}> {children} </RoleContext.Provider> ) } const NormalUser = ({ children }) => { return ( <RoleContext.Provider value={{ role: 'normal' }}> {children} </RoleContext.Provider> ) } ``` 儘管上面的範例確實將角色注入到 User 元件中,但為其使用上下文純粹是矯枉過正。當上下文本身有其用途時,應該在適當的時候使用 React 上下文。在這種情況下,一個簡單的道具可能是更好的解決方案。 ``` const User = ({ role }) => { return <div>{`User has role ${role}`}</div> } const AdminUser = () => <User role='admin' /> const NormalUser = () => <User role='normal' /> ``` {% cta https://2e015922.sibforms.com/serve/MUIFAGF3ypa0p6D6nTWI0MHVOIAC7q4TIJd0yXAhiBC9CswkNPnOlQBzeqSbR2XFM95gUn2G1IxWwCpDpDjkjk aaG9tz9UYhn\_O\_dWg1PPGS8kRM5ROREaJsslnGD8WEHszzZr0geJ9-g7lGsbn\_hTT-wZSKWa1C8ay4Ok85ozro %}訂閱我的文章{% endcta %} {% 嵌入 https://dev.to/perssondennis %} --- 原文出處:https://dev.to/perssondennis/write-solid-react-hooks-436o

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

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

PHP:Laravel,Ruby:Rails,JavaScript:?

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

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

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

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

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

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

我建立了一個免費的開源專案管理器,可以幫助團隊將成本控制在每月 15 美元以下。

大家好,這裡是胡迪! 今天,我很高興與大家分享我的開源專案經理。我從頭開始建立此專案的目標是將營運成本保持在每月 15 美元以下。 在決定建造它之前,我嘗試過 Trello、Jira 和 Clickup。它們都是很棒的工具,但成本對我們來說是一個主要障礙。作為一家越南新創公司的 7 - 10 名成員的小團隊,我們根本沒有這些付費平台的預算。 您可能想知道為什麼我們不只使用免費套餐。事情是這樣的:我相信我可以建立一個專案管理器,提供我們所需的指定功能,例如報告、匯出功能、看板、日曆等。 此外,當時我有大量的空閒時間,這使得這是一個承擔這個專案的好機會。 我在 github 上開源了這個應用程式: <https://github.com/hudy9x/namviek>或您可以查看網站[namviek.com](https://namviek.com) 這是給誰的? ------ 這個專案非常適合具有開發技能、在有限的預算下運作一個小團隊的人,就像我一樣。 乍一看可能令人望而生畏,但請參閱下面的成本報告。我能夠將營運成本從每月 49 美元(7 美元 x 7 名會員)大幅降低到每月 10 美元以下。 ![亞馬遜成本](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30fjxmx0fmmsuzc22cs7.png) 我是如何保持低成本的? ----------- 我利用各種免費平台來最大限度地降低營運成本。這是一個細分: - Vercel:用於前端(免費) - Aws Lightsail:用於後端(付費) - AWS S3:用於檔案儲存(付費) - Resend:發送電子郵件(免費) - Cloudflare:管理我的網域(免費) - Github Action:CD 自動化(免費) 我的技術堆疊 ------ 為了確保快速建置和部署,我在前端選擇了 Next.js,因為它與 Vercel 無縫整合。對於後端,我目前使用 Node.js,但我計劃在不久的將來將一些功能遷移到 Golang。 包含哪些功能? ------- 如前所述,該應用程式包含一些適合小型團隊的基本功能,例如: ### 清單顯示 一下子就看到了。在一個簡單的清單中確定任務的優先順序並管理您的任務。 ![清單顯示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aj75jb3vu9gl3nsppdy0.png) ### 板視圖 可視化您的工作流程。在階段之間移動任務以進行清晰的進度追蹤。 ![板視圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8p40vkwmxhmvtsq8bj2y.png) ### 目標視圖 保持目標。一目了然地查看您的進度並慶祝里程碑。 ![目標視圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n0uohpxfrshi5xwnhb1t.png) ### 日曆視圖 計劃你的日子。永遠不會錯過日曆上安排的任務的最後期限。 ![日曆視圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsndq9r27qszq3mvwo03.png) ### 自訂視圖 按照你的方式工作。設計完美的視圖以滿足您的特定需求。 ![查看客製化](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zk24iwg5dzf43dgvg5t0.png) 如何使用它。 ------ 查看[設定指南](https://www.namviek.com/#download)。如果您在設定過程中遇到任何錯誤,您可以參考[此處的](https://docs.namviek.com/doc/installation)完整指南。 也許您更喜歡逐步影片指南?看看下面這個影片: https://www.youtube.com/embed/3CS0DB4\_2FU 貢獻您的功能或錯誤修復 ----------- 該應用程式仍在開發中,歡迎您為改進它做出貢獻!請隨意提交功能請求和錯誤修復。 想要建議更好的解決方案或程式碼庫重構嗎?只需建立一個拉取請求,我很樂意討論它。 結論 -- 最後,我希望這個開源專案可以幫助您和您的團隊降低營運成本,同時提供透過修復錯誤和建立功能來學習新技能的機會。它將永遠免費使用。 下一個開源應用程式見:D --- 原文出處:https://dev.to/hudy9x/i-built-a-free-open-source-project-manager-that-helps-teams-keep-costs-under-15month-3pmk

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

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

掌握 SQL:結構化查詢語言綜合指南

介紹 -- 在上一篇部落格文章中,我們共同探討了以下內容的綜合指南: https://dev.to/louaiboumediene/mastering-relational-database-design-a-compressive-guide-3jh8 在本文中,我們將在較高層次上發現實際用於實現資料庫模式設計的語言的語法和核心功能... SQL。 那麼...讓我們深入探討吧! ![讓我們深入了解圖像](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cvmr1vh4frdyjfmzf5sh.gif) --- 什麼是 SQL ------- SQL,即結構化查詢語言,是用於與所有**RDMS**對話的外觀語言,但是大多數時候,作為後端工程師(我們不是資料庫工程師),我們不直接使用 SQL,而是使用物件關係映射器**ORM**它在原始SQL 之上提供了一個更好、更可靠的接口,以便用我們首選的程式語言與資料庫進行通信,但是我們仍然需要SQL 的基本知識,以便快速、簡單地操作以及與資料庫互動。 ![如果我告訴你表情包怎麼辦](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvpr0nujx4fed7e4xvh3.png) --- 基本 SQL 查詢 --------- 基本 SQL 查詢涉及使用 SELECT、DISTINCT、WHERE、LIMIT 和 OFFSET 等命令從資料庫表中選擇特定資料。 ``` -- Selecting all columns from a table SELECT * FROM employees; -- Selecting specific columns SELECT first_name, last_name FROM employees; -- Using DISTINCT to get unique values SELECT DISTINCT department_id FROM employees; -- Using WHERE to filter results SELECT * FROM employees WHERE department_id = 10; -- Using LIMIT to limit the number of results SELECT * FROM employees LIMIT 5; -- Using OFFSET to skip certain rows SELECT * FROM employees OFFSET 5; ``` --- 過濾資料 ---- 在 SQL 中篩選資料可讓您根據某些條件從表格中擷取特定記錄,例如使用 >、<、= 等比較運算子以及 AND、OR 和 NOT 等邏輯運算子。 ``` -- Using comparison operators SELECT * FROM employees WHERE salary > 50000; -- Using logical operators SELECT * FROM employees WHERE department_id = 10 AND salary > 50000; -- Using IN and NOT IN SELECT * FROM employees WHERE department_id IN (10, 20); -- Using BETWEEN SELECT * FROM employees WHERE salary BETWEEN 40000 AND 60000; -- Using LIKE for pattern matching SELECT * FROM employees WHERE last_name LIKE 'S%'; ``` --- 資料排序 ---- SQL 中的資料排序是使用 ORDER BY 子句根據指定列以升序或降序排列檢索到的記錄。 ``` -- Sorting data in ascending order SELECT * FROM employees ORDER BY salary; -- Sorting data in descending order SELECT * FROM employees ORDER BY salary DESC; -- Sorting by multiple columns SELECT * FROM employees ORDER BY department_id, salary DESC; ``` --- 聚合函數 ---- SQL 中的聚合函數對一組值執行計算並傳回單一值。常見的聚合函數包括 COUNT、SUM、AVG、MIN 和 MAX。 ``` -- Counting the number of rows SELECT COUNT(*) FROM employees; -- Calculating total salary SELECT SUM(salary) FROM employees; -- Finding average salary SELECT AVG(salary) FROM employees; -- Finding minimum salary SELECT MIN(salary) FROM employees; -- Finding maximum salary SELECT MAX(salary) FROM employees; ``` --- 資料分組 ---- 在 SQL 中將資料分組可讓您使用 GROUP BY 子句(通常與聚合函數結合使用)對指定列中具有相同值的行進行分組。 ``` -- Grouping data by department SELECT department_id, COUNT(*) FROM employees GROUP BY department_id; -- Using HAVING to filter grouped data SELECT department_id, COUNT(*) FROM employees GROUP BY department_id HAVING COUNT(*) > 5; ``` --- 加入 -- SQL 中的聯結會根據相關資料列組合來自多個資料表的資料,以擷取跨這些資料表的資料。 ``` -- Inner Join SELECT * FROM employees INNER JOIN departments ON employees.department_id = departments.department_id; -- Left Join SELECT * FROM employees LEFT JOIN departments ON employees.department_id = departments.department_id; -- Right Join SELECT * FROM employees RIGHT JOIN departments ON employees.department_id = departments.department_id; -- Full Outer Join SELECT * FROM employees FULL OUTER JOIN departments ON employees.department_id = departments.department_id; ``` --- 子查詢 --- SQL 中的子查詢是另一個查詢中的巢狀查詢,用於檢索依賴另一個查詢結果的資料。 ``` -- Subquery example SELECT * FROM employees WHERE department_id IN (SELECT department_id FROM departments WHERE location_id = 1700); -- Correlated subquery example SELECT * FROM employees e WHERE salary > (SELECT AVG(salary) FROM employees WHERE department_id = e.department_id); ``` --- 意見 -- SQL 中的檢視是根據查詢結果產生的虛擬表,提供了一種簡化複雜查詢並限制對某些資料的存取的方法。 ``` -- Creating a view CREATE VIEW high_paid_employees AS SELECT * FROM employees WHERE salary > 80000; -- Updating a view CREATE OR REPLACE VIEW high_paid_employees AS SELECT * FROM employees WHERE salary > 90000; -- Dropping a view DROP VIEW IF EXISTS high_paid_employees; ``` --- 索引 -- SQL 中的索引透過在列上建立索引來提高查詢效能,從而實現更快的資料檢索。 ``` -- Creating an index CREATE INDEX idx_lastname ON employees(last_name); -- Dropping an index DROP INDEX idx_lastname; ``` --- 交易 -- SQL 中的交易透過將 SQL 語句分組為原子單元來確保資料完整性,從而確保所有語句都成功執行或全部都不執行。 ``` -- Beginning a transaction BEGIN TRANSACTION; -- Committing a transaction COMMIT; -- Rolling back a transaction ROLLBACK; ``` --- 儲存過程 ---- SQL中的預存程序是儲存在資料庫中的預編譯的SQL程式碼,可以透過單一命令執行,通常用於封裝頻繁執行的任務 ``` -- Creating a stored procedure CREATE PROCEDURE get_employee (IN employee_id INT) BEGIN SELECT * FROM employees WHERE employee_id = employee_id; END; -- Executing a stored procedure CALL get_employee(100); -- Modifying a stored procedure ALTER PROCEDURE get_employee (IN employee_id INT) BEGIN SELECT employee_id, first_name, last_name FROM employees WHERE employee_id = employee_id; END; -- Dropping a stored procedure DROP PROCEDURE IF EXISTS get_employee; ``` --- 備份與復原 ----- SQL 中的備份和復原涉及建立資料庫備份以防止資料遺失,並在資料庫發生故障或損壞時還原它們。 ``` -- Creating a full backup BACKUP DATABASE dbname TO disk = 'path_to_backup'; -- Creating a differential backup BACKUP DATABASE dbname TO disk = 'path_to_backup' WITH DIFFERENTIAL; -- Creating a transaction log backup BACKUP LOG dbname TO disk = 'path_to_backup'; -- Restoring from a backup RESTORE DATABASE dbname FROM disk = 'path_to_backup'; ``` --- SQL 方言和特定於供應商的擴展 ---------------- 雖然 SQL 是一種標準化語言,但不同的資料庫供應商已經實作了自己的擴充和方言,導致不同 RDBMS 之間 SQL 的編寫和執行方式略有不同。這些變更可能會影響使用特定資料庫系統的開發人員可用的語法、函數和特性。 例如,以下是特定於供應商的 SQL 方言和擴展的一些範例: **甲骨文SQL** : - Oracle SQL 包括專有擴展,例如分層查詢、分析函數和用於資料建模的 MODEL 子句。 - 範例: `SELECT CUBE(product, region) FROM sales;` (CUBE 是 Oracle 特定的用於產生小計的擴充) **SQL Server(微軟)** : - SQL Server 包含 T-SQL (Transact-SQL),它透過串流控制語言建構、錯誤處理和流程程式設計建構等功能擴展了標準 SQL。 - 範例: `SELECT ISNULL(column_name, 'default_value') FROM table_name;` (ISNULL 是一個 T-SQL 函數) **MySQL** : - MySQL 包括空間資料類型和函數、視窗函數以及用於正規表示式匹配的 REGEX 運算子等擴充。 - 範例: `SELECT column_name REGEXP '^pattern' FROM table_name;` (REGEXP 是 MySQL 特定的運算子) **PostgreSQL** : - PostgreSQL 包括陣列、JSON 支援、全文搜尋和範圍資料類型等擴充。 - 範例: `SELECT column_name || 'suffix' FROM table_name;` (|| 是 PostgreSQL 特定的字串連接運算子) ![RDBMS 之間的差異](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7m0q9jdx3opw29zja6j.png) 所以最合乎邏輯的方法是: 1. **基礎知識**:了解關聯式資料庫設計的基礎:實體、鍵、關係…。 。 2. **SQL** :學習 SQL 作為獨立語言的基礎知識。 3. **選擇 RDBM** :選擇最適合您的 RDBMS,然後按照其所有特殊語法和結構來使用它。 結論 -- SQL 本身就是一個廣闊的領域,包含許多我們沒有涉及的概念。事務、備份和文件管理只是更廣泛範圍的幾個範例。然而,對於像我們這樣的後端工程師來說,我們所介紹的基礎知識足以作為 SQL 的基礎概述。 --- 原文出處:https://dev.to/louaiboumediene/mastering-sql-comprehensive-guide-to-structured-query-language-4gh

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

20 多個使用 AI 的專案,具有完整的源程式碼🚀

過去幾天對於人工智慧來說是令人興奮的。 然而,作為開發人員,我們中的許多人還不了解人工智慧的易用性。 今天,我們將介紹您可以使用人工智慧輕鬆建立的精彩專案。無需成為人工智慧專家,每個工具都附帶教學或程式碼演練。 讓我們跳進去吧! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vxxzizvu643bfpbo1xu.gif) --- 1. [CopilotKit](https://github.com/CopilotKit/CopilotKit) - 在數小時內為您的產品提供 AI Copilot。 ------------------------------------------------------------------------------------ [![副駕駛套件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzuxjfog2ldam3csrl62.png)](https://github.com/CopilotKit/CopilotKit) 將 AI 功能整合到 React 中是很困難的,這就是 Copilot 的用武之地。一個簡單快速的解決方案,可將可投入生產的 Copilot 整合到任何產品中! 您可以使用兩個 React 元件將關鍵 AI 功能整合到 React 應用程式中。它們還提供內建(完全可自訂)Copilot 原生 UX 元件,例如`<CopilotKit />` 、 `<CopilotPopup />` 、 `<CopilotSidebar />` 、 `<CopilotTextarea />` 。 開始使用以下 npm 指令。 ``` npm i @copilotkit/react-core @copilotkit/react-ui ``` Copilot Portal 是 CopilotKit 提供的元件之一,CopilotKit 是一個應用程式內人工智慧聊天機器人,可查看目前應用狀態並在應用程式內採取操作。它透過插件與應用程式前端和後端以及第三方服務進行通訊。 這就是整合聊天機器人的方法。 `CopilotKit`必須包裝與 CopilotKit 互動的所有元件。建議您也開始使用`CopilotSidebar` (您可以稍後切換到不同的 UI 提供者)。 ``` "use client"; import { CopilotKit } from "@copilotkit/react-core"; import { CopilotSidebar } from "@copilotkit/react-ui"; import "@copilotkit/react-ui/styles.css"; export default function RootLayout({children}) { return ( <CopilotKit url="/path_to_copilotkit_endpoint/see_below"> <CopilotSidebar> {children} </CopilotSidebar> </CopilotKit> ); } ``` 您可以使用此[快速入門指南](https://docs.copilotkit.ai/getting-started/quickstart-backend)設定 Copilot 後端端點。 之後,您可以讓 Copilot 採取行動。您可以閱讀如何提供[外部上下文](https://docs.copilotkit.ai/getting-started/quickstart-chatbot#provide-context)。您可以使用`useMakeCopilotReadable`和`useMakeCopilotDocumentReadable`反應掛鉤來執行此操作。 ``` "use client"; import { useMakeCopilotActionable } from '@copilotkit/react-core'; // Let the copilot take action on behalf of the user. useMakeCopilotActionable( { name: "setEmployeesAsSelected", // no spaces allowed in the function name description: "Set the given employees as 'selected'", argumentAnnotations: [ { name: "employeeIds", type: "array", items: { type: "string" } description: "The IDs of employees to set as selected", required: true } ], implementation: async (employeeIds) => setEmployeesAsSelected(employeeIds), }, [] ); ``` 您可以閱讀[文件](https://docs.copilotkit.ai/getting-started/quickstart-textarea)並查看[演示影片](https://github.com/CopilotKit/CopilotKit?tab=readme-ov-file#demo)。 您可以輕鬆整合 Vercel AI SDK、OpenAI API、Langchain 和其他 LLM 供應商。您可以按照本[指南](https://docs.copilotkit.ai/getting-started/quickstart-chatbot)將聊天機器人整合到您的應用程式中。 基本想法是非常快速地建立人工智慧聊天機器人,而無需在製作任何基於法學碩士的應用程式時費力。 用例是巨大的,作為開發人員,我們絕對應該在下一個專案中嘗試使用 CopilotKit。 CopilotKit 在 GitHub 上擁有超過 5800 顆星,發布了 200 多個版本,這意味著它們不斷改進。 ![明星副駕駛套件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p8i6roafbjxvds26fl35.gif) {% cta https://go.copilotkit.ai/Anmol %} Star CopilotKit ⭐️ {% endcta %} --- ### 🎯 使用 CopilotKit 建立的熱門應用程式。 我們可以使用 CopilotKit 建立許多創新應用程式,所以讓我們探索一些脫穎而出的應用程式! ### ✅ [人工智慧驅動的部落格平台](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/tvx995v2lvyujnsavaxx.gif) 您可以閱讀本文,使用`Next.js` 、 `Langchain` 、 `Supabase`和`CopilotKit`來建立這個令人驚嘆的應用程式。 LangChain&Tavily用作網路搜尋人工智慧代理,Supabase用於儲存和檢索部落格平台文章資料,CopilotKit用於將人工智慧整合到應用程式中。 ![演示人工智慧部落格平台](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/88ni6x3pdno43vani7q9.png) 您可以檢查[GitHub 儲存庫](https://github.com/TheGreatBonnie/aipoweredblog)。 ### ✅ [V0.dev 複製](https://dev.to/copilotkit/i-created-a-v0-clone-with-nextjs-gpt4-copilotkit-3cmb)。 ![v0](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyutbegrv571lp3i6081.png) 如果您不熟悉,Vercel 的 V0 是一款人工智慧驅動的工具,可讓您根據提示產生 UI,以及許多其他有用的功能。 shadcn 元件現在可以在文件本身的 v0 中進行編輯(如其網站所示)。 ![v0 開發](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/951hk0jqrioboe4jxf5i.gif) 您可以使用`Next.js` 、 `GPT4`和`CopilotKit`建立 V0 的克隆。這個詳細的教程名列前 7 名,總的來說,這是一個值得加入到您的作品集中的偉大專案。 簽名頁的產生輸出如下所示。 ![簽名頁](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xu1l5el91x4w62sz7kh.png) 您可以透過點擊右上角的按鈕輕鬆在`React Code`和`UI`之間切換。這麼酷的概念! 您可以檢查[GitHub 儲存庫](https://github.com/Tabintel/v0-copilot-next)。 ### ✅ [人工智慧行銷經理](https://dev.to/copilotkit/build-an-ai-powered-campaign-manager-nextjs-openai-copilotkit-59ii)。 ![競選經理](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/moytsjm7lcq1g52sn0ot.gif) 您可以使用`Next.js` 、 `OpenAI` 、 `Radix UI` (用於實現可存取性)、 `Recharts` (用於建立互動式圖表)以及`CopilotKit`來建立這個出色的專案來閱讀本文。 您可以觀看 David 的示範! {% 嵌入 https://youtu.be/gCJpH6Tnj5g %} 如果你想用更少的錢學到更多,這是我最喜歡的一個。 我喜歡它的 UI(一般教學不是這樣),這正是它成為你的編碼清單上的一個乾淨專案的原因:) ![示範動圖](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gt14n0xn3bekl7u5uib1.gif) 您可以查看該應用程式的[現場演示](https://campaign-manager-demo.vercel.app/)。 您可以檢查[GitHub 儲存庫](https://github.com/CopilotKit/campaign-manager-demo)。 ### ✅ [附有人工智慧副駕駛的電子表格應用程式](https://dev.to/copilotkit/build-an-ai-powered-spreadsheet-app-nextjs-langchain-copilotkit-109d)。 ![電子表格應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gexhqf0alwmwguu7kqsv.gif) 您可以閱讀本文,使用`Next.js` 、 `GPT-4` 、 `LangChain`和`CopilotKit`來建立這個很棒的工具。 為了使工作更輕鬆,它使用[React Spreadsheet](https://github.com/iddan/react-spreadsheet)套件為 React 和[Tavily AI](https://tavily.com/)建立簡單的可自訂電子表格作為搜尋引擎,使 AI 代理能夠進行研究並存取即時知識 你可以觀看這個演示! {% 嵌入 https://www.youtube.com/watch?v=kGQ9xl5mSoQ %} 您也可以查看[現場演示](https://spreadsheet-demo-tau.vercel.app/)。我可以肯定地說,這是一個獨特的案例,你可以得到很多啟發。 您可以檢查[GitHub 儲存庫](https://github.com/CopilotKit/spreadsheet-demo)。 ### ✅[與您的履歷聊天](https://dev.to/copilotkit/how-to-build-the-with-nextjs-openai-1mhb)。 ![與履歷聊天](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gdagmyn1tvoa2lwfoqto.gif) 您可以閱讀本文,使用`Next.js` 、 `OpenAI`和`CopilotKit`來建立這個很棒的用例。 您不僅可以使用 ChatGPT 產生履歷,還可以將其匯出為 PDF,甚至可以透過與其對話來進一步改進它。多酷啊,對吧:) ![簡歷聊天演示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6j27yls99cdv219ztwx.png) 您可以檢查[GitHub 儲存庫](https://github.com/TheGreatBonnie/AIPoweredResumeBuilder)。 ### ✅ [文字到 Powerpoint 應用程式](https://dev.to/copilotkit/how-to-build-ai-powered-powerpoint-app-nextjs-openai-copilotkit-ji2)。 ![文字到 Powerpoint 應用程式](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vh01hh3l29qtztri4180.png) 您可以閱讀本文,使用`Next.js` 、 `OpenAI`和`CopilotKit`建立 Text to Powerpoint 應用程式。 這是一個簡單但非常強大的概念,本文也清楚地說明如何在任何幻燈中加入背景圖像。 您可以檢查[GitHub 儲存庫](https://github.com/TheGreatBonnie/aipoweredpresentation)。 ### ✅ [StudyPal:您的人工智慧驅動的個人化學習伴侶](https://dev.to/rajesh-adk-137/studypal-your-ai-powered-personalized-learning-companion-59d)。 ![學習夥伴](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qhau3p28cylr25lae5r4.png) 您可以從精選清單中選擇您想要的主題,為個人化的學習旅程奠定基礎。 您需要提供有關您的教育背景的詳細訊息,以便 StudyPal 能夠根據他們當前的知識水平定製材料和練習。 `Additional Details`部分可讓學生指定重點領域,確保內容與其學習目標一致。 您可以閱讀本文,使用`React` 、 `Node`和`CopilotKit`來建立這個很棒的用例。 您可以觀看該應用程式的[演示](https://github-production-user-asset-6210df.s3.amazonaws.com/89499267/328419789-a06b11c6-ffbc-44b6-96b0-648d2a38cd7c.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20240512%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240512T083208Z&X-Amz-Expires=300&X-Amz-Signature=f6fe016e65e167e94b8322b70743a7fb02fed91f2c87c5af7459e1fa022faac2&X-Amz-SignedHeaders=host&actor_id=74038190&key_id=0&repo_id=793889064)。 您可以檢查[GitHub 儲存庫](https://github.com/rajesh-adk-137/StudyPal)。 --- 2.什麼是郎鏈? -------- 其餘專案將與 langchain 和 AI 相關(有些使用 python)。最好稍微了解一下這一點。 LangChain 是用於開發由大型語言模型(LLM)支援的應用程式的框架。 ![朗查恩](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fuo9c2ljruv3c54is10.png) ![朗查恩](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btgq9o8y1yhjfnrinqqn.png) 總體而言,LangChain 簡化了 LLM 申請生命週期的每個階段。您可以閱讀[官方文件](https://python.langchain.com/docs/get_started/introduction/)以了解更多內容。 如果您想了解有關 langchain 的更多訊息,我建議您觀看 freeCodeCamp 的[本教程](https://www.youtube.com/watch?v=HSZ_uaif57o)。 {% 嵌入 https://www.youtube.com/watch?v=HSZ\_uaif57o %} --- ### 🎯 使用 Langchain/AI/Python 建立的熱門應用程式。 我們可以使用 langchain 建立很多很多高級應用程式,所以讓我們探索一些脫穎而出的應用程式! ### ✅ [Mac 上的語音助理](https://github.com/chidiwilliams/GPT-Automator)- 您的語音控制 Mac 助理。 ![GPT自動機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdzv06jnr3z33s7qll5k.png) 您的語音控制 Mac 助理。 GPT Automator 可讓您使用語音在 Mac 上執行任務。例如,打開應用程式、尋找餐廳、綜合資訊。太棒了:D 它是在倫敦黑客馬拉松期間建構的。 它有兩個主要部分: A。語音命令:它使用本地執行的 Whisper(Buzz 的一個分支)來產生命令。 b.命令到行動:您向配備了我們編寫的自訂工具的 LangChain 代理程式發出命令。這些工具包括使用 AppleScript 控制電腦的作業系統以及使用 JavaScript 控制活動瀏覽器。最後,就像任何優秀的人工智慧一樣,我們讓代理商使用 AppleScript 說出最終結果「{Result}」(如果您以前沒有使用過,請嘗試在 Mac 終端機中輸入「Hello World!」)。 我們製作了一個自訂工具,讓法學碩士使用 AppleScript 控制電腦。提示符是文件字串: ``` @tool def computer_applescript_action(apple_script): """ Use this when you want to execute a command on the computer. The command should be in AppleScript. Here are some examples of good AppleScript commands: Command: Create a new page in Notion AppleScript: tell application "Notion" activate delay 0.5 tell application "System Events" to keystroke "n" using {{command down}} end tell ... Write the AppleScript for the Command: Command: """ p = subprocess.Popen(['osascript', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate(applescript.encode('utf-8')) if p.returncode != 0: raise Exception(stderr) decoded_text = stdout.decode("utf-8") return decoded_text ``` 如果您想知道它是如何運作的,GPT Automator 使用 OpenAI 的 Whisper 將您的音訊輸入轉換為文字。然後,它使用LangChain Agent 選擇一組操作,包括使用OpenAI 的GPT-3(“text-davinci-003”)從提示符號產生AppleScript(用於桌面自動化)和JavaScript(用於瀏覽器自動化)命令,然後執行產生的腳本。 請記住,這不適用於生產用途。該專案執行從自然語言產生的程式碼,可能容易受到提示注入和類似的攻擊。這項工作是作為概念驗證而進行的。 您可以閱讀[安裝指南](https://github.com/chidiwilliams/GPT-Automator?tab=readme-ov-file#instructions)。 讓我們看看一些提示及其作用: ⚡ 求計算結果。 > 提示:“2 + 2 是什麼?” 它將編寫 AppleScript 開啟計算器並輸入 5 \* 5。 ⚡ 尋找附近的餐廳。 > 提示:“查找我附近的餐廳” 它將打開 Chrome,谷歌搜尋附近的餐廳,解析頁面,然後返回最上面的結果。有時它很厚顏無恥,反而會打開谷歌地圖結果並說「最好的餐廳是谷歌地圖頁面頂部的餐廳」。其他時候,它會打開 Google 上的頂部連結 - 並卡在 Google 可存取性頁面上... 以下是執行時列印到終端的內容: ``` Command: Find a great restaurant near Manchester. > Entering new AgentExecutor chain... I need to search for a restaurant near Manchester. Action: chrome_open_url Action Input: https://www.google.com/search?q=restaurant+near+Manchester Observation: Thought: I need to read the page Action: chrome_read_the_page Action Input: Observation: Accessibility links Skip to main content ... # Shortned for brevity Dishoom Manchester 4.7 (3.3K) · £££ · Indian 32 Bridge St · Near John Rylands Library Closes soon ⋅ 11 pm Stylish eatery for modern Indian fare San Carlo 4.2 (2.8K) · £££ · Italian 42 King St W · Near John Rylands Library Closes soon ⋅ 11 pm Posh, sceney Italian restaurant Turtle Bay Manchester Northern Quarter 4.7 Thought: I now know the final answer Final Answer: The 15 best restaurants in Manchester include El Gato Negro, Albert's Schloss, The Refuge, Hawksmoor, On The Hush, Dishoom, Banyan, Zouk Tea Room & Grill, Edison Bar, MyLahore Manchester, Turtle Bay Manchester Northern Quarter, San Carlo, The Black Friar, Mana, and Tast Cuina Catalana. ``` 我不能保證這些餐廳值得,請自行承擔風險。哈哈! ⚡ 如果您要求 GPT Automator 擦除您的計算機,它會的。 是的,如果您要求的話,它會擦除您的電腦! 我內心的自我尖叫著要這麼做:) 您可以在這裡查看完整的演示! {% 嵌入 https://www.loom.com/share/7bfa82c604f3412fbbb04191ce2ae12f %} 您可以在[Chidi 的部落格](https://chidiwilliams.com/posts/gpt-automator)上閱讀更多內容。 它更像是一個業餘專案,因此他們在 GitHub 上有大約 200 個 star,但它非常酷。 您可以檢查[GitHub 儲存庫](https://github.com/chidiwilliams/GPT-Automator)。 ✅ [Instrukt](https://github.com/blob42/Instrukt) - 終端中整合人工智慧。 ------------------------------------------------------------- ![指示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsk64pf5yuosui91tmz9.png) Instrukt是一個基於終端的AI整合環境。它提供了一個平台,用戶可以: - 建立並指導模組化人工智慧代理。 - 產生問答的文件索引。 - 建立工具並將其附加到任何代理程式。 用自然語言指導它們,並且為了安全起見,在安全容器(目前使用 Docker 實作)中執行它們,以在其專用的沙盒空間中執行任務。 使用`Langchain` 、 `Textual`和`Chroma`建構。 開始使用以下命令。 ``` pip install instrukt[all] ``` ![指示](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r3aza7hnlji7hbi2o0js.gif) 有許多令人興奮的功能,例如: - 基於終端的介面,讓強力鍵盤使用者無需離開鍵盤即可指示 AI 代理。 - 對您的資料建立索引並讓代理程式檢索它以進行問答。您可以使用簡單的 UI 建立和組織索引。 - 索引建立將自動偵測程式語言並相應地優化拆分/分塊策略。 - 在安全的 Docker 容器內執行代理程式以確保安全和隱私。 - 整合的 REPL-Prompt 可實現與代理程式的快速交互,以及用於開發和測試的快速回饋循環。 - 您可以使用自訂命令自動執行重複任務。它還具有內建的提示/聊天歷史記錄。 您可以閱讀有關所有[功能的](https://github.com/blob42/Instrukt?tab=readme-ov-file#features)資訊。 您可以閱讀[安裝指南](https://blob42.github.io/Instrukt/install.html)。 您還可以使用內建的 IPython 控制台來除錯和內省代理,這是一個簡潔的小功能。 ![控制台除錯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qaan8np68e3fk1yueexm.png) Instrukt 已獲得 AGPL 許可證,這意味著任何人都可以將其用於任何目的。 可以肯定地說,Instrukt 是您觸手可及的終端人工智慧指揮官。 這是一個新專案,因此他們在 GitHub 上有大約 200 多顆星,但用例非常好。 您可以檢查[GitHub 儲存庫](https://github.com/blob42/Instrukt)。 ✅ [ChatFiles](https://github.com/guangzhengli/ChatFiles) - 上傳您的檔案並與其對話。 ----------------------------------------------------------------------- ![聊天文件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lhimajsma8ijyzeknmlg.png) 文件聊天機器人 — 多個文件,由 GPT / Embedding 提供支援。你可以上傳任何文件並與之對話,考慮到他們使用了另一個著名的開源專案,UI 非常好。 它在底層使用 Langchain 和[Chatbot-ui](https://github.com/mckaywrigley/chatbot-ui) 。使用 Nextjs、TypeScript、Tailwind 和 Supabase(向量 DB)建構。 如果您想了解該方法和技術架構,那麼就在這裡! ![建築學](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8zbn7h50k6gwxgz6rkaf.png) 此環境僅用於試用,支援最大檔案大小為 10 MB,這是一個缺點,如果您想要更大的大小,則可以[在本機安裝](https://github.com/guangzhengli/ChatFiles?tab=readme-ov-file#how-to-run-locally)。 他們提供了您可以使用的[入門問題](https://github.com/guangzhengli/ChatFiles/blob/main/doc/Example.md)。您可以查看[現場演示](https://chatfile.vectorhub.org/)。 他們在 GitHub 上有 3k star,並且發布了`v0.3`版本。 您可以檢查[GitHub 儲存庫](https://github.com/guangzhengli/ChatFiles)。 ✅ [具有多代理協作的終極人工智慧自動化 - LangGraph + GPT 研究人員](https://blog.langchain.dev/how-to-build-the-ultimate-ai-automation-with-multi-agent-collaboration/)。 ------------------------------------------------------------------------------------------------------------------------------------------------- LangGraph 是一個使用 LLM 建立有狀態、多參與者應用程式的函式庫。此範例使用 Langgraph 自動化對任何給定主題的深入研究過程。 簡而言之,這個範例展示了人工智慧代理團隊如何協同工作,對給定主題進行從規劃到發布的研究。此範例還將利用領先的自主研究代理[GPT Researcher](https://github.com/assafelovic/gpt-researcher) ,我已在過去的一篇文章中介紹過該代理。 研究團隊由七名法學碩士代理人: ⚡ `Chief Editor` - 監督研究過程並管理團隊。這是使用 LangGraph 協調其他代理程式的「主」代理程式。該代理充當主要的 LangGraph 介面。 ⚡ `GPT Researcher` - 專門的自主代理,對給定主題進行深入研究。 ⚡ `Editor` - 負責規劃研究大綱和結構。 ⚡ `Reviewer` - 根據一組標準驗證研究結果的正確性。 ⚡ `Reviser` - 根據審查者的回饋修改研究結果。 ⚡ `Writer` - 負責編譯和撰寫最終報告。 ⚡ `Publisher` - 負責以各種格式發布最終報告。 自動化過程基於以下階段(架構),文章中清楚地顯示了這一點。 - 策劃階段。 - 資料收集和分析。 - 審查和修訂。 - 寫作並提交。 - 出版品. ![建築學](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwpvlf859m9c6v8mttxk.png) 您可以閱讀有關正在發生的事情的[詳細步驟文件](https://github.com/assafelovic/gpt-researcher/tree/master/multi_agents?ref=blog.langchain.dev#steps)。 助手的最終運作將產生 Markdown、PDF 和 Docx 等格式的最終研究報告。 您可以閱讀這篇文章,其中介紹[如何透過多代理協作來建立終極人工智慧自動化](https://blog.langchain.dev/how-to-build-the-ultimate-ai-automation-with-multi-agent-collaboration/),其中 Wix 研發主管 Assaf Elovic 介紹如何使用 LangGraph 與專業代理團隊建立自主研究助理。它具有易於理解的程式碼範例,並清楚地說明正在發生的事情。開發者必讀! 最好的部分是,如果您想更改研究查詢並自訂報告,只需編輯主目錄中的`task.json`檔案。真的很棒:) 它由 GPT 研究人員負責,擁有 10k 顆星,但自從上次提交是在幾天前以來,它經常更新。 您可以檢查[GitHub 儲存庫](https://github.com/assafelovic/gpt-researcher/tree/master/multi_agents)。 ✅[僚機AI](https://github.com/e-johnstonn/wingmanAI) 。 --------------------------------------------------- ![僚機人工智慧](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ortnj43j63gx4riqvl4x.png) WingmanAI 是一款功能強大的工具,可與系統和麥克風音訊的即時轉錄進行互動。 它使用 ChatGPT,讓您與文字記錄即時交互,作為機器人的廣泛記憶體基礎,提供獨特的通訊平台。 當您載入指定人員的文字記錄時,機器人甚至可以回答有關過去對話的問題。 所有精彩功能的詳細介紹: ⚡ 它可以轉錄系統輸出和麥克風輸入音頻,讓您以易於閱讀的格式查看即時轉錄。 ⚡ 機器人以令牌有效的方式維護對話記錄,因為只有當前的文字區塊會傳遞給機器人。 ⚡ 您可以與 ChatGPT 支援的機器人聊天,機器人會即時讀取您的文字記錄。 ⚡ 您可以繼續附加到已儲存的記錄中,隨著時間的推移建立一個龐大的資料庫供機器人從中提取。 ⚡ 它允許您保存成績單以供將來使用。您可以稍後隨時加載它們,並且對機器人進行的任何查詢都將與保存的轉錄本的向量資料庫交叉引用,從而為機器人提供更豐富的上下文。 您可以閱讀[安裝說明](https://github.com/e-johnstonn/wingmanAI?tab=readme-ov-file#installation)。 您只需將 OpenAI API 金鑰放入`keys.env`檔案中並執行`main.py` 。 唯一的缺點是該應用程式目前僅與 Windows 相容。 Windows 用戶現在更高興了:) 您可以觀看[完整的示範影片](https://github.com/e-johnstonn/wingmanAI?tab=readme-ov-file#demo)。由於限制,下面所附的 gif 很短(86 秒中只有 30 秒)。 ![30 秒演示 gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gmosnsbwkkb76q83y46i.gif) 我對這個概念感到非常驚訝,因為我從來沒有想過它可以以這種方式實現。當開發人員用非常簡單的概念創造出一些很酷的東西時,感覺真的很棒:) 它在 GitHub 上有 420 多顆星,並且不再維護。但你可以用它來建造更好的東西。 您可以檢查[GitHub 儲存庫](https://github.com/e-johnstonn/wingmanAI)。 ✅[考試](https://github.com/codeacme17/examor)。 -------------------------------------------- ![前愛](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4fh09yrwhnalr1oxgv4.png) 一款允許您根據知識筆記參加考試的應用程式。它可以讓您專注於您所學和所寫的內容🧠。 它不斷提示您提出問題以複習筆記內容,這對於學生、學者、受訪者和終身學習者非常有用。 專案管理員正在使用 next.js 重構專案,這對於使用`next.js`開發人員來說非常好。 讓我們來詳細分析一下一些很棒的功能: ⚡ 建立筆記時可以上傳相關文件。該應用程式根據這些文件的內容產生一組問題。這些問題將在未來呈現給大家。建立筆記時,您作為使用者還可以選擇要產生的問題類型。 ![問題選擇](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rp5seq1zpotaxej6dj6l.png) ⚡ 收到每日問題後,您可以提供答案。 GPT 將評分、驗證並提供正確答案。透過評估答案和連結文件的正確性來確定分數(0 ~ 10 分)。這個分數會影響隨後的艾賓浩斯評審過程。將會在未來的發布版本中進行最佳化。 ⚡ 角色可以為問題產生和評估提供更多可能性。您可以在設定頁面上設定角色。有關各種角色的更多訊息,建議參閱詳細的[角色手冊指南](https://github.com/codeacme17/examor/blob/main/docs/en-role.md)。 ![角色選擇](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n0zdohzkowcdrdnxjzba.png) ⚡ 練習問題時,可以用不同的方法作答。下圖顯示了單選題的範例。 ![回答問題](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzg8vvuxndhw9v2s1x8c.png) ⚡ 它有一個包含多個[模組](https://github.com/codeacme17/examor?tab=readme-ov-file#-modules)的列表,例如`Examine` 、 `Note` 、 `Notes Management`和`Random Question`使用這些模組您可以在筆記中導入問題,刪除或加入新文件到上傳的筆記中,等等。 我喜歡整個概念,這會引起任何曾經面臨過修改筆記問題的人的注意。 您可以閱讀包含如何正確使用它的詳細指南的[文件](https://github.com/codeacme17/examor/blob/main/README.md)。 它在 GitHub 上有 1k star,目前版本為`v0.4.2` 。 您可以檢查[GitHub 儲存庫](https://github.com/codeacme17/examor)。 ✅[語音GPT](https://github.com/hahahumble/speechgpt) 。 --------------------------------------------------- ![語音GPT](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/on0exhy65owc13tzue0v.png) ![語音GPT](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rrge2nyhowtcdyd3gi5.png) SpeechGPT 是一個 Web 應用程式,可讓您與 ChatGPT 進行對話。 您可以利用此應用程式來提高您的語言技能,或只是透過 ChatGPT 享受聊天的樂趣。 大多數人會說這有什麼獨特之處,但事實確實如此。 讓我們來打破一些很棒的功能: ⚡ 所有資料儲存在本地,隱私性更強。 ⚡ 根據文件,它支援 100 多種語言,但我在現場演示中只能看到對三種語言的支援。 ![語言](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6e7jsrhmvrdlidyvnho.png) ⚡ 包含內建語音辨識以及與 Azure 語音服務的整合。 ![語音辨識](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gr2vsaymy50wtiperprd.png) ⚡ 包含內建語音合成,以及與 Amazon Polly 和 Azure 語音服務的整合。 ![語音合成](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2m3kp9othpa9rbb4it57.png) 請按照[文件中的教學](https://github.com/hahahumble/speechgpt?tab=readme-ov-file#-tutorial)了解如何使用它。 您可以在[speechgpt.app](https://speechgpt.app/)上觀看現場演示。這是一個完美的例子,說明了一些額外的功能如何將您的應用程式提升到一個新的水平! SpeechGPT 在 GitHub 上有 2700 顆星,目前版本為`v0.5.1` 。 您可以檢查[GitHub 儲存庫](https://github.com/hahahumble/speechgpt)。 ✅ [myGPTReader](https://github.com/madawei2699/myGPTReader) - 閱讀並與 AI 機器人聊天。 ---------------------------------------------------------------------------- ![我的GPT閱讀器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/58doii8daomf54te5eca.png) myGPTReader 是 Slack 上的機器人,可以閱讀和總結任何網頁、文件(包括電子書),甚至來自 YouTube 的影片。它可以透過語音與您交流。 一些有價值的功能是: ⚡ 使用 myGPTReader 透過對話快速閱讀和理解任何網頁內容,甚至是影片(目前僅支援帶有字幕的 YouTube 影片)。 ![讀者](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x626mtnvqr5vw43938iw.gif) ⚡ 使用 myGPTReader 快速閱讀任何文件的內容,支援電子書、PDF、DOCX、TXT 和 Markdown。 ![文件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5am7njxco7vhronuirgu.gif) ⚡ 透過與 myGPTReader 語音對話來練習外語,它可以成為您的私人導師,支援中文、英語、德語和日語。 ![嗓音](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/40pzlgtuhcyxgwa1z2gs.gif) ⚡ 內建大量提示模板,使用它們可以更好地與chatGPT對話。 ![問](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ehgn218hwewzeft98xkp.gif) ⚡ myGPTReader 每天發送最新熱點新聞,並自動產生摘要,讓您快速了解今日熱點。 您可以造訪[官方網站](https://www.myreader.io/)。 您可以加入擁有超過 5000 名會員的儲存庫上的 Slack 頻道,免費體驗所有這些功能。 它們在 GitHub 上有 4.4k 顆星,並且像此列表中的其他專案一樣使用 Python 建置。 您可以檢查[GitHub 儲存庫](https://github.com/madawei2699/myGPTReader)。 ✅ [RepoChat](https://github.com/pnkvalavala/repochat) - 支援 GitHub 儲存庫互動的聊天機器人助理。 -------------------------------------------------------------------------------- ![重新聊天](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3gf9bjn2a47f1t43aiju.png) Repochat 是一個互動式聊天機器人專案,旨在使用大型語言模型 (LLM) 參與有關 GitHub 儲存庫的對話。 它允許用戶進行有意義的討論、提出問題並從 GitHub 儲存庫檢索相關資訊。本自述文件提供了在本機電腦上設定和使用 Repochat 的逐步說明。 他們建立了兩個具有不同功能的分支,這對我來說有點新鮮。 ⚡ Repochat 的主要分支被設計為完全在本機上執行。此版本的 Repochat 不依賴外部 API 呼叫,並且可以更好地控制您的資料和處理。如果您正在尋找獨立的解決方案,那麼主分支就是您的最佳選擇。 ⚡ Repochat 的雲端分支主要依賴對外部服務的 API 呼叫來進行模型推理和儲存。它非常適合那些喜歡基於雲端的解決方案並且不想設定本地環境的人。 您可以閱讀[安裝說明](https://github.com/pnkvalavala/repochat?tab=readme-ov-file#installation)。 Repochat 讓您與聊天機器人進行對話。您可以提出問題或提供輸入,聊天機器人將從向量資料庫中檢索相關文件。 然後,它將您的輸入以及檢索到的文件傳送到語言模型以產生回應。 預設情況下,我已將模型設為`codellama-7b-instruct` ,但您可以根據計算機的速度更改它,甚至可以嘗試 13b 量化模型進行回應。 聊天機器人在對話過程中保留記憶以提供上下文相關的回應。 您可以查看[即時網站](https://repochat.streamlit.app/),您可以使用 API 金鑰進行檢查。 你可以觀看這個演示! ![示範](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o7ndxqpwkkww4f5qudiq.gif) 如果您想查看的話,我找到了另一種[選擇](https://github.com/peterw/Chat-with-Github-Repo)。 Repochat 擁有 200 多顆星,並部署在 Streamlit 上。 您可以檢查[GitHub 儲存庫](https://github.com/pnkvalavala/repochat)。 ✅ [NextChat - ChatGPT Next Web](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web) 。 ------------------------------------------------------------------------------------- ![下次聊天](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lnuqjkfcyz8z7kejgbb1.png) 這不是一個典型的副專案,因為程式碼庫足夠大,但值得一看作為靈感。 您只需一鍵即可獲得精心設計的跨平台 ChatGPT Web UI,支援 GPT3、GPT4 和 Gemini Pro(Web / PWA / Linux / Win / MacOS)。 一些很棒的功能是: ⚡ 隱私 首先,所有資料都儲存在瀏覽器本地。 ⚡ 首屏載入速度快(~100kb),支援串流響應。 ⚡ 自動壓縮聊天歷史記錄以支援長時間對話,同時儲存您的代幣。 ⚡ Linux/Windows/MacOS 上的緊湊型用戶端 (~5MB)。 ⚡ 您只需在 Vercel 上一鍵點擊即可在 1 分鐘內免費部署。 ⚡ 與自行部署的法學碩士完全相容。 ⚡ Markdown 支援:LaTex、mermaid、程式碼高亮等。 ![下次聊天](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2uvdfwz1rgy1l2l4pb9p.png) 您可以查看 NextChat 的[現場演示](https://app.nextchat.dev/)和[文件,](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web?tab=readme-ov-file#roadmap)其中包括所有環境變數(主要是 API 金鑰)的清單。 ![下次聊天](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fqykjwgjf35khapdfu20.png) 在本地處理它並不難,他們還提供了 GitHub 操作工作流程,每小時都會自動更新。 NextChat 在 GitHub 上擁有 69k+ 顆星,目前已發布`v2.2`版本。 您可以檢查[GitHub 儲存庫](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web)。 --- 如果您喜歡觀看教程來建立專案,我有一些很好的建議。 🎯 [LangChain GEN AI 教學 – 使用 OpenAI、Google Gemini Pro、LLAMA2 的 6 個端到端專案](https://www.youtube.com/watch?v=x0AnCE9SE4A)– 4 小時。 本教學涵蓋的專案: ✅ LangChain 速成課程 - 打下基礎。 ✅ 使用 Langchain 和 Astradb 與 PDF 聊天。 ✅ 使用 Llama 2 LLM 模型產生部落格。 ✅ 使用 Pinecone VectorDB 的端到端法學碩士課程。 ✅ Google Gemini 專業版示範。 ✅ 多語言發票提取器 LLM 專案。 ✅ 使用 Gemini Pro API 的對話式問答聊天機器人。 {% 嵌入 https://www.youtube.com/watch?v=x0AnCE9SE4A %} 🎯 Streamlit 的 LangChain 速成課程。 本教學涵蓋的專案: ✅ 發票資料提取器。 ✅ 針對自訂資料的基本 QA。 ✅ 總結和有用的鏈類型。 ✅ WordPress 程式碼助理。 ✅ 將語音備忘錄轉換為文字。 你可以找到[速成課程](https://learnlangchain.streamlit.app/)。側邊欄中將有一個關於實踐專案的部分! --- 這麼多很棒的專案:) 但說實話,我見過很多開發人員建立相同的應用程式,您可以獲得無限的靈感。我希望你喜歡這個。 繼續,保存它,並建造每一個,以展示誰是技術老大! 讓我知道哪個專案最讓你驚訝。 祝你有美好的一天!直到下一次。 |如果你喜歡這類東西, 請關注我以了解更多:) | [![用戶名 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/) | |------------|----------| 請關注 Copilotkit 以獲取更多此類內容。 {% 嵌入 https://dev.to/copilotkit %} --- 原文出處:https://dev.to/copilotkit/20-projects-you-can-build-with-ai-today-352k

成為資深前端開發者需要的 37 個心態

我真的很喜歡 @abbeyperini 的[帖子](https://dev.to/abbeyperini/12-tips-from-a-mid-level-developer-29bk),並決定在擔任軟體開發人員**5 年多**後分享我的技巧。 準備好?讓我們深入探討。 1.掌握基礎知識 ======== 建在搖搖欲墜的土地上的房子🏠,稍有問題就會倒塌。 同樣,如果你沒有紮實的基礎: - 你會很難適應 JavaScript 框架 - 你會陷入第一個不熟悉的問題 - 您無法掌握某些問題之間的共同主題 因此,如果你想提升前端開發人員的水平,首先要掌握**HTML** 、 **CSS**和**JavaScript** 。 --- 2. 了解網路的工作原理 ============ 在過去的幾年裡,前端開發變得更加複雜。 使用了許多工具(*捆綁器*、*轉譯器*等) 如果您不了解網路的工作原理(即「唯一」支援的語言是**HTML** (用於結構)、 **CSS** (用於樣式)和**JavaScript** (用於互動)),您將很難理解為什麼需要有這麼多工具可以在線執行您的程式碼。 ![建築模組](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/miha7y379n9wnemtnhdi.gif) --- 3.熟悉資料結構與演算法 ============ 由於程式設計面試,資料結構和演算法經常受到不好的評價🤦‍♀️。 **然而**,了解關鍵因素及其複雜性至關重要。如果沒有這些知識,您將無法編寫複雜的程式或評估程式碼效率。 以下是需要了解的資料結構/演算法的非詳盡列表: **資料結構:***棧*、*佇列*、*雜湊圖*、*集合*、*圖*等。 **演算法:***動態規劃*、*貪心演算法*、*遞迴*等。 --- 4. 透過實踐而不是閱讀/觀看來學習 ================== 教學會欺騙您,讓您感覺自己正在取得進步。 它們讓你相信你正在學習和進步,但你並沒有前進。真正的學習是透過實踐或教學發生的。 所以,多多練習,避免陷入教學地獄🔥。 --- 5.遇到困難時尋求協助 =========== 你不是一個人。 您附近很可能有高級開發人員,您可以向他們尋求協助。 所以,不要浪費時間去兔子洞裡。您的目標是提供價值,如果您浪費時間解決其他人已經解決的問題,您就無法實現這一目標。 ![請求幫忙](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iksbkr0yvd3gqh4x22d5.png) --- 6.以正確的方式尋求協助 ============ 在尋求幫助之前,請確保您已經做了最低限度的事情。 你應該首先: - 在 Google/Stack Overflow/ChatGPT 上搜尋解決方案 - 了解你的目標以及什麼不起作用 - 記錄所有失敗的嘗試 另外,不要針對同一問題重複尋求協助。當您獲得幫助時,請在某處記下,以免忘記。 --- 7. 不要複製/貼上你不理解的程式碼 ================== 由於多種原因,這非常糟糕: - 您最終可能會得到不安全的程式碼,這些程式碼會暴露令牌等敏感資訊。 - 您將無法輕鬆除錯程式碼。 - 你將無法向你的同事解釋它。 這對 ChatGPT 尤其重要,因為它有時只能提供 80% 的準確答案。 ![困惑的表情符號](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfansm0i6qss45kkcz8a.png) --- 8. 不要盲目採納網路上找到的每一個建議 ==================== 我剛開始的時候就犯了這個錯誤。 我發現有人建議說 React 中的記憶化是邪惡的,所以我停止使用它。 令我尷尬的是,我的程式碼在預生產中崩潰了。 所以,別讓我「老」了。 當您在網路上看到建議時,請先問自己以下問題: - 這個建議適用於我嗎? - 提供建議的人是否與我的情況類似? **TLDR** :運用常識🫠。 --- 9. 懷抱良好的意願:人們希望你成功❤️ ==================== 當你是新人時,人們通常會認為人們正在等待發現你的錯誤並解僱你。 至少,這是我的思想對我低聲說的。 但事實恰恰相反。 當一家公司僱用你時,它非常希望你成功。否則,這就是浪費他們在培訓和入職方面投入的時間和資源。 因此,相信你的公司希望你做得很好,並毫不猶豫地向你的同事尋求支持。 --- 10.完成勝於完美 ========= 追求完美往往會導致以下結果: - 拖延 - 浪費時間 - 過於複雜 - ETC。 因此,目標是在推動更多之前交付/驗證 V0。 ![做完比求完美強](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u146x2ia7stie8eyvwpa.png) --- 11. 始終將任務分解為可管理的任務 ================== 感到不知所措的最簡單方法是什麼? 👉 試圖咬得比你能咀嚼的更多。 始終將專案分解為更小的任務。 這會: - 讓你不會感到不知所措 - 讓您的 PR(拉取請求)更容易審核 - 提供進步感 --- 12. 值得信賴,當你需要幫助時會伸出援手 ===================== 剛開始時,您的首要任務是贏得經理的信任。 當他們想到你時,應該安心。 他們應該相信: - 你在簡單的任務上很可靠 - 必要時您會尋求協助 - 有任何問題你都會溝通 您不想因為成為經理必須持續監控的問題而增加他們的工作量🔎。 --- 13.表現出對工作的熱情 ============ 用熱情可以彌補很多不足🤪。 當你是新人時,要充滿渴望和興奮。 只有經驗豐富的開發人員才能承受缺乏熱情的後果。 沒有人願意不斷地督促某人工作。指導已經夠困難的了;必須激勵某人會使事情變得更具挑戰性。 ![熱情](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hmc0s50vm86bam0069nw.png) --- 14. 對學習新事物/工具/方法保持開放態度 ====================== 前端開發不斷發展。 因此,您需要對新技術持開放態度。 不要太拘泥於現有的工具。相反,表現出學習的興趣😋。 --- 15. 掌握你的開發工具🛠️ ============== 想要加快您的開發時間嗎? 掌握你的開發工具: - 您的 IDE(例如 VSCode) - 您的原始碼控制系統(例如 Github) - 您的瀏覽器和檢查器(例如 Chrome 檢查器) - ETC。 ![工具包](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9h6zn8k68yghmb0ecffh.png) --- 16. 專注於創造價值 =========== 不要在真空中編寫程式碼。 您編寫的每段程式碼都應該為以下方面提供價值: - 您的客戶 - 你的公司 - 您的利害關係人 - ETC。 您的報酬與您提供的價值掛鉤,而不是與您編寫的程式碼掛鉤。 因此,優先考慮編寫有目的的有效程式碼🥅。 --- 17. 為你的工作辯護:它不會自己說話 =================== 可能是新開發人員最常見的錯誤之一(特別是如果您來自重視謙虛的文化)。 1. 你做了一些了不起的事。 2. 沒有人知道這件事。 👉 那工作並不重要。 因此,透過寫作、演示等方式分享您的作品。 ![為你的工作說話](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t55ep1c3phxgypwchbfh.png) --- 18. 喜歡寫愚蠢的程式碼而不是聰明的程式碼 ====================== 程式碼被閱讀的次數遠多於寫的次數📝。 因此,不要編寫只有您才能理解的聰明程式碼。 **可讀性>效能>聰明。** 您希望您的同事能夠有效率地處理您的程式碼,並在必要時為您提供協助等。 --- 19.你的經理是你最好的盟友 ============== 除非你特別不幸,否則你的經理會支持你的成長📈。 他們通常希望你能夠蓬勃發展,為團隊做出貢獻,並留在公司,而不是在其他地方尋找機會。 因此,請務必招募他們來實現您的目標。 分享你的勝利、挫折(以積極的方式)和挫折,而不是獨自奮鬥。 --- 20.讓你的經理的生活更輕鬆 ============== 這個很簡單,但常被忽略。 您的經理可能有您可以協助解決的問題: - 他們可能需要加入文件但缺乏時間 - 他們的工作量可能龐大,需要支持 - 和更多 這可能是贏得經理支持(升遷、加薪等)的最簡單方法。他們已經意識到這些任務並且可以直接看到它們的影響(至少對他們來說)。 ![最佳老闆杯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yz4tz3h7o12oh4x4f0lg.png) --- 21.了解任務背後的大局 ============ 不要成為程式碼猴子🐒。 剛開始時它可能會對您很有幫助。 但要達到下一個級別,您需要了解任務背後的背景: - 為什麼它們有價值 - 為什麼你被分配給他們 - 它們如何適應公司的整體策略 這種理解對於您的職業生涯更上一層樓至關重要。 --- 22. 為團隊做出貢獻(文件、技術講座、演示等) ======================== 這不僅對公司有利,對您也有利。 透過進行演示、共享文件等,您可以展示您的技能並提高團隊的生產力。 始終致力於盡可能提升團隊的表現:這是令人愉快且有益的😊。 ![貢獻](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbmz4r1ucrrqe84mpq6f.png) --- 23. 成為特定領域的“掌門人” ================ 如果我必須提供一個建議,那就是這個。 在職業生涯的初期,探索各個領域是可以的。 但是,要晉升到中/高級級別,請專注於培養某一領域的專業知識。這對於促銷來說比多個領域的平均水平更具吸引力。 因此,我們的目標是培養[T 型](https://www.forbes.com/sites/lisabodell/2020/08/28/futurethink-forecasts-t-shaped-teams-are-the-future-of-work/)技能:在某一領域擁有廣泛的知識和深厚的專業知識。 --- 24. 培養你的溝通技巧 ============ 不幸的是,這是必須的。 溝通對於開發人員來說至關重要。我們經常需要做以下事情: - RFC(徵求意見) - 示範 - 演講 - ETC。 因此,請確保您具有基本的溝通能力。 --- 25. 當你遇到問題時休息一下 =============== 當你深陷一個問題時,很難停下來。 即使已經過去了 5 年多,我仍然在掙扎🥹。 然而,休息後我總是會產生更新鮮的想法。 所以,如果你已經被困太久了,那就離開吧。 ![休息](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96yk7dr61s2sc7rflive.png) --- 26. 發揮你的優勢,而不是劣勢 ================ 不要再浪費時間試圖修復明顯的弱點。 如果您持續花費超過 1 小時才能完成同您級別的其他人在不到 5 分鐘內完成的任務,請避開該任務。 投入更多的精力很可能不會讓你在這方面表現出色。 相反,做必要的事情並專注於最大限度地發揮你的優勢。如果某件事對你來說很自然且有價值,那就多做一點吧🚀。 --- 27. 掌控自己的職涯道路 ============= 沒有人會為你規劃你的職涯。 如果沒有計劃,你就會為別人的計劃而努力。 因此,請確保您為自己想要在 1/2/5 年內實現的目標制定計劃 💪。 --- 28. 與其他開發人員一起交流 =============== 您目前是否患有冒名頂替症候群? 如果是這樣,請花時間與其他開發人員交流。 您很快就會意識到您並不孤單。 與其他開發人員聯繫還有其他好處: - 您可以學習新的技巧/技巧 - 你們可以討論共同的經歷 - 你們可以在工作上互相補充 - ETC。 ![朋友們](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9r46ijzzv99jfdjrssa.png) --- 29. 指導年輕開發人員 ============ 這是冒名頂替症候群的最佳治療方法之一。 一旦你開始指導年輕的開發人員: - 你會發現你知道一些事情 - 您將把自己定位為中/高級開發人員 - ETC。 --- 30.讓你解決的問題多樣化 ============= 如果你不斷地解決同樣的問題,你的進步就會趨於穩定。 確保您正在解決不同的問題,以便您可以: - 比較各種方法 - 開發解決問題的工具包 - ETC。 ![雞蛋放在多個籃子裡](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hllqddeurnt0bx03m2md.png) --- 31.尋找導師 ======= 擁有偉大的導師是我職業生涯的亮點。 - 導師了解您的旅程,讓您腳踏實地。 - 他們會指導你避免他們所犯的錯誤。 - ETC。 **如何尋找導師?** 與您互動的更有經驗的開發人員聯繫,提出問題,討論他們的經驗等。 如果您無法聯繫資深開發人員,請與 X 等平台上的個人互動,與他們建立關係,然後聯絡 😉。 --- 32. 致力於 JavaScript 框架並掌握它 ========================= 最好的框架是能夠幫助您最快實現目標的框架。 所以,忽略網路上毫無意義的爭論。 選擇您最熟悉或需要學習的框架。 並掌握它。這就足夠了。 有了紮實的 JavaScript 基礎知識,過渡到另一個框架將會很快。 ![合約](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7p9c7u02uqv5b8fhxew.png) --- 33.不斷思考使用者體驗 ============ 身為前端開發人員,你應該考慮使用者。 即使您有 PM 或設計師,也要確保使用者體驗良好 😌。 - 需要時使用載入狀態 - 在 UI 中傳達進度 - 給用戶回饋 - ETC。 --- 34. 坦然地說“不” =========== 這對我來說是一件艱難的事。 我對每一個專案都感到興奮,並努力拒絕。 但身為開發人員,您經常會收到超出您處理能力的請求。 因此,請優先考慮與您的目標最相符的那些。 --- 35.不斷投資你的技能 =========== 選擇成為前端開發人員,您就致力於從事必須不斷學習的職業。 因此,透過學習新語言、掌握新技術等不斷投資你的技能。 ![技能](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2lptuajtkra0p080nnc.png) --- 36. 當面臨太多工作時,減少功能而不是提高程式碼品質。 ============================ 您的應用程式擁有的功能越多越好,對嗎?正確的? 最初,這似乎是正確的,但附加的功能會導致更多的程式碼。更多的程式碼意味著更多的問題(維護、錯誤等)。 因此,當時間緊迫時,應減少功能而不是犧牲程式碼品質。 --- 37. 努力了解你的合作者(設計師、後端開發人員等) ========================== 始終尊重您的合作者(後端開發人員、設計師、產品經理等)。 應用程式開發是團隊的努力。 團隊成員之間的協同越多,環境就會越快樂、越有效🥰。 ![交朋友](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1vdbfdepvkkxdug91noo.gif) --- 感謝您閱讀這篇文章🙏。 發表評論 📩 分享小貼士。 並且不要忘記加上“💖🦄🔥”。 如果您喜歡這樣的文章,請加入我的**免費時事**通訊**[FrontendJoy](https://frontendjoy.substack.com/)** 。 如果您想要每日提示,請在[X/Twitter](https://twitter.com/_ndeyefatoudiop)上找到我。 --- 原文出處:https://dev.to/_ndeyefatoudiop/37-tips-from-a-senior-frontend-developer-251b

48 小時內更改資料庫 5 次,使我們的發布瀏覽量達到 35,000 次

這個故事的開始方式和它的標題一樣古怪。我於 2021 年開始[整合推理](https://integrated-reasoning.com/),以找出在解決[背包問題](https://en.wikipedia.org/wiki/Knapsack_problem)(例如 9、33 和 65 位元暫存器)時使用[任意精度](https://docs.amd.com/r/en-US/ug1399-vitis-hls/Overview-of-Arbitrary-Precision-Integer-Data-Types)整數會發生什麼。我的想法是,靈活的字長將使解決背包問題的[偽多項式時間演算法](https://en.wikipedia.org/wiki/Pseudo-polynomial_time#Knapsack_problem)更有效。簡而言之,它確實有幫助,但最大的收益來自[管道化](https://www.xilinx.com/developer/articles/task-level-parallelism-and-pipelining-in-hls.html)。 快進到 2024 年 4 月[中旬](https://irx.app)。我們規劃了一個 MVP,從本質上將執行[HiGHS](https://github.com/ERGO-Code/HiGHS)等開源求解器的體驗從命令列轉移到瀏覽器中。賣點是這些過程可能需要數月或更長時間才能完成,並且不必爭論它們將幫助我們的用戶專注於優化而不是執行優化所需的基礎設施。 將日誌從 AWS 即時推送到瀏覽器是我以前從未做過的事情。我認為這與[從 LLM 串流文字](https://vercel.com/docs/recipes/streaming-from-llm)的問題大致相似,這是我以前從未做過的事情,最近已經有了大量的發展。一方面,即時日誌事件對 MVP 來說可能有些過大了。另一方面,即時渲染日誌看起來很漂亮,並且可以幫助我們提供像命令列一樣流暢的使用者體驗。我們就這麼做了。 ![irx.app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f5ncdab8cecwrfidgv5o.png) 我們最初的計劃是使用[Prisma Pulse](https://www.prisma.io/docs/pulse/what-is-pulse)在邊緣函數中訂閱 Postgres 寫入,該邊緣函數使用[Vercel 串流回應](https://vercel.com/docs/functions/streaming)將每一行標準輸出從[HiGHS](https://github.com/ERGO-Code/HiGHS) 、 [CBC](https://github.com/coin-or/Cbc)和[SCIP](https://github.com/scipopt/scip)傳送到瀏覽器。除了複雜性之外,該計劃還存在兩個主要問題。找到一個具有正確的[表複製功能](https://www.prisma.io/docs/pulse/database-setup/general-database-instructions)組合來滿足 Pulse 和我們後端的要求的託管 Postgres 實例並非易事,這導致了本文標題前半部分的荒謬之處。兩天內五次更換 Postgres 提供者所引發的一系列事件仍然令我震驚。 ![螞蟻威爾森推特](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/42o4f7nsoane5mzl3bap.png) 當來自 Supabase 的 Long ( [@beertocode](https://x.com/beertocode) ) 提出挑戰時,骨牌效應開始了。他解釋說,他希望為使用 Supabase 進行建造的新人提供額外的推動力。如果我們在兩週內與 Supabase 一起建立並發布,他們將利用社交媒體上的超級粉絲來使此次發布成為一項重大活動。挑戰被接受了,挑戰確實如此。 在評估資料庫選項時,社群媒體機會通常不被考慮在內。然而,我們的發布目標是收集盡可能多的用戶回饋,因此這是我們不能忽視的因素。我對 Supabase 的產品幾乎一無所知,因此花了一個下午的時間閱讀了他們的所有文件。到那天晚上,我對於如何建立 IRX 有了一個完全不同、更簡單的思維模型。 Supabase 的[匿名登入](https://supabase.com/docs/guides/auth/auth-anonymous)功能與[行級安全性相](https://supabase.com/docs/guides/auth/row-level-security)結合,這意味著人們可以在發布當天使用 IRX,而無需執行註冊程序。我們談論的是零准入門檻,在 2024 年看似永無止境的「建立另一個帳戶並重置密碼」的循環中,我什至認為這是不可能的。 事實證明,匿名登入對我們來說非常有價值,因為它使近 300 人能夠在發布當天嘗試使用 IRX 解決混合整數程式 - 即使他們不知道 IRX 是什麼並且只是玩玩。我們從比我想像的更廣泛的背景中獲得了令人難以置信的反饋。 ![IRX 流量](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h0en2wbnzudxv7wfsbn9.png) 我們的即時日誌流方法的兩個問題中的第二個問題直到我們實現該功能之後才出現。 Prisma Pulse 每個表最多有 20 個同時訂閱。直到資源洩漏瞬間消耗了我們的整個連接配額之前,這個限制並不明顯。如果將並髮用戶數限制在 20 個,則不會帶來良好的啟動效果,而且時間真的很緊迫。 ![IRX 啟動定時器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7banl0soa2fm39kcwqdu.png) 當 Long 在三小時後向我們發推文時,我們仍在除錯串流媒體。幸運的是,到目前為止,我已經閱讀了有關 Supabase 的所有內容,包括他們的[即時事件](https://supabase.com/docs/guides/realtime)[配額表](https://supabase.com/docs/guides/realtime/quotas),該表支援開箱即用的 10,000 個並發用戶端。進行切換很容易,這很大程度上要歸功於 Supabase 的 TypeScript[類型產生](https://supabase.com/docs/reference/cli/supabase-gen-types-typescript)。 除了一些[背壓](https://sdk.vercel.ai/docs/advanced/backpressure)問題之外,我們還設法為在可能不同的現場實例上同時執行的三個求解器提供即時日誌流。 ![IRX基礎設施](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1lgl316idyd9vcprnz8.png) ![IRX 解算器基礎設施](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tv7730xmmhcmn1rqcfgh.png) (IRX 內部基礎架構圖,作者: [@baykovr](https://twitter.com/baykovr) ) 龍說得最好: ![長推特](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1s50siph4hz53iqtpn5r.png) 真正瘋狂的是,我因為 Supabase 整合而註冊了 Resend。他們的創辦人[@zenorocha](https://x.com/zenorocha)在發布前幾天炸毀了[我們的 Twitter](https://twitter.com/IntegrateReason/) ,僅用一條推文就為我們的發布周流量增加了 16,000 次瀏覽。 ![芝諾·羅查在推特上](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/juruto1h7g5m32eum8ho.png) 這是我在發布當天對 IRX 基礎設施的草圖: ![IRX 發布日基礎設施](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a263k49npgp2p22ane1i.png) 我們驚慌地發射了。感謝您對 Supabase 的挑戰! ![Supabase 在 Twitter 上](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5j5fqeqyfolulnf1ctrb.png) --- 原文出處:https://dev.to/supabase/changing-databases-5-times-in-48-hours-boosted-our-launch-to-35000-views-1oc2