🔍 搜尋結果:開源

🔍 搜尋結果:開源

Polyfill 供應鏈攻擊:將惡意軟體嵌入 JavaScript CDN

2024 年 6 月 25 日,Sansec 安全研究和惡意軟體團隊[宣布](https://sansec.io/research/polyfill-supply-chain-attack),一個流行的JavaScript polyfill 專案已被一家被認定為中國公司的外國參與者接管,該專案將惡意程式碼嵌入從其CDN 來源取得的JavaScript 資產中: `cdn.polyfill.io` 。 Sansec 聲稱超過 100,000 個網站因這次 Polyfill 攻擊而受到影響,其中包括 Intuit 等上市公司。 惡意 Polyfill 函式庫發生了什麼事? --- Andrew Betts 是[polyfill Web 服務](https://github.com/polyfillpolyfill/polyfill-service)的原始作者。該專案允許根據使用者代理或其他屬性將 JavaScript 填充庫自動注入到網站中。 [Andrews 的聲明](https://x.com/triblondon/status/1761852117579427975)可以追溯到 2 月份,當時他們警告不要參與`cdn.polyfill.io`官方網站。 據我們所知,npm 上沒有特定的 polyfill 函式庫是該特定惡意行為者註入惡意程式碼活動的一部分。也就是說,跨不同軟體生態系統的函式庫(例如 Magento 專案等內容管理系統)可能包含引入來自`cdn.polyfill.io`的 JavaScript 程式碼的靜態腳本導入的程式碼。特別是,我們檢測到了 CVE-2024-38526,這是 PyPI 註冊表上`pdoc`庫的安全性報告,該註冊表為 Python 專案提供 API 文件。如果使用指令`pdoc --math`產生文件,則將包含來自`polyfill.io` JavaScript 文件的連結。 `pdoc`庫的這項行為已在pdoc版本14.5.1中修復,我們敦促用戶盡快升級。 什麼是 JavaScript 填色? --- JavaScript Polyfill 通常是專門建置的一段程式碼,可在本機不支援它的舊瀏覽器上提供現代功能。從歷史上看,polyfill 對於旨在建立跨不同瀏覽器版本無縫執行的應用程式的 Web 開發人員至關重要。它們充當橋樑,使較舊的瀏覽器能夠執行較新的 JavaScript 功能,從而確保無論瀏覽器的年齡或功能如何,都能提供一致的使用者體驗。 在 Web 開發的早期,瀏覽器以不同的速度發展,導致環境分散,相同的程式碼可能無法在所有平台上統一運作。一般來說,對瀏覽器 API 的支援不會得到同等支援。由於無法控制最終使用者可用的瀏覽器版本,開發人員無法保證在瀏覽器中執行 JavaScript 程式碼時可用的 API 相同。因此,polyfills 透過引入 polyfill 程式庫來解決這個問題,讓開發人員編寫現代 JavaScript 程式碼,而不必擔心相容性問題。例如,像`Array.prototype.includes`和`Promise`這樣的方法在 Internet Explorer 等舊版瀏覽器中不受支援。不過,開發人員可以透過瀏覽器中載入的 polyfill 程式庫來提供這些功能。 JavaScript CDN 在 polyfill 函式庫中的作用 --- 內容交付網路 (CDN) 是一個由全球部署的分散式伺服器組成的系統,可根據使用者的地理位置向使用者交付 Web 內容。在 JavaScript 填充庫的背景下,CDN 透過在全球範圍內有效地託管和服務這些庫而發揮著至關重要的作用。透過利用 CDN,開發人員可以確保將其 Polyfill 快速可靠地交付給用戶,從而最大限度地減少延遲並縮短載入時間。使用 CDN 也有助於開發人員避免捆綁 JavaScript 程式庫。 您可能遇到的 CDN 的一般用例是使用基於雲端的指標和應用程式效能,例如 Google Analytics,它正式建議您將以下程式碼新增至您的網站: ``` { "vars" : { "gtag\_id": "<GA\_MEASUREMENT\_ID>", "config" : { "<GA\_MEASUREMENT\_ID>": { "groups": "default" } } } } ``` 在惡意 Polyfill 接手的情況下, `cdn.polyfill.io`是一個廣泛使用的 CDN,它會根據傳入請求的 HTTP 標頭動態提供 Polyfill。這意味著根據使用者的瀏覽器和版本提供適當的polyfill,確保最佳相容性。 CDN 上託管的 Polyfill 的安全風險 --- 使用 CDN 上託管的 Polyfill 會帶來重大的安全風險,主要是因為在應用程式上下文中可能存在任意 JavaScript 程式碼執行的可能性。此風險通常被報告為給定 Web 應用程式的跨站點腳本 (XSS) 漏洞。 當從 CDN 取得 Polyfill 庫時,應用程式會依賴外部伺服器的完整性和安全性。正如 CDN 來源本身一樣。如果 CDN 或託管庫受到損害,如最近對`cdn.polyfill.io`的攻擊所示,新受到損害的程式碼可以在使用者的瀏覽器中註入並執行。此類惡意程式碼可以執行各種邪惡活動,例如將使用者重新導向到網路釣魚網站、竊取敏感資訊,甚至進一步傳播惡意軟體。就瀏覽器安全性而言,此類 XSS 漏洞是最嚴重的後果。 Snyk 如何偵測 CDN 上易受攻擊的 JavaScript 函式庫? --- 除了偵測專案清單和專案依賴項中的不安全程式碼和易受攻擊的第三方程式庫之外, [Snyk VS Code 擴充功能](https://marketplace.visualstudio.com/items?itemName=snyk-security.snyk-vulnerability-scanner)還支援偵測使用靜態腳本匯入語句匯入的易受攻擊的程式庫。 例如,如果從 CDN 匯入的`lodash`庫使用易受攻擊的版本範圍或已知包含惡意程式碼,Snyk 將附加內聯註釋,以引起開發人員對安全風險的注意。 ![](https://res.cloudinary.com/snyk/image/upload/v1719411274/blog-polyfill-supply-chain-attack.png) 防範 CDN 供應鏈攻擊 --- 最近對 JavaScript polyfill 專案的攻擊凸顯了支援整個 Web 生態系統資源的至關重要性,而 CDN 是其中的重要組成部分。供應鏈安全問題通常圍繞著 PyPI 和 npm 等開源套件註冊中心,但 JavaScript polyfill 攻擊提醒我們,CDN 也是一個令人難以置信的網路建構塊。 以下是您應該考慮的一些最佳實踐,以幫助防範此類攻擊: - 使用受信任的 CDN:僅使用來自信譽良好的提供者的 CDN。例如,Cloudflare 以其強大的安全措施和可靠性而聞名。 - 監控依賴關係:定期審核和監控所有第三方腳本和依賴關係。 - 子資源完整性:子資源完整性 (SRI) 等工具可以幫助確保 CDN 交付的內容不被篡改,並且可以固定到經過審核且已知不存在惡意或其他不良行為的預期版本/雜湊。 - 內容安全策略 (CSP):實作強大的 CSP 以限制可以載入腳本的來源。這可以防止惡意腳本被執行。由於 Polyfill 通常包含在應用程式載入的關鍵路徑中,因此它們以與頁面上任何其他 JavaScript 相同的權限執行,這使得它們成為旨在利用這種信任的攻擊者的主要目標。這種風險凸顯了使用安全且信譽良好的 CDN、實施內容安全策略 (CSP) 等強大的安全措施以及定期審核第三方依賴項以防範此類漏洞的重要性。 - 定期更新:使所有庫和依賴項保持最新。許多攻擊利用了已在後續版本中修補的已知漏洞。 - 替代解決方案:評估您的專案是否仍需要 Polyfill。隨著瀏覽器的現代化,polyfill 提供的許多功能現在都得到了原生支援。高度考慮使用您自己的專案資產來供應依賴項,而不是依賴 CDN 等第三方提供者。 --- 原文出處:https://dev.to/snyk/polyfill-supply-chain-attack-embeds-malware-in-javascript-cdn-assets-55d6

了解 Jamstack:現代 Web 開發架構 🔥

Web 開發環境不斷發展,新的架構和方法不斷湧現,以滿足現代 Web 應用程式日益增長的複雜性和效能需求。 Jamstack 是近年來獲得巨大關注的此類架構之一。 對於 JavaScript、API 和標記,Jamstack 是一種現代 Web 開發架構,強調效能、安全性、可擴充性和卓越的開發人員體驗。 *本文深入探討了 Jamstack 的複雜性、其核心原則、優點以及它與傳統 Web 開發方法的比較。* --- 📌 Jamstack 是什麼? --------------- Jamstack 是一種現代架構,旨在讓 Web 開發更快、更安全、更容易擴展。 與傳統的 Web 開發(通常涉及使用伺服器端邏輯來建立整體應用程式)不同,Jamstack 解耦了前端和後端,利用預先渲染的靜態檔案和客戶端 JavaScript 來提供動態內容。 --- 📌 Jamstack 的核心原則 ---------------- 1- **JavaScript:** Jamstack 利用 JavaScript 來處理客戶端的動態功能。這可以包括 React、Vue 或 Angular 等框架以及普通 JavaScript。 2- **API:**伺服器端操作被抽象化為透過 HTTPS 存取的可重複使用 API。這些服務可以是第三方服務或客製化服務,提供身分驗證、付款或內容管理等功能。 3-**標記:**內容和佈局通常在建置時預先渲染並作為靜態 HTML 檔案。這可以使用 Gatsby、Next.js 或 Hugo 等靜態站點產生器 (SSG) 來實現。 --- 📌 Jamstack 的好處 -------------- 1-**效能:**透過從內容交付網路 (CDN) 提供預先渲染的靜態文件,Jamstack 網站可以以驚人的速度載入。這改善了用戶體驗並有助於更好的 SEO 排名。 2-**安全性:**隨著伺服器端邏輯和資料庫轉移到 API,惡意行為者的攻擊媒介就會減少。靜態檔案可降低 SQL 注入等常見漏洞的風險。 3-**可擴展性:**提供靜態檔案意味著輕鬆處理高流量負載。 CDN 可以在全球範圍內快取這些文件,從而確保快速交付,無論用戶位於何處。 4-**開發人員體驗:**將前端與後端解耦,使開發人員能夠獨立處理應用程式的不同部分。這種分離通常會帶來更易於維護和模組化的程式碼庫。 --- 📌 與傳統Web開發的比較 ------------- *傳統的 Web 開發通常涉及前端和後端緊密耦合的整體架構。這種方法可能會帶來一些挑戰:* 1-**效能:**伺服器渲染的頁面要求伺服器針對每個請求產生 HTML,這可能會導致延遲,尤其是在高流量的情況下。 2-**安全性:**更大的攻擊面以及對伺服器和資料庫的更直接存取會增加漏洞風險。 3-**可擴展性:**擴展單體應用程式可能很複雜且佔用資源,通常需要額外的伺服器基礎架構。 4-**開發人員工作流程:**緊密耦合會減慢開發週期,因為系統一個部分的變更可能會影響另一部分,從而需要前端和後端團隊之間的協調。 --- 📌 Jamstack 生態系統中的熱門工具和技術 ------------------------ 1-**靜態網站產生器 (SSG):** `Gatsby` 、 `Next.js` 、 `Nuxt.js`和`Hugo`等工具在建置時預先渲染內容,建立可直接從 CDN 提供服務的靜態`HTML`檔案。 2- **Headless CMS:** `Contentful` 、 `Sanity` 、 `Strapi`和`Netlify CMS`等內容管理系統提供 API 來管理和交付內容,將內容管理與前端呈現解耦。 3- **CDN:** `Netlify` 、 `Vercel`和`Cloudflare`等內容交付網路在全球分發靜態文件,確保快速交付和高可用性。 4-**無伺服器函數:** `AWS Lambda` 、 `Netlify Functions`和`Vercel Functions`等平台可讓開發人員按需執行伺服器端程式碼,而無需管理伺服器基礎架構。 --- 📌 建置 Jamstack 應用程式 ------------------ *建立 Jamstack 應用程式通常涉及以下步驟:* 1-**選擇 SSG:**根據您的專案要求選擇靜態網站產生器。例如,Gatsby 非常適合基於 React 的專案,而 Hugo 則以其速度而聞名。 2-**設定無頭 CMS:**整合無頭 CMS 來管理您的內容。這可能涉及設定 Contentful 或使用 Strapi 等開源解決方案。 3-**建立 API 整合:**利用 API 處理動態功能,例如從第三方服務取得資料或與無伺服器函數整合以實作自訂邏輯。 4-**部署到 CDN:**將靜態站點部署到 CDN 以進行全球分發。 Netlify 和 Vercel 提供具有持續整合和持續部署 (CI/CD) 功能的簡化部署流程。 --- --- 結論✅ --- Jamstack 代表了 Web 開發的範式轉變,透過解耦架構和預渲染靜態內容強調效能、安全性和可擴展性。 透過利用現代工具和技術,開發人員可以建立快速、安全且可擴展的 Web 應用程式,從而提供卓越的使用者體驗。 隨著網路的不斷發展,採用 Jamstack 原則可以幫助開發團隊滿足未來的需求,提供在競爭激烈的數位環境中脫穎而出的尖端解決方案。 --- ***快樂編碼!*** 🔥 **[LinkedIn](https://www.linkedin.com/in/dev-alisamir)** 、 **[X (Twitter)](https://twitter.com/dev_alisamir)** 、 **[Telegram](https://t.me/the_developer_guide)** 、 **[YouTube](https://www.youtube.com/@DevGuideAcademy)** 、 **[Discord](https://discord.gg/s37uutmxT2)** 、 **[Facebook](https://www.facebook.com/alisamir.dev)** 、 **[Instagram](https://www.instagram.com/alisamir.dev)** --- 原文出處:https://dev.to/alisamirali/understanding-jamstack-a-modern-web-development-architecture-4i9c

開發人員的綜合 React.js 備忘單

React.js 已成為現代 Web 開發的基石,用於建立動態和高效能 Web 應用程式。這份全面的備忘單將涵蓋您掌握 React.js 所需了解的所有內容,包括實際範例、程式碼片段以及所有功能的詳細說明。目標是提供可供您隨時參考的深入指南。 ### 目錄 1. 反應簡介 2. 開始使用 React - 設定環境 - 建立一個新的 React 應用程式 3. 反應元件 - 功能元件 - 類別元件 - 功能元件和類別元件之間的差異 4. JSX - JSX 語法 - 嵌入表達式 - JSX 屬性 5. 狀態和道具 - 了解狀態 - 使用 useState Hook 管理狀態 - 了解道具 - 傳遞道具 - 道具類型和預設道具 6. 元件生命週期 - 類別元件中的生命週期方法 - 使用 useEffect 鉤子 - 使用 useEffect 進行清理 7. 處理事件 - React 中的事件處理 - 綜合事件 - 處理表格 - 事件處理程序最佳實踐 8. 條件渲染 - if-else 語句 - 三元運算符 - 邏輯 &amp;&amp; 運算符 - 內嵌 If 與邏輯 &amp;&amp; 運算符 9. 列表和鍵 - 渲染列表 - 使用按鍵 - 鍵只能在兄弟姊妹中是唯一的 10. 表單和受控元件 ``` - Handling Form Data ``` ``` - Controlled vs Uncontrolled Components ``` ``` - Using Refs for Uncontrolled Components ``` ``` - Form Validation ``` 11. 反應路由器 ``` - Setting Up React Router ``` ``` - Route Parameters ``` ``` - Nested Routes ``` ``` - Redirects and Navigation ``` 12. 上下文API ``` - Creating Context ``` ``` - Consuming Context ``` ``` - Context with Functional Components ``` ``` - Updating Context ``` ``` - Context Best Practices ``` 13. 掛鉤 ``` - Basic Hooks (useState, useEffect) ``` ``` - Additional Hooks (useContext, useReducer) ``` ``` - Custom Hooks ``` ``` - Rules of Hooks ``` 14. 高階元件 (HOC) ``` - Understanding HOCs ``` ``` - Creating HOCs ``` ``` - Using HOCs ``` ``` - HOC Best Practices ``` 15. 誤差邊界 ``` - Implementing Error Boundaries ``` ``` - Catching Errors ``` ``` - Error Boundaries Best Practices ``` 16. 反應性能優化 ``` - Memoization ``` ``` - Code Splitting ``` ``` - Lazy Loading ``` ``` - React Profiler ``` 17. 在 React 中測試 ``` - Unit Testing with Jest ``` ``` - Component Testing with React Testing Library ``` ``` - End-to-End Testing with Cypress ``` ``` - Testing Best Practices ``` --- ### 1.React簡介 React.js 通常簡稱為 React,是一個開源 JavaScript 函式庫,用於建立使用者介面,特別是對於需要快速互動式使用者體驗的單頁應用程式。 React 由 Facebook 開發,允許開發人員建立大型 Web 應用程式,這些應用程式可以有效地更新和渲染以回應資料變更。 React 的核心概念是元件,它是一個獨立的模組,可以呈現一些輸出。元件可以獨立嵌套、管理和處理,使開發過程高效且可維護。 ### 2. React 入門 #### 設定環境 在開始使用React之前,您需要設定開發環境。就是這樣: 1. **安裝 Node.js 和 npm** :React 依賴 Node.js 和 npm(節點套件管理器)來管理相依性。 - 從[官方網站](https://nodejs.org/)下載並安裝 Node.js。 - 透過執行以下命令驗證安裝: ``` node -v npm -v ``` 2. **安裝 Create React App** :Create React App 是學習 React 的舒適環境,也是在 React 中啟動新的單頁應用程式的好方法。 ``` npm install -g create-react-app ``` #### 建立一個新的 React 應用程式 一旦環境設定完畢,您就可以建立一個新的 React 應用程式。 1. **建立一個新專案**: ``` npx create-react-app my-app cd my-app npm start ``` 此命令建立一個具有指定名稱( `my-app` )的新目錄,設定一個新的 React 專案,並啟動開發伺服器。您可以開啟瀏覽器並造訪`http://localhost:3000`來查看新的 React 應用程式。 ### 3. 反應元件 元件是任何 React 應用程式的建置塊。它們讓您可以將 UI 分成獨立的、可重複使用的部分。 #### 功能元件 函數式元件是接受 props 作為參數並傳回 React 元素的 JavaScript 函數。它們比類別元件更簡單、更容易編寫。 ``` import React from 'react'; const Welcome = ({ name }) => { return <h1>Welcome, {name}!</h1>; }; export default Welcome; ``` #### 類別元件 類別元件是擴展`React.Component`的 ES6 類,並具有傳回 React 元素的 render 方法。 ``` import React, { Component } from 'react'; class Welcome extends Component { render() { return <h1>Welcome, {this.props.name}!</h1>; } } export default Welcome; ``` #### 功能元件和類別元件之間的差異 - **狀態管理**:功能元件使用鉤子( `useState` 、 `useEffect`等)進行狀態管理,而類別元件則使用`this.state`和生命週期方法。 - **生命週期方法**:類別元件具有生命週期方法,例如`componentDidMount` 、 `componentDidUpdate`和`componentWillUnmount` 。功能元件使用`useEffect`鉤子來處理副作用。 - **簡單性**:函數式元件更簡單、更簡潔,使它們更易於閱讀和維護。 ### 4.JSX JSX 是一種語法擴展,可讓您直接在 JavaScript 中編寫 HTML。它產生 React“元素”。 #### JSX 語法 JSX 看起來像 HTML,但被轉換為 JavaScript。 ``` const element = <h1>Hello, world!</h1>; ``` #### 嵌入表達式 您可以透過將任何 JavaScript 表達式括在大括號中來將其嵌入到 JSX 中。 ``` const name = 'John'; const element = <h1>Hello, {name}!</h1>; ``` #### JSX 屬性 JSX 允許您使用類似 HTML 的語法的屬性。 ``` const element = <img src={user.avatarUrl} alt={user.name} />; ``` ### 5. 狀態和道具 #### 了解狀態 State 是一個內建物件,用來儲存屬於元件的屬性值。當狀態物件發生變化時,元件會重新渲染。 #### 使用 useState Hook 管理狀態 `useState`鉤子用於向功能元件加入狀態。 ``` import React, { useState } from 'react'; const Counter = () => { const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }; export default Counter; ``` #### 了解道具 Props 是傳遞給 React 元件的參數。 Props 透過 HTML 屬性傳遞給元件。 #### 傳遞道具 道具是唯讀且不可變的。 ``` const Greeting = (props) => { return <h1>Hello, {props.name}!</h1>; }; const App = () => { return <Greeting name="Alice" />; }; ``` #### 道具類型和預設道具 PropTypes 可讓您定義元件應接收的 props 類型。可以定義預設 props 以確保 prop 在未指定的情況下具有值。 ``` import React from 'react'; import PropTypes from 'prop-types'; const Greeting = ({ name }) => { return <h1>Hello, {name}!</h1>; }; Greeting.propTypes = { name: PropTypes.string.isRequired, }; Greeting.defaultProps = { name: 'Guest', }; export default Greeting; ``` ### 6. 元件生命週期 #### 類別元件中的生命週期方法 生命週期方法是類別元件中的特殊方法,它們在元件生命週期的特定點執行。 - **componentDidMount** :在元件渲染後執行。 - **componentDidUpdate** :在元件的更新刷新到 DOM 後執行。 - **componentWillUnmount** :在元件從 DOM 中刪除之前執行。 ``` class MyComponent extends React.Component { componentDidMount() { // Runs after component is mounted } componentDidUpdate(prevProps, prevState) { // Runs after component updates } componentWillUnmount() { // Runs before component is unmounted } render() { return <div>My Component</div>; } } ``` #### 使用 useEffect 鉤子 `useEffect`掛鉤結合了`componentDidMount` 、 `componentDidUpdate`和`componentWillUnmount`的功能。 ``` import React, { useState, useEffect } from 'react'; const MyComponent = () => { const [count, setCount] = useState(0); useEffect(() => { // Runs on mount and update document.title = `You clicked ${count} times`; // Cleanup function (runs on unmount) return () => { console.log('Cleanup'); }; }, [count]); // Dependency array return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }; export default MyComponent; ``` ### 7. 處理事件 #### React 中的事件處理 React 事件使用駝峰式命名,而不是小寫。使用 JSX,您可以傳遞一個函數作為事件處理程序,而不是一個字串。 ``` const handleClick = () => { console.log('Button clicked'); }; const MyComponent = () => { return <button onClick={handleClick}>Click me</button>; }; ``` #### 綜合事件 React 的事件系統稱為綜合事件。它是瀏覽器本機事件系統的跨瀏覽器包裝器。 #### 處理表格 在 React 中處理表單涉及控制輸入元素和管理狀態。 ``` import React, { useState } from 'react'; const MyForm = () => { const [value, setValue] = useState(''); const handleChange = (event) => { setValue(event.target.value); }; const handleSubmit = (event) => { event.preventDefault(); alert('A name was submitted: ' + value); }; return ( <form onSubmit={handleSubmit}> <label> Name: <input type="text" value={value} onChange={handleChange} /> </label> <input type="submit" value="Submit" /> </form> ); }; export default MyForm; ``` #### 事件處理程序最佳實踐 - **避免內聯事件處理程序**:在 JSX 外部定義事件處理程序,以獲得更好的可讀性和效能。 - **使用箭頭函數**:使用箭頭函數可以避免`this`綁定出現問題。 - **去抖昂貴的操作**:去抖昂貴的操作(如 API 呼叫)以避免效能問題。 ### 8. 條件渲染 #### if-else 語句 您可以在`render`方法中使用 JavaScript if-else 語句。 ``` const MyComponent = ({ isLoggedIn }) => { if (isLoggedIn) { return <h1>Welcome back!</h1>; } else { return <h1>Please sign in.</h1>; } }; ``` #### 三元運算符 三元運算子是執行條件渲染的簡潔方法。 ``` const MyComponent = ({ isLoggedIn }) => { return ( <div> {isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign in.</h1>} </div> ); }; ``` #### 邏輯 &amp;&amp; 運算符 您可以使用邏輯 &amp;&amp; 運算子有條件地包含元素。 ``` const MyComponent = ({ isLoggedIn }) => { return ( <div> {isLoggedIn && <h1>Welcome back!</h1>} </div> ); }; ``` #### 內嵌 If 與邏輯 &amp;&amp; 運算符 帶有邏輯 &amp;&amp; 運算子的內聯 if 允許您有條件地在輸出中包含元素。 ``` const Mailbox = ({ unreadMessages }) => { return ( <div> <h1>Hello!</h1> {unreadMessages.length > 0 && <h2> You have {unreadMessages.length} unread messages. </h2> } </div> ); }; ``` ### 9. 列表和鍵 #### 渲染列表 您可以建立元素集合並使用大括號`{}`將它們包含在 JSX 中。 ``` const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li key={number.toString()}> {number} </li> ); const NumberList = () => { return ( <ul>{listItems}</ul> ); }; ``` #### 使用按鍵 鍵可協助 React 辨識哪些專案已變更、新增或刪除。應為陣列內的元素提供鍵,以便為元素提供穩定的標識。 ``` const NumberList = (props) => { const numbers = props.numbers; const listItems = numbers.map((number) => <li key={number.toString()}> {number} </li> ); return ( <ul>{listItems}</ul> ); }; ``` #### 鍵只能在兄弟姊妹中是唯一的 陣列中使用的鍵在其兄弟陣列中應該是唯一的。 ``` function Blog(props) { const sidebar = ( <ul> {props.posts.map((post) => <li key={post.id}> {post.title} </li> )} </ul> ); const content = props.posts.map((post) => <div key={post.id}> <h3>{post.title}</h3> <p>{post.content}</p> </div> ); return ( <div> {sidebar} <hr /> {content} </div> ); } ``` ### 10. 表格和受控元件 #### 處理表單資料 在 React 中處理表單資料涉及管理表單欄位的狀態。 ``` import React, { useState } from 'react'; const MyForm = () => { const [value, setValue] = useState(''); const handleChange = (event) => { setValue(event.target.value); }; const handleSubmit = (event) => { event.preventDefault(); alert('A name was submitted: ' + value); }; return ( <form onSubmit={handleSubmit}> <label> Name: <input type="text" value={value} onChange={handleChange} /> </label> <input type="submit" value="Submit" /> </form> ); }; export default MyForm; ``` #### 受控元件與非受控元件 受控元件是由 React 狀態控制的元件。不受控制的元件是那些維持其自身內部狀態的元件。 ``` class NameForm extends React.Component { constructor(props) { super(props); this.state = { value: '' }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({ value: event.target.value }); } handleSubmit(event) { alert('A name was submitted: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" value={this.state.value} onChange={this.handleChange} /> </label> <input type="submit" value="Submit" /> </form> ); } } ``` #### 對不受控制的元件使用引用 Refs 提供了一種存取 DOM 節點或在 render 方法中建立的 React 元素的方法。 ``` class NameForm extends React.Component { constructor(props) { super(props); this.input = React.createRef(); this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit(event) { alert('A name was submitted: ' + this.input.current.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" ref={this.input} /> </label> <input type="submit" value="Submit" /> </form> ); } } ``` #### 表單驗證 表單驗證可確保使用者輸入有效。 ``` const MyForm = () => { const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [error, setError] = useState(''); const handleSubmit = (event) => { event.preventDefault(); if (!name || !email) { setError('Name and Email are required'); } else { setError(''); // Submit form } }; return ( <form onSubmit={handleSubmit}> {error && <p>{error}</p>} <label> Name: <input type="text" value={name} onChange={(e) => setName(e.target.value)} /> </label> <label> Email: <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} /> </label> <input type="submit" value="Submit" /> </form> ); }; export default MyForm; ``` ### 11.反應路由器 React Router 是一個用於在 React 應用程式中進行路由的函式庫。它允許您根據 URL 處理不同元件的導航和渲染。 #### 設定 React 路由器 1. **安裝反應路由器**: ``` npm install react-router-dom ``` 2. **設定路線**: ``` import React from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; const Home = () => <h2>Home</h2>; const About = () => <h2>About</h2>; const App = () => { return ( <Router> <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> </Switch> </Router> ); }; export default App; ``` #### 路由參數 您可以使用路由參數從 URL 擷取值。 ``` import React from 'react'; import { BrowserRouter as Router, Route, Switch, useParams } from 'react-router-dom'; const User = () => { const { id } = useParams(); return <h2>User ID: {id}</h2>; }; const App = () => { return ( <Router> <Switch> <Route path="/user/:id" component={User} /> </Switch> </Router> ); }; export default App; ``` #### 嵌套路由 嵌套路由可讓您在父元件內渲染子元件。 ``` import React from 'react'; import { BrowserRouter as Router, Route, Switch, Link, useRouteMatch } from 'react-router-dom'; const Topic = ({ match }) => <h3>Requested Topic ID: {match.params.topicId}</h3>; const Topics = ({ match }) => { let { path, url } = useRouteMatch(); return ( <div> <h2>Topics</h2> <ul> <li> <Link to={`${url}/components`}>Components</Link> </li> <li> <Link to={`${url}/props-v-state`}>Props v. State</Link> </li> </ul> <Switch> <Route exact path={path}> <h3>Please select a topic.</h3> </Route> <Route path={`${path}/:topicId`} component={Topic} /> </Switch> </div> ); }; const App = () => { return ( <Router> <div> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/topics">Topics</Link> </li> </ul> <hr /> <Switch> <Route exact path="/" component={Home} /> <Route path="/topics" component={Topics} /> </Switch> </div> </Router> ); }; export default App; ``` #### 重定向和導航 您可以使用`Redirect`元件以程式設計方式重定向到不同的路由。 ``` import React from 'react'; import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom'; const Home = () => <h2>Home</h2>; const About = () => <h2>About</h2>; const App = () => { return ( <Router> <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> <Redirect from="/old-path" to="/new-path" /> </Switch> </Router> ); }; export default App; ``` ### 12. 上下文API Context API 提供了一種透過元件樹傳遞資料的方法,而無需在每個層級手動向下傳遞 props。 #### 建立上下文 若要建立上下文,請使用`React.createContext` 。 ``` const MyContext = React.createContext(); ``` #### 消費環境 若要使用上下文值,請在功能元件中使用`useContext`掛鉤,或在類別元件中使用`Context.Consumer` 。 ``` const MyComponent = () => { const value = useContext(MyContext); return <div>{value}</div>; }; ``` #### 功能元件的上下文 ``` const MyComponent = () => { return ( <MyContext.Provider value="Hello"> <AnotherComponent /> </MyContext.Provider> ); }; const AnotherComponent = () => { const value = useContext(MyContext); return <div>{value}</div>; }; ``` #### 更新情境 若要更新上下文,請建立一個具有狀態的提供者元件。 ``` const MyProvider = ({ children }) => { const [value, setValue] = useState('Hello'); return ( <MyContext.Provider value={{ value, setValue }}> {children} </MyContext.Provider> ); }; const MyComponent = () => { const { value, setValue } = useContext(MyContext); return ( <div> {value} <button onClick={() => setValue('Updated Value')}>Update</button> </div> ); }; ``` #### 情境最佳實踐 - **避免過度使用上下文**:謹慎使用上下文,並且僅針對全域資料。 - **使用多個上下文**:透過使用多個上下文來分離關注點。 - **記憶上下文值**:使用`useMemo`來避免不必要的重新渲染。 ### 13. 掛鉤 Hooks 是允許您在功能元件中使用狀態和其他 React 功能的函數。 #### 基本 Hooks(useState、useEffect) - **useState** :向功能元件新增狀態。 - **useEffect** :在功能元件中執行副作用。 #### 附加掛鉤(useContext、useReducer) - **useContext** :存取上下文值。 - **useReducer** :管理複雜的狀態邏輯。 ``` const initialState = { count: 0 }; function reducer(state, action) { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <div> Count: {state.count} <button onClick={() => dispatch({ type: 'increment' })}>+</button> <button onClick={() => dispatch({ type: 'decrement' })}>-</button> </div> ); } ``` #### 定制掛鉤 自訂鉤子是封裝邏輯的函數,可以跨元件重複使用。 ``` const useFetch = (url) => { const [data, setData] = useState(null); useEffect(() => { fetch(url) .then((response) => response.json()) .then((data) => setData(data)); }, [url]); return data; }; const MyComponent = () => { const data = useFetch('https://api.example.com/data'); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; }; ``` #### 鉤子規則 - **在頂層呼叫鉤子**:不要在循環、條件或巢狀函數內呼叫鉤子。 - **僅從 React 函數呼叫鉤子**:從功能元件或自訂鉤子呼叫鉤子。 ### 14. 高階元件(HOC) 高階元件 (HOC) 是獲取元件並傳回新元件的函數。 #### 了解 HOC HOC 用於為元件新增附加功能。 ``` const withLogging = (WrappedComponent) => { return (props) => { console.log('Rendering', WrappedComponent.name); return <WrappedComponent {...props} />; }; }; ``` #### 建立 HOC ``` const EnhancedComponent = withLogging(MyComponent); ``` #### 使用 HOC ``` const MyComponent = (props) => { return <div>My Component</div>; }; const EnhancedComponent = withLogging(MyComponent); ``` #### HOC 最佳實踐 - **不要改變原始元件**:傳回一個新元件。 - **使用顯示名稱進行偵錯**:在 HOC 上設定`displayName`以便更好地進行偵錯。 ### 15. 誤差邊界 錯誤邊界是 React 元件,它可以在其子元件樹中的任何位置捕獲 JavaScript 錯誤、記錄這些錯誤並顯示後備 UI。 #### 實施誤差邊界 錯誤邊界會在渲染期間、生命週期方法以及其下方的整個樹的構造函數中捕獲錯誤。 ``` class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { // You can also log the error to an error reporting service console.log(error, errorInfo); } render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; } return this.props.children; } } ``` #### 捕獲錯誤 錯誤邊界捕捉渲染方法和生命週期方法中的錯誤。 ``` const MyComponent = () => { throw new Error('An error occurred'); return <div>My Component</div>; }; const App = () => { return ( <ErrorBoundary> <MyComponent /> </ErrorBoundary> ); }; ``` #### 錯誤邊界最佳實踐 - **使用錯誤邊界捕獲元件中的錯誤**:使用錯誤邊界捕獲並顯示 UI 元件中的錯誤。 - **記錄錯誤以進行偵錯**:將錯誤記錄到外部服務以進行偵錯。 ### 16.React效能優化 #### 記憶化 記憶化有助於避免不必要的重新渲染元件。 ``` import React, { memo } from 'react'; const MyComponent = memo(({ value }) => { return <div>{value}</div>; }); ``` #### 程式碼分割 程式碼分割有助於僅載入必要的程式碼並提高效能。 ``` import React, { Suspense, lazy } from 'react'; const OtherComponent = lazy(() => import('./OtherComponent')); const MyComponent = () => { return ( <Suspense fallback={<div>Loading...</div>}> <OtherComponent /> </Suspense> ); }; ``` #### 延遲載入 延遲載入有助於僅在需要時載入元件。 ``` import React, { Suspense, lazy } from 'react'; const Other Component = lazy(() => import('./OtherComponent')); const MyComponent = () => { return ( <Suspense fallback={<div>Loading...</div>}> <OtherComponent /> </Suspense> ); }; ``` #### useMemo 和 useCallback - **useMemo** :記住昂貴的計算。 - **useCallback** :記憶函數。 ``` const MyComponent = ({ value }) => { const memoizedValue = useMemo(() => { return computeExpensiveValue(value); }, [value]); const memoizedCallback = useCallback(() => { doSomething(value); }, [value]); return ( <div> {memoizedValue} <button onClick={memoizedCallback}>Click me</button> </div> ); }; ``` #### 反應開發者工具 使用 React Developer Tools 來辨識效能瓶頸。 ### 17. 在 React 中測試 #### Jest 和 React 測試函式庫 Jest 和 React 測試庫是測試 React 元件的熱門工具。 #### 編寫測試 - **快照測試**:捕獲渲染的元件並將其與已儲存的快照進行比較。 - **單元測試**:測試各個元件和功能。 - **整合測試**:測試元件和服務之間的整合。 ``` import { render, screen } from '@testing-library/react'; import MyComponent from './MyComponent'; test('renders MyComponent', () => { render(<MyComponent />); const element = screen.getByText(/My Component/i); expect(element).toBeInTheDocument(); }); ``` ### 18.React 最佳實踐 #### 元件結構 - **依功能組織元件**:將相關元件分組在一起。 - **使用描述性名稱**:為元件和道具使用清晰且描述性的名稱。 - **保持元件較小**:將大型元件分解為較小的、可重複使用的元件。 #### 狀態管理 - **Lift state up** :將狀態提升到最近的共同祖先。 - **使用 Context 進行全域狀態**:使用 Context API 進行全域狀態管理。 #### 造型 - **使用 CSS 模組**:將 CSS 模組用於範圍化和模組化樣式。 - **使用樣式元件**:使用樣式元件進行動態樣式設定。 #### 表現 - **避免不必要的重新渲染**:使用記憶和 React 的內建效能最佳化工具。 - **使用程式碼拆分**:拆分程式碼以僅加載必要的元件。 #### 測試 - **編寫全面的測試**:為應用程式的所有關鍵部分編寫測試。 - **使用快照測試**:使用快照測試來擷取意外的變更。 ### 結論 React.js 是一個用於建立現代 Web 應用程式的強大函式庫。透過理解和利用其核心概念,您可以建立高效、可維護和可擴展的應用程式。這份備忘錄是幫助您掌握 React.js 的綜合指南,涵蓋從基本概念到高階主題的所有內容。 --- 原文出處:https://dev.to/raajaryan/comprehensive-reactjs-cheatsheet-for-developers-17e4

您應該了解的 7 個開源專案 - C# 版 ✔️

概述 -- 大家好👋🏼 在本文中,我將介紹七個您應該知道的用 C# 編寫的 OSS 儲存庫,這些有趣的專案吸引了我的注意並且我想分享它們。 讓我們開始吧🤙🏼 --- 1.[QuestPDF](https://www.questpdf.com/) ------------------------------------ QuestPDF 是用於產生 PDF 文件的開源 .NET 函式庫。提供由簡潔且可發現的 C# Fluent API 提供支援的全面佈局引擎。 易於使用,您可以一步一步建立您的 PDF 文件 🙂‍↕️ https://github.com/QuestPDF/QuestPDF 2.[ShareX](https://getsharex.com/) ------------------------------- ShareX 是一款免費的開源軟體,可讓您擷取或記錄螢幕的任何區域,並只需按一下鍵即可共享它。 我每天都會使用這個軟體:太神奇了🧙🏼‍♂️ https://github.com/ShareX/ShareX 3.[OpenRA](https://www.openra.net/) --------------------------------- 你知道*命令與征服:紅色警戒*嗎? 那麼您一定會喜歡這個:OpenRA 是早期 Westwood 遊戲的開源即時策略遊戲引擎。 它可以在 Windows、Linux 和 Mac OS X 上執行。 https://github.com/OpenRA/OpenRA 4.[Uno Platform](https://platform.uno/) --------------------------------- Uno Platform 是一個開源平台,用於快速建立單一程式碼庫本機行動、Web、桌面和嵌入式應用程式。 它允許 C# 和 WinUI XAML 和/或 C# 程式碼在所有目標平台上執行,同時允許您控制每個像素。 太神奇了,快來試試吧🥇 https://github.com/unoplatform/uno 5.QRCoder -------- QRCoder 是一個用 C# 編寫的簡單函式庫,可讓您建立 QR 碼。重要的是要指定它沒有外部相依性並且支援不同版本的.NET(Framework、Core 等) 它以 NuGet 套件的形式提供。 https://github.com/codebude/QRCoder 6. Windows Auto Dark Mode -------------- Windows Auto Dark Mode 是 Microsoft Store 中提供的一款簡單軟體,用於在 Windows 10 和 Windows 11 的深色和淺色主題之間切換。 簡單、乾淨、實用💣 https://github.com/AutoDarkMode/Windows-Auto-Night-Mode 7. [Ryujinx](https://www.ryujinx.org/) ---------------------------------- 最後但並非最不重要的一點是,任天堂遊戲迷的真正瑰寶:Ryujinx 是用 C# 編寫的任天堂 Switch 模擬器。 該模擬器旨在提供出色的準確性和性能、用戶友好的介面和一致的建置✈️ https://github.com/Ryujinx/Ryujinx --- 結論 -- 此列表列出了七個值得檢查的開源專案,無論是使用它們還是做出貢獻🖖 快樂編碼! --- 嗨👋🏻 我叫 Domenico,是一位對 Vue.js 框架充滿熱情的軟體開發人員,我寫了一篇有關它的文章來分享我的知識和經驗。 不要忘記參觀我的 Linktree 來發現我的專案🫰🏻 連結樹:https://linktr.ee/domenicotenace 在 dev.to 上關注我以獲取其他文章👇🏻 https://dev.to/dvalin99 --- 原文出處:https://dev.to/this-is-learning/7-open-source-projects-you-should-know-c-edition-2bmh

比披薩更吸引開發者的 12 個開源工具👋🍕

現在是開源工具時間! 除了大家都知道的前 3 個之外,開源工具還有更多內容。 哎呀,你實際上可能已經知道這個清單中的所有 12 個(在這種情況下:「慢拍」),但我們大多數人都不知道。 ![開發者開源慢拍手](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/87r8u8xpfavjuc4xp96v.gif) 當談到幫助開發人員完成工作的工具時,開源是一個令人信服的論點! 這就是為什麼我們也推出了自己的[開源工具來提高開發人員的生產力。](https://github.com/middlewarehq/middleware) 因此,這裡列出了 12 個開源工具,它們可能成為您的工具包中不可或缺的一部分。 我們走吧! > 注意:我們發現專案中存在一些不一致之處,根據社區的建議重新表述並加入了新專案。 1.Theia ----- 當您正在尋找 VSCode 的[真正開源替代品](https://eclipse-foundation.blog/2020/05/05/eclipse-theia-and-vs-code-differences-explained/)時,請考慮 Theia。 它是一個靈活的 IDE,可在雲端和桌面上執行。它是用 TypeScript 建構的,並附帶許多可供您使用的附加元件。 - **主要特徵**: - 雲端和桌面 IDE 功能 - 可擴展的插件系統:接受 VSCode 插件/擴展 - 多語言支援 - [忒亞網站](https://theia-ide.org/) - [忒亞 Github](https://github.com/eclipse-theia/theia) 2.Postman ---- 我們很多人都知道 Postman。 不不,不是給你的亞馬遜包裹送貨的人。 ![郵差開源](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d2pslqrzp72ztaf3myck.gif) 此 Postman 讓您可以將請求連結在一起、自動執行任務以及與其他人協作,從而更輕鬆地使用 API。 因此,如果您不喜歡 cURL,Postman 可以拯救您。 - **主要特徵**: - API測試和自動化 - 複雜工作流程的請求鏈 - 團隊協作工具 - [郵差網站](https://www.postman.com/) - [郵差Github](https://github.com/postmanlabs/postman-app-support) 3. Hoppscotch ------ Hoppscotch 是一個免費、輕量級、快速且漂亮的 API 請求建立器工具,可以相對快速地建立和測試您的 API。 - **主要特徵**: - HTTP 請求方法(GET、POST、PUT、DELETE、PATCH 等) - 對 GraphQL 的內建支持 - 集合管理與環境變數 - **網站**:[跳房子](https://hoppscotch.io/) - **GitHub** :[跳房子 GitHub](https://github.com/hoppscotch/hoppscotch) 4. Pocketbase ------- Pocketbase 是一個檔案中的開源即時後端,可在 Flutter、Vue、React 和 Angular 應用程式中使用。 想像一下用 Go 編寫的為開發人員提供的簡單的 SQL 資料庫。 - **主要特徵**: - 具有即時訂閱功能的嵌入式資料庫 (SQLite) - 內建文件和使用者管理 - 以及簡單的 REST-ish API - [Pocketbase網站](https://pocketbase.io/) - [Pocketbase Github](https://github.com/pocketbase/pocketbase) 5. cURL ----- 我想沒有一個開發人員不知道 cURL。 cURL 是一個簡單的命令列工具,用於呼叫 API。事實上,大多數作業系統發行版(例如 Linux 和 MacOS)中都預設包含 cURL。 - **主要特徵**: - 支援多種協定(HTTP、FTP等) - 可編寫腳本的命令列工具 - [捲曲網站](https://curl.se/) - [捲曲Github](https://github.com/curl/curl) 6. Waveterm ----- Waveterm 是一款開源 AI 原生終端機。 Waveterm 將命令列與開放網路連結起來,幫助開發人員提高工作效率。 - **主要特徵**: - 跨網路斷開和重新啟動的持久會話 - 可搜尋的上下文命令歷史記錄 - CodeEdit,使用類似 VSCode 的內聯編輯器編輯本機和遠端文件 - AI 與 ChatGPT(或 ChatGPT 相容 API)集成,幫助編寫命令並獲得內聯答案 - [Waveterm 網站](https://www.waveterm.dev/) - [Waveterm Github](https://github.com/wavetermdev/waveterm) 7. Ollama ----- AI 風靡一時,到 2024 年,不與當地 LLM 打交道的開發人員根本就不是開發人員,對嗎? Ollama 致力於在本地試驗大型語言模式。 它就像法學碩士的 Docker Desktop。 ![奧拉馬開源](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8l3mt8lhulrm4iftjjtz.gif) - **主要特徵**: - 法學碩士的本地實驗 - 大語言模型的開發環境 - OpenAI 相容 API - [奧拉馬網站](https://ollama.com/) - [奧拉馬 Github](https://github.com/ollama/ollama) 8.LM-Studio ------- LM-Studio 也類似 Docker Desktop,是 Ollama 的競爭對手。 - **主要特徵**: - 法學碩士的本地實驗 - OpenAI 相容 API - 支援 Windows 電腦 - [LM-Studio 網站](https://lmstudio.ai/) - [LM-Studio Github](https://github.com/lmstudio-ai) 9.VS Code ------ 告訴我您知道 VS Code 是開源的。請告訴我。 VS Code 或多或少是當今大多數開發人員開始使用的第一個程式碼編輯器。除非你在 Linux 上使用 Vim。順便說一句,我使用 Arch。 VSCode 的擴展數量之多難以想。 - **主要特徵**: - 可擴展的程式碼編輯器 - 除錯支援 - 豐富的擴展生態系統 - [VS 程式碼網站](https://code.visualstudio.com/) - [VS 程式碼 Github](https://github.com/microsoft/vscode) 10.Docker Compose ------------ 現在每個人都使用 Docker,對嗎? Docker Compose 可以透過使用簡單的`compose.yaml`檔案更輕鬆地設定多個連接的 Docker 應用程式。 - **主要特徵**: - Docker容器的編排 - 使用 YAML 定義服務 - 多容器應用程式管理 - [Docker 撰寫網站](https://docs.docker.com/compose/) - [Docker 組合 Github](https://github.com/docker/compose) 11.ESLint --------- ESLint 是一款適用於 JavaScript 和 TypeScript 的出色工具,它透過可自訂的 linting 規則和外掛程式強制執行編碼標準並提高程式碼品質。 ESLint 與 Prettier 和其他此類工具結合可以幫助廣大 JavaScript 開發人員。 - **主要特徵**: - 程式碼品質分析 - 可設定的 linting 規則 - JavaScript 和 TypeScript 支持 - [ESLint 網站](https://eslint.org/) - [ESLint Github](https://github.com/eslint/eslint) 12. Oh My Zsh --------- Oh My Zsh 就像您的 Zsh shell 設定的超級升級,它有酷炫的主題和插件,可以讓您的終端體驗更上一層樓。 當然,對於某些人來說,取得合適的 Zsh 資源檔案往往有點困難。 - **主要特徵**: - Zsh設定管理 - 可自訂的主題和插件 - 社區驅動的發展 - [哦我的 Zsh 網站](https://ohmyz.sh/) - [哦我的 Zsh Github](https://github.com/ohmyzsh/ohmyzsh) --- 我錯過了一些重要的事情嗎? 你怎麼認為? https://github.com/middlewarehq/middleware --- 原文出處:https://dev.to/middleware/13-foss-tools-that-developers-would-give-up-pizza-for-4a6g

使用 ToolJet 建立 AI BPMN 圖分析器🛠️

在本教程中,我們將使用 ToolJet 建立一個 BPMN 圖分析器應用程式。該應用程式允許用戶透過以圖像格式上傳來產生 BPMN 流程的詳細說明。我們將使用**ToolJet 的低程式碼應用程式建構器**作為使用者介面及其**查詢建構器**來連接到 Gemini API,以產生對上傳的 BPMN 流程的深入分析。 以下是我們應用程式的快速預覽: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/20b0iaftmp1hpm9bbae0.gif) 先決條件 ---- **Gemini API 金鑰**:Gemini API 是[Google AI Studio](https://aistudio.google.com/app/apikey)提供的進階 AI 服務。它使開發人員能夠將強大的內容生成功能整合到他們的應用程式中。 **ToolJet** (https://github.com/ToolJet/ToolJet):一個開源、低程式碼的商業應用程式建構器。[註冊](https://www.tooljet.com/signup)免費的 ToolJet 雲端帳號或使用 Docker[在本機上執行 ToolJet](https://docs.tooljet.com/docs/setup/try-tooljet/) 。 首先,建立一個名為*BPMN 圖分析器*的新應用程式。 --- 步驟 1: 新增 UI 元素🖼️ ---------------- 應用程式建置流程的第一步是利用 ToolJet 的可自訂預建置元件在幾分鐘內建立 UI。我們將從標題開始。 ### 應用程式標題 1. 對於徽標,在畫布頂部加入一個**Icon**元件並將其命名為`logo` 。 2. 選擇適當的圖示(例如`IconAnalyzeFilled` )並將其顏色設為`#3e63ddff` 。 3. 在圖示元件旁邊新增一個**文字**元件。 4. 將其資料屬性設定為“BPMN 圖分析器”。 5. 使用`#3e63ddff`作為顏色, `24px`作為字體大小,字體粗細為粗體。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1r4qz4lxsqiu65o61fae.png) *我們使用藍色(十六進位程式碼:#3e63ddff)作為主要顏色,相應地設計即將到來的元件。* ### 輸入部分 1. 在左側新增一個**Container**來儲存輸入元素,並將其命名為`inputContainer` 。 2. 在此容器內,新增一個**Text**元件作為標題,並將其命名為`inputLabel` 。 3. 將文字元件的資料屬性設定為“輸入”。 4. 在其下方放置一個**Image**元件來顯示上傳的 BPMN 圖。將其命名為`imagePreview` 。 5. 新增**檔案選擇器**元件並將其命名為`fileUploader` 。 6. 新增一個標記為「生成」的**按鈕**元件。將其命名為`generateButton` 。 7. 新增另一個標有「複製輸出」的**按鈕**,並將其命名為`copyButton` 。 8. 將按鈕放置在文件選擇器旁的適當位置。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jskct4n24vbg07jmv2oz.png) ### 輸出部分 1. 為輸出部分新增另一個**容器**,並將其命名為`outputContainer` 。 2. 在此容器內新增一個**Text**元件作為標題,並將其命名為`outputLabel` 。 3. 將文字元件的資料屬性設定為“輸出”。 4. 為產生的解釋加入另一個**文字**元件。將其命名為`generatedOutput` 。 5. 將資料格式設為 HTML,因為產生的解釋將採用 HTML 格式。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mjvytfj5sfdzsp8g7cdx.png) --- 第 2 步:設定查詢🔗 ----------- UI 準備好後,我們現在可以連接到 Gemini API 並使用查詢格式化映像預覽。 ### 產生圖像預覽查詢 1. 建立一個名為`generateImagePreview`的新**執行JavaScript程式碼**查詢。 2. 在查詢中加入以下程式碼: ``` return `data:image;base64,${components.fileUploader.file[0].base64Data}` ``` 上面的查詢將重構圖像資料並傳回它。傳回的值將用作 URL,以在 Image 元件中將圖像顯示為預覽。 ### 分析圖查詢 1. 建立一個名為`analyseDiagram`的新**REST API**查詢。 2. 將方法設為 POST 並在 URL 屬性下輸入以下 URL: ``` https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent ``` 3. 在**Headers**下,新增標頭並將鍵設為`Content-Type`並將值設為`application/json` 。 4. 建立一個名為`GEMINI_API_KEY`的新工作區常數,並在其中新增您的 Gemini API 金鑰。 5. 在**「Parameters」**下,新增一行,其中鍵為`key` ,值為`{{constants.GEMINI_API_KEY}}` 。 6. 使用以下程式碼配置查詢的 Body 屬性: ``` { "contents": [ { "parts": [ { "text": "Explain in depth the content and overall of the uploaded BPMN (Business Process Model and Notation) diagram in HTML formatting only. Respond with only the explanation, and nothing else. Return the following information, with clear bullet points and headers (under 18 px) for each section: 1. **Title**: The title or main heading of the BPMN diagram. 2. **Description**: A brief description or summary of the BPMN diagram. 3. **Elements**: Explain all the processes identified in the diagram in the correct flow. If there are multiple sequences, explain them individually. 4. **Flows**: Describe the sequence flows, message flows, and associations between elements. 5. **Data Objects**: Identify and describe any data objects present in the diagram. 6. **Swimlanes**: If present, list the swimlanes (e.g., pools, lanes) and their roles or participants. Ensure the returned HTML is well-structured, with appropriate tags for headers, lists, and any other necessary elements for readability and organization." }, { "inline_data": { "mime_type":"image/jpeg", "data": "{{components.fileUploader.file[0].base64Data}}" } } ] } ] } ``` 此 JSON 請求發送上傳的 BPMN 圖圖像進行分析,要求提供其內容的詳細 HTML 解釋,包括標題、描述、元素、流、資料物件和泳道。 --- 第三步:使用事件進行動態互動🔘 --------------- ToolJet 中的事件可讓您根據按鈕點擊或查詢完成等觸發器輕鬆建立動態應用程式互動。 ### 產生按鈕點擊 1. 將新事件新增至**「生成」**按鈕。 2. 將“事件”保留為**“單擊時”** ,選擇**“執行查詢”**作為“操作”,選擇“查詢”作為`analyseDiagram` 。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/juagcv10qmhon1i8i8ac.png) 現在,每次按一下「產生」按鈕時,都會執行`analyseDiagram`查詢並產生輸出。 ### 複製按鈕點擊 1. 在**「複製輸出」**按鈕上新增按**一下**事件,以將產生的輸出複製到剪貼簿。 2. 將操作設定為**「複製到剪貼簿」** ,然後在「文字」屬性下輸入以下程式碼: ``` {{components.generatedOutput.text}} ``` ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqovfgxi4tt882feg4oo.png) 每次我們點擊“複製輸出”按鈕時,上述設定都會從相關元件複製輸出文字。 ### 文件選擇器載入: 1. 在檔案選擇器元件上新增**檔案載入**事件以執行generateImagePreview 查詢。 2. 此配置將確保每次將檔案上傳到檔案選擇器元件時都會執行`generateImagePreview`查詢。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84funu16nihb1wkh9xww.png) 此配置將確保每次將檔案上傳到檔案選擇器元件時都會執行generateImagePreview 查詢。 ### 圖像預覽 1. 在**Image**元件的 URL 屬性下,輸入以下程式碼: ``` {{queries.generateImagePreview.data}} ``` 現在,使用檔案選擇器上傳 BPMN 圖表圖像後,圖像元件將顯示該圖像。 --- 第 4 步:測試 ✅ ---------- 是時候測試所有功能了。 - 使用**檔案選擇器**上傳圖像 - 預覽應該在圖像元件上可見。 - 點選**「產生」按鈕**- 輸出中的「文字」元件應透過 HTML 格式顯示 BPMN 圖的深入解釋。 - 點擊**“複製輸出”按鈕**- 產生的解釋應該被複製,並且您應該收到一條通知,顯示“已複製到剪貼簿!” ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/092pwp4qug1auw560d1q.png) --- 結論 -- 透過遵循本教學課程,您已使用 ToolJet 成功建立了 BPMN 圖分析器。該應用程式允許用戶上傳圖像格式的 BPMN 圖並接收詳細解釋,從而增強他們的工作流程分析能力。您可以根據您的具體要求隨意進一步擴展和自訂應用程式。快樂建設! 要了解和探索有關 ToolJet 的更多訊息,請查看[ToolJet 文件](https://docs.tooljet.com/docs/tooljet-concepts/what-are-components)或聯絡我們並在[Slack](https://tooljet.slack.com/)上發布您的問題。 --- 原文出處:https://dev.to/tooljet/build-an-ai-bpmn-diagram-analyzer-using-tooljet-2b00

建立人工智慧驅動的簡歷和求職信產生器(CopilotKit、LangChain、Tavily 和 Next.js)

**長話短說** -------- 對於有抱負的開發人員來說,建立一個偉大的專案是最好的履歷。 好,今天我們就一舉兩得;我將教您如何建立一個由人工智慧驅動的尖端應用程式,該應用程式將根據您的 LinkedIn、GitHub 和 X 生成您的簡歷和求職信。 這個專案和你隨後的簡歷會讓任何雇主驚嘆不已。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bty1rqdcu4wknb2ws0w4.gif) 我們將介紹如何: - 使用 Next.js、TypeScript 和 Tailwind CSS 建立履歷和求職信產生器 Web 應用。 - 使用 CopilotKit 將 AI 功能整合到履歷和求職信產生器中。 - 使用 Langchain 和 Tavily 抓取您的 LinkedIn、GitHub 或 X 個人檔案內容。 --- CopilotKit:用於建立應用內人工智慧副駕駛的開源框架 ============================== CopilotKit是一個[開源的AI副駕駛平台](https://github.com/CopilotKit/CopilotKit)。我們可以輕鬆地將強大的人工智慧整合到您的 React 應用程式中。 建造: - ChatBot:上下文感知的應用內聊天機器人,可以在應用程式內執行操作 💬 - CopilotTextArea:人工智慧驅動的文字字段,具有上下文感知自動完成和插入功能📝 - 聯合代理:應用程式內人工智慧代理,可以與您的應用程式和使用者互動🤖 ![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%2Fx3us3vc140aun0dvrdof.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%2Fx3us3vc140aun0dvrdof.gif) {% cta https://git.new/devtoarticle1 %} Star CopilotKit ⭐️ {% endcta %} --- 先決條件 ---- 要完全理解本教程,您需要對 React 或 Next.js 有基本的了解。 以下是建立人工智慧驅動的履歷和求職信產生器所需的工具: - [React Markdown](https://github.com/remarkjs/react-markdown) - 一個**React**元件,可以給予一串 Markdown 來安全地渲染到 React 元素。 - [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 airesumecoverlettergenerator ``` 選擇您首選的配置設定。在本教學中,我們將使用 TypeScript 和 Next.js App Router。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhgnfrg24f5v54vons0d.png) 接下來,安裝 React Markdown 和 OpenAI 套件及其相依性。 ``` npm i react-markdown openai ``` 最後,安裝 CopilotKit 軟體套件。這些套件使我們能夠從 React 狀態檢索資料並將 AI copilot 新增至應用程式。 ``` npm install @copilotkit/react-ui @copilotkit/react-core @copilotkit/backend ``` 恭喜!您現在已準備好建立人工智慧驅動的履歷和求職信產生器。 **建立履歷和求職信產生器前端** ----------------- 在本節中,我將引導您完成使用靜態內容建立履歷和求職信產生器前端的過程,以定義生成器的使用者介面。 首先,請在程式碼編輯器中前往`/[root]/src/app`並建立一個名為`components`的資料夾。在 Components 資料夾中,建立一個名為`Resume.tsx`的文件 在`Resume.tsx`檔案中,加入以下程式碼來定義名為**`Resume`**的 React 功能元件。 ``` "use client"; // Import React and necessary hooks from the react library import React from "react"; import { useState } from "react"; // Import the ReactMarkdown component to render markdown content import ReactMarkdown from "react-markdown"; // Import the Link component from Next.js for navigation import Link from "next/link"; function Resume() { // State variables to store the resume and cover letter content const [coverLetter, setCoverLetter] = useState(""); const [resume, setResume] = useState(""); return ( // Main container with flex layout, full width, and minimum height of screen <div className="flex flex-col w-full min-h-screen bg-gray-100 dark:bg-gray-800"> {/* Header section with a fixed height, padding, and border at the bottom */} <header className="flex items-center h-16 px-4 border-b shrink-0 md:px-6 bg-white dark:bg-gray-900"> {/* Link component for navigation with custom styles */} <Link href="#" className="flex items-center gap-2 text-lg font-semibold md:text-base" prefetch={false}> <span className="sr-only text-gray-500">Resume Dashboard</span> <h1>Resume & Cover Letter Generator</h1> </Link> </header> {/* Main content area with padding */} <main className="flex-1 p-4 md:p-8 lg:p-10"> {/* Container for the content with maximum width and centered alignment */} <div className="max-w-4xl mx-auto grid gap-8"> {/* Section for displaying the resume */} <section> <div className="bg-white dark:bg-gray-900 rounded-lg shadow-sm"> <div className="p-6 md:p-8"> <h2 className="text-lg font-bold">Resume</h2> <div className="my-6" /> <div className="grid gap-6"> {/* Conditional rendering of the resume content */} {resume ? ( <ReactMarkdown>{resume}</ReactMarkdown> ) : ( <div>No Resume To Display</div> )} </div> </div> </div> </section> {/* Section for displaying the cover letter */} <section> <div className="bg-white dark:bg-gray-900 rounded-lg shadow-sm"> <div className="p-6 md:p-8"> <h2 className="text-lg font-bold">Cover Letter</h2> <div className="my-6" /> <div className="grid gap-4"> {/* Conditional rendering of the cover letter content */} {coverLetter ? ( <ReactMarkdown>{coverLetter}</ReactMarkdown> ) : ( <div>No Cover Letter To Display</div> )} </div> </div> </div> </section> </div> </main> </div> ); } export default Resume; ``` 接下來,前往`/[root]/src/page.tsx`文件,並新增以下程式碼來導入`Resume`元件並定義名為`Home`的功能元件。 ``` import Resume from "./components/Resume"; export default function Home() { return <Resume />; } ``` 最後,在命令列上執行命令`npm run dev` ,然後導航到 http://localhost:3000/。 現在您應該在瀏覽器上查看履歷和求職信產生器前端,如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7twcr2xhw15s9x9zz88k.png) 恭喜!現在您已準備好將 AI 功能新增至 AI 支援的履歷和求職信產生器。 **使用 CopilotKit 將 AI 功能整合到履歷和求職信產生器** ------------------------------------- 在本節中,您將學習如何將 AI 副駕駛員加入到履歷和求職信產生器,以使用 CopilotKit 產生履歷和求職信。 CopilotKit 提供前端和[後端](https://docs.copilotkit.ai/getting-started/quickstart-backend)套件。它們使您能夠插入 React 狀態並使用 AI 代理在後端處理應用程式資料。 首先,我們將 CopilotKit React 元件加入履歷和求職信產生器前端。 ### **將 CopilotKit 新增至待辦事項清單產生器前端** 在這裡,我將引導您完成將履歷和求職信產生器與 CopilotKit 前端整合的過程,以促進履歷和求職信的產生。 首先,使用下面的程式碼片段導入`/src/app/components/Resume.tsx`檔案頂部的自訂掛鉤`useCopilotReadable`和`useCopilotAction` 。 ``` import { useCopilotAction, useCopilotReadable } from "@copilotkit/react-core"; ``` 在`Resume`函數內的狀態變數下方,加入以下程式碼,該程式碼使用`useCopilotReadable`掛鉤來新增將作為應用程式內聊天機器人的上下文產生的履歷和求職信。該掛鉤使副駕駛可以閱讀簡歷和求職信。 ``` useCopilotReadable({ description: "The user's cover letter.", value: coverLetter, }); useCopilotReadable({ description: "The user's resume.", value: resume, }); ``` 在上面的程式碼下方,新增以下程式碼,程式碼使用`useCopilotAction`掛鉤來設定名為`createCoverLetterAndResume`的操作,該操作將啟用簡歷和求職信的產生。 操作採用兩個參數,稱為`coverLetterMarkdown`和`resumeMarkdown` ,用於產生履歷和求職信。它包含一個處理程序函數,可根據給定的提示產生履歷和求職信。 在處理函數內部, `coverLetter`和`resume`狀態會使用新產生的履歷和求職信 markdown 進行更新,如下所示。 ``` useCopilotAction( { // Define the name of the action name: "createCoverLetterAndResume", // Provide a description for the action description: "Create a cover letter and resume for a job application.", // Define the parameters required for the action parameters: [ { // Name of the first parameter name: "coverLetterMarkdown", // Type of the first parameter type: "string", // Description of the first parameter description: "Markdown text for a cover letter to introduce yourself and briefly summarize your professional background.", // Mark the first parameter as required required: true, }, { // Name of the second parameter name: "resumeMarkdown", // Type of the second parameter type: "string", // Description of the second parameter description: "Markdown text for a resume that displays your professional background and relevant skills.", // Mark the second parameter as required required: true, }, ], // Define the handler function to be executed when the action is called handler: async ({ coverLetterMarkdown, resumeMarkdown }) => { // Update the state with the provided cover letter markdown text setCoverLetter(coverLetterMarkdown); // Update the state with the provided resume markdown text setResume(resumeMarkdown); }, }, // Empty dependency array, indicating this effect does not depend on any props or state [], ); ``` 之後,請前往`/[root]/src/app/page.tsx`檔案並使用下面的程式碼匯入頂部的 CopilotKit 前端套件和樣式。 ``` import { CopilotKit } from "@copilotkit/react-core"; import { CopilotSidebar } from "@copilotkit/react-ui"; import "@copilotkit/react-ui/styles.css"; ``` 然後使用`CopilotKit`包裝`CopilotSidebar`和`Resume`元件,如下所示。 `CopilotKit`元件指定 CopilotKit 後端端點 ( `/api/copilotkit/` ) 的 URL,而`CopilotSidebar`則呈現應用程式內聊天機器人,您可以提示您產生履歷和求職信。 ``` export default function Home() { return ( <CopilotKit runtimeUrl="/api/copilotkit"> <CopilotSidebar instructions={"Help the user create a cover letter and resume"} labels={{ initial: "Welcome to the cover letter app! Add your LinkedIn, X, or GitHub profile link below.", }} defaultOpen={true} clickOutsideToClose={false}> <Resume /> </CopilotSidebar> </CopilotKit> ); } ``` 之後,執行開發伺服器並導航至[http://localhost:3000](http://localhost:3000/) 。您應該會看到應用程式內聊天機器人已整合到履歷和求職信產生器中。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3dbqyfqzhjj0dw8imv7.png) ### **將 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" OPENAI_MODEL=gpt-4-1106-preview ``` 若要取得 ChatGPT API 金鑰,請導覽至 https://platform.openai.com/api-keys。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tblh9suj8dsp6tab3ej0.jpg) 若要取得 Tavilly Search API 金鑰,請導覽至 https://app.tavily.com/home ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9comyk1kt8mibhvhtpq3.jpg) 之後,轉到`/[root]/src/app`並建立一個名為`api`的資料夾。在`api`資料夾中,建立一個名為`copilotkit`的資料夾。 在`copilotkit`資料夾中,建立一個名為`tavily.ts`的檔案並加入以下程式碼。程式碼定義了一個非同步函數**`scrape`** ,它將連結作為輸入,將此連結傳送到 Tavily API,處理 JSON 回應,然後使用 OpenAI 的語言模型以簡單的英文產生回應摘要。 ``` // Import the OpenAI library import OpenAI from "openai"; // Define an asynchronous function named `scrape` that takes a search query string as an argument export async function scrape(query: string) { // Send a POST request to the specified API endpoint with the search query and other parameters const response = await fetch("https://api.tavily.com/search", { method: "POST", // HTTP method headers: { "Content-Type": "application/json", // Specify the request content type as JSON }, body: JSON.stringify({ api_key: process.env.TAVILY_API_KEY, // API key from environment variables query, // The search query passed to the function search_depth: "basic", // Search depth parameter include_answer: true, // Include the answer in the response include_images: false, // Do not include images in the response include_raw_content: false, // Do not include raw content in the response max_results: 20, // Limit the number of results to 20 }), }); // Parse the JSON response from the API const responseJson = await response.json(); // Instantiate the OpenAI class const openai = new OpenAI(); // Use the OpenAI API to create a completion based on the JSON response const completion = await openai.chat.completions.create({ messages: [ { role: "system", // Set the role of the message to system content: `Summarize the following JSON to answer the research query \`"${query}"\`: ${JSON.stringify( responseJson )} in plain English.`, // Provide the JSON response to be summarized }, ], model: process.env.OPENAI_MODEL || "gpt-4", // Specify the OpenAI model, defaulting to GPT-4 if not set in environment variables }); // Return the content of the first message choice from the completion response return completion.choices[0].message.content; } ``` 接下來,在`copilotkit`資料夾中建立一個名為`route.ts`的文件,並加入以下程式碼。程式碼使用 CopilotKit 框架設定抓取操作,以根據給定連結取得和匯總內容。 然後它定義一個呼叫 scrape 函數並傳回結果的操作。如果所需的 API 金鑰可用,它會將此操作新增至 CopilotKit 執行時間,並使用環境變數中指定的 OpenAI 模型回應 POST 請求。 ``` // Import necessary modules and functions import { CopilotRuntime, OpenAIAdapter } from "@copilotkit/backend"; import { Action } from "@copilotkit/shared"; import { scrape } from "./tavily"; // Import the previously defined scrape function // Define a scraping action with its name, description, parameters, and handler function const scrapingAction: Action<any> = { name: "scrapeContent", // Name of the action description: "Call this function to scrape content from a url in a query.", // Description of the action parameters: [ { name: "query", // Name of the parameter type: "string", // Type of the parameter description: "The query for scraping content. 5 characters or longer. Might be multiple words", // Description of the parameter }, ], // Handler function to execute when the action is called handler: async ({ query }) => { console.log("Scraping query: ", query); // Log the query to the console const result = await scrape(query); // Call the scrape function with the query and await the result console.log("Scraping result: ", result); // Log the result to the console return result; // Return the result }, }; // Define an asynchronous POST function to handle POST requests export async function POST(req: Request): Promise<Response> { const actions: Action<any>[] = []; // Initialize an empty array to store actions // Check if the TAVILY_API_KEY environment variable is set if (process.env["TAVILY_API_KEY"]) { actions.push(scrapingAction); // Add the scraping action to the actions array } // Create a new instance of CopilotRuntime with the defined actions const copilotKit = new CopilotRuntime({ actions: actions, }); const openaiModel = process.env["OPENAI_MODEL"]; // Get the OpenAI model from environment variables // Return the response from CopilotKit, using the OpenAIAdapter with the specified model return copilotKit.response(req, new OpenAIAdapter({ model: openaiModel })); } ``` 如何產生履歷和求職信 ---------- 現在轉到您之前整合的應用程式內聊天機器人,加入 LinkedIn、GitHub 或 X 個人資料連結,然後按 Enter 鍵。 在新增連結後,聊天機器人將使用 LangChain 和 Tavily 從連結設定檔中抓取內容。然後它將使用該內容產生履歷和求職信。 產生的簡歷應如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ey6p8xsgxf3poigz2rko.png) 產生的求職信應如下所示。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/39h4te778e6fuahqfv2k.png) 恭喜!您已完成本教學的專案。 結論 -- 現在您可以建立一個出色的人工智慧驅動的簡歷產生器,以磨練您的人工智慧建立技能並簡化您的求職過程! 如果您喜歡這篇文章,請記得按讚並保存它,並讓我知道您接下來希望看到哪些主題。 --- 原文出處:https://dev.to/copilotkit/build-an-ai-powered-resume-cover-letter-generator-copilotkit-langchain-tavily-nextjs-1nkc

使用 WebSockets、React 和 TypeScript 建立即時投票應用程式 🔌⚡️

長話短說 ---- WebSocket 允許您的應用程式具有「即時」功能,其中更新是即時的,因為它們是在開放的雙向通道上傳遞的。 這與 CRUD 應用程式不同,CRUD 應用程式通常使用 HTTP 請求,必須建立連線、傳送請求、接收回應,然後關閉連線。 ![即時的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/805xrpyehxllmtp6x0ez.png) 要在 React 應用程式中使用 WebSockets,您需要一個專用伺服器,例如帶有 NodeJS 的 ExpressJS 應用程式,以維持持久連接。 不幸的是,無伺服器解決方案(例如 NextJS、AWS lambda)本身並不支援 WebSocket。真糟糕。 😞 為什麼不?嗯,無伺服器服務的開啟和關閉取決於請求是否傳入。 幸運的是,我們將討論兩種實作 WebSocket 的好方法: 1. **進階**:使用 React、NodeJS 和 Socket.IO 自行實作和配置 2. **簡單**:透過使用[Wasp](https://wasp-lang.dev)這個全端 React-NodeJS 框架,為您配置 Socket.IO 並將其整合到您的應用程式中。 這些方法允許您建立有趣的東西,例如我們在這裡建立的立即更新的「與朋友投票」應用程式: {% 嵌入 https://www.youtube.com/watch?v=Twy-2P0Co6M %} 您可以[在此處嘗試即時演示應用程式](https://websockets-voting-client.fly.dev/) 如果您只想要應用程式程式碼,可以[在 GitHub 上找到](https://github.com/vincanger/websockets-wasp) 在我們開始之前 ------- 我們正在努力幫助您盡可能輕鬆地建立高效能的網路應用程式 - 包括建立這樣的內容,每週發布一次! 如果您能在 GitHub 上為我們的儲存庫加註星標以支持我們,我們將不勝感激:https://www.github.com/wasp-lang/wasp 🙏 僅供參考, [Wasp = }](https://wasp-lang.dev)是唯一一個開源、完全伺服器化的全端 React/Node 框架,具有內建編譯器和 AI 輔助功能,可讓您超快速地建立應用程式。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1hk4emh8rr8q4j35sxud.gif) {% cta https://www.github.com/wasp-lang/wasp %} 連 Ron 也會在 GitHub 上為 Wasp 加註星標 🤩 {% endcta %} 為什麼選擇 WebSocket? ---------------- 因此,想像一下您在一個聚會上向朋友發送短信,告訴他們要帶什麼食物。 現在,如果您打電話給您的朋友,這樣您就可以不斷地交談,而不是偶爾發送訊息,不是更容易嗎?這幾乎就是 Web 應用程式世界中的 WebSocket。 例如,傳統的 HTTP 請求(例如 CRUD/RESTful)就像那些短信 - 您的應用程式每次需要新資訊時都必須**詢問伺服器**,就像您每次想到食物時都必須向朋友發送簡訊一樣為您的聚會。 但使用 WebSockets,一旦建立連接,它**就會保持開放狀態**以進行持續的雙向通信,因此伺服器可以在新資訊可用時立即向您的應用程式發送新訊息,即使客戶端沒有請求。 這非常適合聊天應用程式、遊戲伺服器等即時應用程式,或當您追蹤股票價格時。例如,Google Docs、Slack、WhatsApp、Uber、Zoom 和 Robinhood 等應用程式都使用 WebSocket 來支援其實時通訊功能。 ![https://media3.giphy.com/media/26u4hHj87jMePiO3u/giphy.gif?cid=7941fdc6hxgjnub1rcs80udcj652956fwmm4qhxsmk6ldxg7&ep=v1_](https://media3.giphy.com/media/26u4hHj87jMePiO3u/giphy.gif?cid=7941fdc6hxgjnub1rcs80udcj652956fwmm4qhxsmk6ldxg7&ep=v1_gifs_search&rid=giphy.gif&ct=g) 因此請記住,當您的應用程式和伺服器有很多主題要討論時,請使用 WebSockets,讓對話自由進行! WebSocket 的工作原理 --------------- 如果您希望應用程式具有即時功能,則並非總是需要 WebSocket。您可以透過使用資源密集型進程來實現類似的功能,例如: 1. 長輪詢,例如執行`setInterval`定期存取伺服器並檢查更新。 2. 單向“伺服器發送事件”,例如保持單向伺服器到客戶端連接開啟以僅接收來自伺服器的新更新。 另一方面,WebSockets 在用戶端和伺服器之間提供雙向(也稱為「全雙工」)通訊通道。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/76wuptbq21qzppy4dtp0.png) 如上圖所示,一旦透過 HTTP「握手」建立連接,伺服器和客戶端就可以在連接最終被任何一方關閉之前立即自由地交換資訊。 儘管引入 WebSocket 確實會因為非同步和事件驅動的元件而增加複雜性,但選擇正確的程式庫和框架可以使事情變得簡單。 在下面的部分中,我們將向您展示在 React-NodeJS 應用程式中實作 WebSocket 的兩種方法: 1. 與您自己的獨立 Node/ExpressJS 伺服器一起自行配置 2. 讓Wasp這個擁有超強能力的全端框架為您輕鬆配置 在 React-NodeJS 應用程式中新增 WebSockets 支持 ------------------------------------ ### 你不應該使用什麼:無伺服器架構 但首先,請注意:儘管無伺服器解決方案對於某些用例來說是一個很好的解決方案,但它**並不是**完成這項工作的正確工具。 這意味著,流行的框架和基礎設施(例如 NextJS 和 AWS Lambda)不支援開箱即用的 WebSocket 整合。 {% 嵌入 https://www.youtube.com/watch?v=e5Cye4pIFeA %} 此類解決方案不是在專用的傳統伺服器上執行,而是利用無伺服器函數(也稱為 lambda 函數),這些函數旨在在收到請求時立即執行並完成任務。關閉」。 這種無伺服器架構對於保持 WebSocket 連線處於活動狀態並不理想,因為我們需要持久的、「始終在線」的連線。 這就是為什麼如果您想建立即時應用程式,您需要一個「伺服器化」架構。儘管有一種解決方法可以在無伺服器架構上取得 WebSocket,[例如使用第三方服務](https://vercel.com/guides/do-vercel-serverless-functions-support-websocket-connections),但這有許多缺點: - **成本:**這些服務以訂閱形式存在,並且隨著應用程式的擴展而變得昂貴 - **有限的客製化:**您使用的是預先建置的解決方案,因此您的控制權較少 - **除錯:**修復錯誤變得更加困難,因為您的應用程式沒有在本地執行 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ldjj1szn6gkk1daj2dqy.png) 💪 ### 將 ExpressJS 與 Socket.IO 結合使用 — 複雜/可自訂的方法 好吧,讓我們從第一個更傳統的方法開始:為您的客戶端建立一個專用伺服器,以與之建立雙向通訊通道。 這種方法更先進,複雜一些,但允許更精細的客製化。**如果您正在尋找一種簡單、更簡單的方法將 WebSockets 引入您的 React/NodeJS 應用程式,我們將在[下面的部分](#implementing-websockets-with-wasp-easierless-config-method)中介紹該方法** &gt; > 👨‍💻**提示**:如果您想一起編碼,可以按照以下說明進行操作。或者,如果您只想查看這個特定的已完成的 React-NodeJS 全端應用程式,請查看[此處的 github 存儲庫](https://github.com/vincanger/websockets-react) &gt; 在此範例中,我們將使用[ExpressJS](https://expressjs.com/)和[Socket.IO](http://Socket.io)庫。儘管還有其他函式庫,Socket.IO 是一個很棒的函式庫,它使得在 NodeJS 中使用 WebSockets 變得[更加容易](https://socket.io/docs/v4/)。 如果您想一起編碼,請先克隆`start`分支: ``` git clone --branch start https://github.com/vincanger/websockets-react.git ``` 您會注意到裡面有兩個資料夾: - 📁 我們的 React 應用程式的`ws-client` - 📁 `ws-server`用於我們的 ExpressJS/NodeJS 伺服器 讓我們進入伺服器資料`cd`並安裝依賴項: ``` cd ws-server && npm install ``` 我們還需要安裝使用打字稿的類型: ``` npm i --save-dev @types/cors ``` 現在,在終端機中使用`npm start`命令執行伺服器。 您應該會看到在控制台上列印出`listening on *:8000` ! 目前,我們的`index.ts`文件如下所示: ``` import cors from 'cors'; import express from 'express'; const app = express(); app.use(cors({ origin: '*' })); const server = require('http').createServer(app); app.get('/', (req, res) => { res.send(`<h1>Hello World</h1>`); }); server.listen(8000, () => { console.log('listening on *:8000'); }); ``` 這裡沒有太多內容,所以讓我們安裝[Socket.IO](http://Socket.IO)套件並開始將 WebSocket 加入到我們的伺服器! 首先,讓我們使用`ctrl + c`終止伺服器,然後執行: ``` npm install socket.io ``` 讓我們繼續用以下程式碼替換`index.ts`檔。我知道程式碼很多,所以我留下了一堆註解來解釋發生了什麼;): ``` import cors from 'cors'; import express from 'express'; import { Server, Socket } from 'socket.io'; type PollState = { question: string; options: { id: number; text: string; description: string; votes: string[]; }[]; }; interface ClientToServerEvents { vote: (optionId: number) => void; askForStateUpdate: () => void; } interface ServerToClientEvents { updateState: (state: PollState) => void; } interface InterServerEvents { } interface SocketData { user: string; } const app = express(); app.use(cors({ origin: 'http://localhost:5173' })); // this is the default port that Vite runs your React app on const server = require('http').createServer(app); // passing these generic type parameters to the `Server` class // ensures data flowing through the server are correctly typed. const io = new Server< ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData >(server, { cors: { origin: 'http://localhost:5173', methods: ['GET', 'POST'], }, }); // this is middleware that Socket.IO uses on initiliazation to add // the authenticated user to the socket instance. Note: we are not // actually adding real auth as this is beyond the scope of the tutorial io.use(addUserToSocketDataIfAuthenticated); // the client will pass an auth "token" (in this simple case, just the username) // to the server on initialize of the Socket.IO client in our React App async function addUserToSocketDataIfAuthenticated(socket: Socket, next: (err?: Error) => void) { const user = socket.handshake.auth.token; if (user) { try { socket.data = { ...socket.data, user: user }; } catch (err) {} } next(); } // the server determines the PollState object, i.e. what users will vote on // this will be sent to the client and displayed on the front-end const poll: PollState = { question: "What are eating for lunch ✨ Let's order", options: [ { id: 1, text: 'Party Pizza Place', description: 'Best pizza in town', votes: [], }, { id: 2, text: 'Best Burger Joint', description: 'Best burger in town', votes: [], }, { id: 3, text: 'Sus Sushi Place', description: 'Best sushi in town', votes: [], }, ], }; io.on('connection', (socket) => { console.log('a user connected', socket.data.user); // the client will send an 'askForStateUpdate' request on mount // to get the initial state of the poll socket.on('askForStateUpdate', () => { console.log('client asked For State Update'); socket.emit('updateState', poll); }); socket.on('vote', (optionId: number) => { // If user has already voted, remove their vote. poll.options.forEach((option) => { option.votes = option.votes.filter((user) => user !== socket.data.user); }); // And then add their vote to the new option. const option = poll.options.find((o) => o.id === optionId); if (!option) { return; } option.votes.push(socket.data.user); // Send the updated PollState back to all clients io.emit('updateState', poll); }); socket.on('disconnect', () => { console.log('user disconnected'); }); }); server.listen(8000, () => { console.log('listening on *:8000'); }); ``` 太好了,使用`npm start`再次啟動伺服器,然後將[Socket.IO](http://Socket.IO)客戶端加入到前端。 `cd`進入`ws-client`目錄並執行 ``` cd ../ws-client && npm install ``` 接下來,使用`npm run dev`啟動開發伺服器,您應該在瀏覽器中看到硬編碼的啟動應用程式: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rnfi9vt819a0w1qfa7p9.png) 您可能已經注意到 poll 與我們伺服器的`PollState`不符。我們需要安裝[Socket.IO](http://Socket.IO)客戶端並進行所有設置,以便開始即時通訊並從伺服器獲取正確的輪詢。 繼續使用`ctrl + c`終止開發伺服器並執行: ``` npm install socket.io-client ``` 現在讓我們建立一個鉤子,在建立連線後初始化並返回 WebSocket 用戶端。為此,請在`./ws-client/src`中建立一個名為`useSocket.ts`新檔案: ``` import { useState, useEffect } from 'react'; import socketIOClient, { Socket } from 'socket.io-client'; export type PollState = { question: string; options: { id: number; text: string; description: string; votes: string[]; }[]; }; interface ServerToClientEvents { updateState: (state: PollState) => void; } interface ClientToServerEvents { vote: (optionId: number) => void; askForStateUpdate: () => void; } export function useSocket({endpoint, token } : { endpoint: string, token: string }) { // initialize the client using the server endpoint, e.g. localhost:8000 // and set the auth "token" (in our case we're simply passing the username // for simplicity -- you would not do this in production!) // also make sure to use the Socket generic types in the reverse order of the server! const socket: Socket<ServerToClientEvents, ClientToServerEvents> = socketIOClient(endpoint, { auth: { token: token } }) const [isConnected, setIsConnected] = useState(false); useEffect(() => { console.log('useSocket useEffect', endpoint, socket) function onConnect() { setIsConnected(true) } function onDisconnect() { setIsConnected(false) } socket.on('connect', onConnect) socket.on('disconnect', onDisconnect) return () => { socket.off('connect', onConnect) socket.off('disconnect', onDisconnect) } }, [token]); // we return the socket client instance and the connection state return { isConnected, socket, }; } ``` 現在讓我們回到`App.tsx`主頁並將其替換為以下程式碼(我再次留下註解來解釋): ``` import { useState, useMemo, useEffect } from 'react'; import { Layout } from './Layout'; import { Button, Card } from 'flowbite-react'; import { useSocket } from './useSocket'; import type { PollState } from './useSocket'; const App = () => { // set the PollState after receiving it from the server const [poll, setPoll] = useState<PollState | null>(null); // since we're not implementing Auth, let's fake it by // creating some random user names when the App mounts const randomUser = useMemo(() => { const randomName = Math.random().toString(36).substring(7); return `User-${randomName}`; }, []); // 🔌⚡️ get the connected socket client from our useSocket hook! const { socket, isConnected } = useSocket({ endpoint: `http://localhost:8000`, token: randomUser }); const totalVotes = useMemo(() => { return poll?.options.reduce((acc, option) => acc + option.votes.length, 0) ?? 0; }, [poll]); // every time we receive an 'updateState' event from the server // e.g. when a user makes a new vote, we set the React's state // with the results of the new PollState socket.on('updateState', (newState: PollState) => { setPoll(newState); }); useEffect(() => { socket.emit('askForStateUpdate'); }, []); function handleVote(optionId: number) { socket.emit('vote', optionId); } return ( <Layout user={randomUser}> <div className='w-full max-w-2xl mx-auto p-8'> <h1 className='text-2xl font-bold'>{poll?.question ?? 'Loading...'}</h1> <h2 className='text-lg italic'>{isConnected ? 'Connected ✅' : 'Disconnected 🛑'}</h2> {poll && <p className='leading-relaxed text-gray-500'>Cast your vote for one of the options.</p>} {poll && ( <div className='mt-4 flex flex-col gap-4'> {poll.options.map((option) => ( <Card key={option.id} className='relative transition-all duration-300 min-h-[130px]'> <div className='z-10'> <div className='mb-2'> <h2 className='text-xl font-semibold'>{option.text}</h2> <p className='text-gray-700'>{option.description}</p> </div> <div className='absolute bottom-5 right-5'> {randomUser && !option.votes.includes(randomUser) ? ( <Button onClick={() => handleVote(option.id)}>Vote</Button> ) : ( <Button disabled>Voted</Button> )} </div> {option.votes.length > 0 && ( <div className='mt-2 flex gap-2 flex-wrap max-w-[75%]'> {option.votes.map((vote) => ( <div key={vote} className='py-1 px-3 bg-gray-100 rounded-lg flex items-center justify-center shadow text-sm' > <div className='w-2 h-2 bg-green-500 rounded-full mr-2'></div> <div className='text-gray-700'>{vote}</div> </div> ))} </div> )} </div> <div className='absolute top-5 right-5 p-2 text-sm font-semibold bg-gray-100 rounded-lg z-10'> {option.votes.length} / {totalVotes} </div> <div className='absolute inset-0 bg-gradient-to-r from-yellow-400 to-orange-500 opacity-75 rounded-lg transition-all duration-300' style={{ width: `${totalVotes > 0 ? (option.votes.length / totalVotes) * 100 : 0}%`, }} ></div> </Card> ))} </div> )} </div> </Layout> ); }; export default App; ``` 現在繼續並使用`npm run dev`啟動客戶端。開啟另一個終端機視窗/選項卡, `cd`進入`ws-server`目錄並執行`npm start` 。 如果我們做得正確,我們應該會看到我們完成的、工作的、即時的應用程式! 🙂 如果您在兩個或三個瀏覽器標籤中打開它,它看起來和工作起來都很棒。一探究竟: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/37wbxygyrxaomyhmueic.gif) 好的! 我們已經在這裡獲得了核心功能,但由於這只是一個演示,因此缺少一些非常重要的部分,導致該應用程式在生產中無法使用。 主要是,每次安裝應用程式時,我們都會建立一個隨機的假用戶。您可以透過重新整理頁面並再次投票來檢查這一點。您會看到投票不斷增加,因為我們每次都會建立一個新的隨機用戶。我們不要這樣! 我們應該為在我們的資料庫中註冊的用戶驗證並保留會話。但另一個問題:我們在這個應用程式中根本沒有資料庫! 您可以開始看到即使只是一個簡單的投票功能,複雜性也是如何增加的 幸運的是,我們的下一個解決方案 Wasp 整合了身份驗證和資料庫管理。更不用說,它還為我們處理了很多 WebSockets 配置。 那麼就讓我們繼續嘗試吧! ### 使用 Wasp 實作 WebSocket — 更簡單/更少的設定方法 由於 Wasp 是一個創新的全端框架,因此它使得建立 React-NodeJS 應用程式變得快速且對開發人員友好。 Wasp 具有許多節省時間的功能,包括透過[Socket.IO](http://socket.io/)提供的 WebSocket 支援、身份驗證、資料庫管理和開箱即用的全端類型安全性。 {% 嵌入 https://twitter.com/WaspLang/status/1673742264873500673?s=20 %} Wasp 可以為您處理所有這些繁重的工作,因為它使用配置文件,您可以將其視為 Wasp 編譯器用來幫助將您的應用程式粘合在一起的一組指令。最後,Wasp 會為您處理一堆樣板程式碼,為您節省大量時間和精力。 要查看它的實際效果,讓我們按照以下步驟使用 Wasp 實作 WebSocket 通訊: &gt; > 😎**提示**如果您想查看完成的應用程式程式碼,您可以[在此處查看 GitHub 儲存庫](https://github.com/vincanger/websockets-wasp) &gt; 1. 透過在終端機中執行以下命令來全域安裝 Wasp: ``` curl -sSL https://get.wasp-lang.dev/installer.sh | sh ``` 如果您想一起編碼,請先克隆範例應用程式的`start`分支: ``` git clone --branch start https://github.com/vincanger/websockets-wasp.git ``` 您會注意到 Wasp 應用程式的結構是分裂的: - 🐝 根目錄下有一個`main.wasp`設定檔 - 📁 `src/client`是 React 檔案的目錄 - 📁 `src/server`是 ExpressJS/NodeJS 函式的目錄 讓我們先快速瀏覽一下`main.wasp`檔案。 ``` app whereDoWeEat { wasp: { version: "^0.13.2" }, title: "where-do-we-eat", client: { rootComponent: import { Layout } from "@src/client/Layout", }, // 🔐 This is how we get Auth in our app. Easy! auth: { userEntity: User, onAuthFailedRedirectTo: "/login", methods: { usernameAndPassword: {} } }, } // 👱 this is the data model for our registered users in our database entity User {=psl id Int @id @default(autoincrement()) psl=} // ... ``` 這樣,Wasp 編譯器就會知道要做什麼並為我們配置這些功能。 讓我們告訴它我們也需要 WebSockets。將`webSocket`定義加入到`main.wasp`檔案中,位於`auth`和`dependencies`之間: ``` app whereDoWeEat { // ... webSocket: { fn: import { webSocketFn } from "@src/server/ws-server", }, // ... } ``` 現在我們必須定義`webSocketFn` 。在`./src/server`目錄中建立一個新檔案`ws-server.ts`並複製以下程式碼: ``` import { getUsername } from 'wasp/auth'; import { type WebSocketDefinition } from 'wasp/server/webSocket'; type PollState = { question: string; options: { id: number; text: string; description: string; votes: string[]; }[]; }; interface ServerToClientEvents { updateState: (state: PollState) => void; } interface ClientToServerEvents { vote: (optionId: number) => void; askForStateUpdate: () => void; } interface InterServerEvents {} export const webSocketFn: WebSocketDefinition<ClientToServerEvents, ServerToClientEvents, InterServerEvents> = ( io, _context ) => { const poll: PollState = { question: "What are eating for lunch ✨ Let's order", options: [ { id: 1, text: 'Party Pizza Place', description: 'Best pizza in town', votes: [], }, { id: 2, text: 'Best Burger Joint', description: 'Best burger in town', votes: [], }, { id: 3, text: 'Sus Sushi Place', description: 'Best sushi in town', votes: [], }, ], }; io.on('connection', (socket) => { if (!socket.data.user) { console.log('Socket connected without user'); return; } const connectionUsername = getUsername(socket.data.user); console.log('Socket connected: ', connectionUsername); socket.on('askForStateUpdate', () => { socket.emit('updateState', poll); }); socket.on('vote', (optionId) => { if (!connectionUsername) { return; } // If user has already voted, remove their vote. poll.options.forEach((option) => { option.votes = option.votes.filter((username) => username !== connectionUsername); }); // And then add their vote to the new option. const option = poll.options.find((o) => o.id === optionId); if (!option) { return; } option.votes.push(connectionUsername); io.emit('updateState', poll); }); socket.on('disconnect', () => { console.log('Socket disconnected: ', connectionUsername); }); }); }; ``` 您可能已經注意到,與傳統的 React/NodeJS 方法相比,Wasp 實作中所需的配置和樣板要少得多。那是因為: - 端點, - 驗證, - 以及 Express 和[Socket.IO](http://Socket.IO)中間件 一切都由 Wasp 為您處理。通知! ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1nvqwcd62j7coe938zxc.png) 現在讓我們繼續執行該應用程式來看看我們現在有什麼。 首先,我們需要初始化資料庫,以便我們的身份驗證正常運作。由於複雜性很高,我們在前面的範例中沒有這樣做,但使用 Wasp 很容易做到: ``` wasp db migrate-dev ``` 完成後,執行應用程式(第一次執行需要一段時間才能安裝所有依賴項): ``` wasp start ``` 這次您應該會看到登入畫面。先註冊一個用戶,然後登入: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7b5rub505uat10z45qmv.png) 登入後,您將看到與上一個範例相同的硬編碼輪詢資料,因為我們還沒有在前端設定[Socket.IO](http://Socket.IO)客戶端。但這一次應該容易多了。 為什麼?嗯,除了更少的配置之外,將[TypeScript 與 Wasp](https://wasp-lang.dev/docs/typescript#websocket-full-stack-type-support)一起使用的另一個好處是,您只需在伺服器上定義具有匹配事件名稱的有效負載類型,這些類型將自動在客戶端上公開! 現在讓我們看看它是如何工作的。 在`.src/client/MainPage.tsx`中,將內容替換為以下程式碼: ``` // Wasp provides us with pre-configured hooks and types based on // our server code. No need to set it up ourselves! import { type ServerToClientPayload, useSocket, useSocketListener } from 'wasp/client/webSocket'; import { useAuth } from 'wasp/client/auth'; import { useState, useMemo, useEffect } from 'react'; import { Button, Card } from 'flowbite-react'; import { getUsername } from 'wasp/auth'; const MainPage = () => { // Wasp provides a bunch of pre-built hooks for us :) const { data: user } = useAuth(); const [poll, setPoll] = useState<ServerToClientPayload<'updateState'> | null>(null); const totalVotes = useMemo(() => { return poll?.options.reduce((acc, option) => acc + option.votes.length, 0) ?? 0; }, [poll]); const { socket } = useSocket(); const username = user ? getUsername(user) : null; useSocketListener('updateState', (newState) => { setPoll(newState); }); useEffect(() => { socket.emit('askForStateUpdate'); }, []); function handleVote(optionId: number) { socket.emit('vote', optionId); } return ( <div className='w-full max-w-2xl mx-auto p-8'> <h1 className='text-2xl font-bold'>{poll?.question ?? 'Loading...'}</h1> {poll && <p className='leading-relaxed text-gray-500'>Cast your vote for one of the options.</p>} {poll && ( <div className='mt-4 flex flex-col gap-4'> {poll.options.map((option) => ( <Card key={option.id} className='relative transition-all duration-300 min-h-[130px]'> <div className='z-10'> <div className='mb-2'> <h2 className='text-xl font-semibold'>{option.text}</h2> <p className='text-gray-700'>{option.description}</p> </div> <div className='absolute bottom-5 right-5'> {username && !option.votes.includes(username) ? ( <Button onClick={() => handleVote(option.id)}>Vote</Button> ) : ( <Button disabled>Voted</Button> )} {!user} </div> {option.votes.length > 0 && ( <div className='mt-2 flex gap-2 flex-wrap max-w-[75%]'> {option.votes.map((username, idx) => { return ( <div key={username} className='py-1 px-3 bg-gray-100 rounded-lg flex items-center justify-center shadow text-sm' > <div className='w-2 h-2 bg-green-500 rounded-full mr-2'></div> <div className='text-gray-700'>{username}</div> </div> ); })} </div> )} </div> <div className='absolute top-5 right-5 p-2 text-sm font-semibold bg-gray-100 rounded-lg z-10'> {option.votes.length} / {totalVotes} </div> <div className='absolute inset-0 bg-gradient-to-r from-yellow-400 to-orange-500 opacity-75 rounded-lg transition-all duration-300' style={{ width: `${totalVotes > 0 ? (option.votes.length / totalVotes) * 100 : 0}%`, }} ></div> </Card> ))} </div> )} </div> ); }; export default MainPage; ``` 與先前的實作相比,Wasp 使我們不必配置[Socket.IO](http://Socket.IO)客戶端以及建置我們自己的鉤子。 另外,將滑鼠懸停在客戶端程式碼中的變數上,您將看到系統會自動為您推斷類型! 這只是一個例子,但它應該適用於所有人: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mi1rlergrj6wqht8uu0v.png) 現在,如果您打開一個新的私人/隱身選項卡,註冊一個新用戶並登錄,您將看到一個完全執行的即時投票應用程式。最好的部分是,與以前的方法相比,我們可以註銷並重新登錄,並且我們的投票資料仍然存在,這正是我們對生產級應用程式的期望。 🎩 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0gkcdes6ntn48upqqeg.gif) 太棒了…😏 比較兩種方法 ------ 現在,僅僅因為一種方法看起來更容易,並不總是意味著它總是更好。讓我們快速總結一下上述兩種實現的優點和缺點。 | |沒有黃蜂|與黃蜂| | --- | --- | --- | | 😎 目標用戶 |資深開發人員,Web 開發團隊 |全端開發人員、「Indiehackers」、初級開發人員 | | 📈 程式碼的複雜性 |中到高 |低| | 🚤 速度 |更慢、更有條理 |更快、更整合 | | 🧑‍💻 圖書館 |任何| Socket.IO | | ⛑ 類型安全 |在伺服器和客戶端上實作 |在伺服器上實作一次,由客戶端上的 Wasp 推斷 | | 🎮 控制量 |高,由你決定實施|各抒己見,黃蜂決定基本實現| | 🐛 學習曲線 |複雜:全面了解前端和後端技術,包括 WebSockets |中級:需要了解全端基礎知識。 | ### 使用 React、Express.js(不使用 Wasp)實作 WebSocket 優點: 1. 控制和**靈活性**:您可以按照最適合您的專案需求的方式來實現 WebSocket,也可以在[許多不同的 WebSocket 庫](https://www.atatus.com/blog/websocket-libraries-for-nodejs/)(而不僅僅是 Socket.IO)之間進行選擇。 缺點: 1. **更多程式碼和複雜性**:如果沒有像 Wasp 這樣的框架提供的抽象,您可能需要編寫更多程式碼並建立自己的抽象來處理常見任務。更不用說 NodeJS/ExpressJS 伺服器的正確配置(範例中提供的配置非常基本) 2. 手動**類型安全性:如果您使用 TypeScript,則必須更小心地輸入傳入和傳出伺服器的事件處理程序和有效負載類型,或自行實作更類型安全的方法。** ### 使用 Wasp 實作 WebSocket(在底層使用 React、ExpressJS 和[Socket.IO](http://Socket.IO) ) 優點: 1. 完全整合**/更少的程式碼**:Wasp 提供了有用的抽象,例如用於 React 元件的`useSocket`和`useSocketListener`掛鉤(除了其他功能,例如身份驗證、非同步作業、電子郵件發送、資料庫管理和部署),簡化了客戶端程式碼,並允許以更少的配置進行完全整合。 2. **類型安全**:Wasp 促進 WebSocket 事件和有效負載的全端類型安全。這降低了由於資料類型不匹配而導致執行時錯誤的可能性,並且使您無需編寫更多樣板檔案。 缺點: 1. **學習曲線**:不熟悉 Wasp 的開發人員需要學習該框架才能有效地使用它。 2. **控制較少**:雖然 Wasp 提供了很多便利,但它抽象化了一些細節,使開發人員對套接字管理的某些方面的控制稍微減少。 --- **幫我幫你**🌟 如果您還沒有,請[在 GitHub 上為我們加註星標](https://www.github.com/wasp-lang/wasp),特別是如果您發現這很有用的話!如果您這樣做,它將有助於支持我們建立更多此類內容。如果你不……好吧,我想我們會處理它。 ![https://media.giphy.com/media/3oEjHEmvj6yScz914s/giphy.gif](https://media.giphy.com/media/3oEjHEmvj6yScz914s/giphy.gif) {% cta https://www.github.com/wasp-lang/wasp %} ⭐️ 感謝您的支持🙏 {% endcta %} --- 結論 -- 一般來說,如何將 WebSocket 加入到 React 應用程式取決於專案的具體情況、您對可用工具的熟悉程度以及您願意在易用性、控制和複雜性之間進行權衡。 不要忘記,如果您想查看我們的“午餐投票”示例全棧應用程式的完整完成程式碼,請轉到此處: <https://github.com/vincanger/websockets-wasp> 如果您使用 WebSockets 建立了一些很酷的東西,請在下面的評論中與我們分享 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c22za38ojlgv2xw6jfii.png) --- 原文出處:https://dev.to/wasp/build-a-real-time-voting-app-with-websockets-react-typescript-3oof

Glasskube v0.10.0 現已發布!

歡迎回到另一篇`new release`部落格文章🚀 我們在這裡介紹最新發布的功能、增強功能、錯誤修復,並介紹所有最新的[Glasskube](https://github.com/glasskube/glasskube)新聞,以確保您完全了解最新情況。我們一直在內部功能開發的動力以及更廣泛社區的興趣中不斷前進,這導致了**Glasskube v0.10.0**的交付。 讓我們看看您可以在這個新的次要版本中找到什麼。 🚨 警報:即將發生的重大變化 ⛓️‍💥 ------------------- 到目前為止,Glasskube 軟體包只能在每個叢集安裝一次,這有時會施加不必要的限制並限制某些用例。 > 從 v0.10.0 開始,套件的作者可以指定一個**“範圍”,**可以是**“集群”**或**“命名空間”** (預設為“集群”)。根據套件範圍,Glasskube 系統會建立叢集範圍或命名空間範圍的自訂資源。群集範圍的 CRD 的名稱是`ClusterPackage` ,而命名空間範圍的 CRD 的名稱是`Package` 。此更新引入了重大更改,因為我們先前對叢集範圍的資源使用了`Package` CRD 名稱。但是,我們決定實施此變更以與常見的 Kubernetes 術語(例如`Role` / `ClusterRole` )保持一致。 ### 附加功能和 UI 增強 - 為了幫助升級到 v0.10.0,新增了`glasskube purge`指令來幫助刪除先前的安裝。 - 還新增了`glasskube repo update`命令,用於從配置的 Glasskube 套件儲存庫中取得最新的套件清單。 [在此處](https://github.com/glasskube/glasskube/releases)存取完整的變更日誌 ### 升級到v0.10.0 > 首次安裝,請按照[此處的](https://glasskube.dev/docs/getting-started/install/)安裝指南進行操作。 要升級 Glasskube CLI,如果您使用的是[Linux](https://glasskube.dev/docs/getting-started/install/)或[Windows](https://releases.dl.glasskube.dev/glasskube_v0.9.0_windows_x86_64.zip)計算機,請安裝最新的二進位。 對於 macOS,執行: ``` brew upgrade glasskube ``` 若要升級 Glasskube 的叢集元件,請依照[此處的升級指南](https://glasskube.dev/docs/getting-started/upgrading/)進行操作。 🆕 新軟體包整合現已推出 ------------ ### 機智 [Quickwit](https://quickwit.io/)是一個雲端原生搜尋引擎,其出現的目標是建立一個開源替代品來取代 Datadog/Splunk 等昂貴的監控軟體。憑藉其強大的與 Elasticsearch 相容的 API,Quickwit 與 OSS 生態系統的工具(例如 Grafana、Jaeger 和 OpenTelemetry)很好地整合。 用戶正在成功大規模部署 Quickwit,每天吸收數百個節點和數百 TB 的資料,同時享受顯著的成本降低以及借助 Glasskube 可以立即啟動和執行。 Quickwit 擅長處理日誌、追蹤、安全資料和僅附加資料集,並計劃很快支援指標。 ![玻璃立方體和Quickwit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/49oonpe9gv2zet0vs9aj.png) ### 斧頭 [Hatchet](https://hatchet.run/)是一個分散式、容錯的任務佇列,它取代了傳統的訊息代理程式和發布/訂閱系統,旨在解決並發性、公平性和持久性等問題。 ![斧頭冰塊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v7p2mniv0hgb9q7hhzz0.png) [在此](https://docs.hatchet.run/self-hosting/kubernetes-glasskube)尋找安裝說明。 ⏭️ 下一個支援的軟體包 ------------ ### 庫貝串流 [Kubeflow](https://www.kubeflow.org/)專案致力於讓 Kubernetes 上的機器學習 (ML) 工作流程的部署變得簡單、可移植且可擴展。他們的目標不是重新建立其他服務,而是提供一種簡單的方法,將最佳的 ML 開源系統部署到不同的基礎架構。 ### 頭燈 [Headlamp](https://headlamp.dev/)開箱即用,是一台功能齊全的 Kubernetes UI。透過利用其強大的插件系統,建構者可以塑造 Headlamp 以適應其客製化的用例、產品和環境。 ### 帆船 在 VMWare 旗下, [Velero](https://velero.io/)是一款開源工具,用於安全備份和復原、執行災難復原以及遷移 Kubernetes 叢集資源和持久磁碟區。 📹更新了演示影片 -------- 查看 Philip 提供的最新 Glasskube 演示影片,您可以在其中找到高達 v0.9.0 的最新專案更新。 {% 嵌入 https://www.youtube.com/watch?v=aIeTHGWsG2c %} 如果您還沒有,請前往[Glasskube YouTube 頻道](https://www.youtube.com/@glasskube/videos),您可以在其中找到不斷增加的每週社群通話、發布影片甚至一些簡短內容的檔案。 ☁️ 加入 Glasskube 雲 ----------------- 我們開始建立 Glasskube 雲端產品,以包含安全性、可存取性和團隊協作方面的進階功能。請[在此處](https://glasskube.cloud/signup.html)註冊,以了解我們的最新進展。 ![玻璃立方體雲片段](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jya4p0vqd8dgpmoy74c.png) --- 如果您喜歡我們的內容並希望支持我們完成這項使命,請在 GitHub 上給我們一顆星⭐️,我們將不勝感激。 ![給了](https://media4.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHVuenNmNGJnYWhzam43MmkxemNrNzloOHJ3ZzZmbGFyb3lseGNteSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l3q2wJsC23ikJg9xe/giphy.gif) {% cta https://github.com/glasskube/glasskube %} ⭐️ 在 GitHub 上為我們加星號 🙏 {% endcta %} --- 原文出處:https://dev.to/glasskube/glasskube-v0100-out-now-3ipi

2024 年您需要了解的免費 API

[![給我買一杯咖啡](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/dk119819) API(應用程式介面)是開發人員必不可少的工具,使他們能夠將第三方服務整合到他們的應用程式中。以下是 2024 年跨不同類別的免費 API 的詳細列表,以及每個 API 的網站連結、描述和範例程式碼。 遊戲 API ------ ### Steam 社群 API - **網址**: [steamcommunity.com/dev](https://steamcommunity.com/dev) - **描述**:Steamworks Web API 提供了各種 Steam 功能的接口,例如使用者驗證、庫存管理和遊戲資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const steamApiKey = 'YOUR_STEAM_API_KEY'; const steamId = 'STEAM_USER_ID'; const url = `http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${steamApiKey}&steamids=${steamId}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 防暴遊戲 API - **網址**: [developer.riotgames.com](https://developer.riotgames.com) - **描述**:存取《英雄聯盟》、《雲頂之弈》、《Valorant》等遊戲的資料。提供比賽、排名、冠軍和其他遊戲相關統計資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const riotApiKey = 'YOUR_RIOT_API_KEY'; const summonerName = 'SUMMONER_NAME'; const url = `https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/${summonerName}?api_key=${riotApiKey}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 語言API ----- ### 邪惡侮辱生成器 API - **網址**: [evilinsult.com/api](https://evilinsult.com/api) - **描述**:出於娛樂或測試目的,以各種語言產生隨機侮辱。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://evilinsult.com/generate_insult.php?lang=en&type=json'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 趣味翻譯 API - **網址**: [funtranslations.com/api](https://funtranslations.com/api) - **描述**:將文字翻譯成各種有趣的語言,如尤達語言、莎士比亞語言、小小兵語言等等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const text = 'Hello, world!'; const url = `https://api.funtranslations.com/translate/yoda.json?text=${encodeURIComponent(text)}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 音樂 API ------ ### Spotify 網路 API - **網址**: [developer.spotify.com/documentation/web-api](https://developer.spotify.com/documentation/web-api) - **描述**:存取音樂資料,例如專輯、藝術家、播放清單和用戶資料。控制 Spotify 播放等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const accessToken = 'YOUR_SPOTIFY_ACCESS_TOKEN'; const url = 'https://api.spotify.com/v1/me/player/recently-played'; fetch(url, { headers: { 'Authorization': `Bearer ${accessToken}` } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 安全API ----- ### 我被偷了嗎 API - **網址**: [haveibeenpwned.com/API/v2](https://haveibeenpwned.com/API/v2) - **描述**:檢查您的電子郵件或使用者名稱是否屬於資料外洩的一部分。提供有關違規、貼上和密碼洩露的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const email = '[email protected]'; const url = `https://haveibeenpwned.com/api/v2/breachedaccount/${email}`; fetch(url, { headers: { 'User-Agent': 'Node.js' } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 首丹API - **網址**: [developer.shodan.io](https://developer.shodan.io) - **描述**:Shodan 是一個針對網路連線裝置的搜尋引擎。它提供全球各種伺服器、設備和系統的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const shodanApiKey = 'YOUR_SHODAN_API_KEY'; const query = 'apache'; const url = `https://api.shodan.io/shodan/host/search?key=${shodanApiKey}&query=${query}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 科學與數學 API --------- ### 美國太空總署火災 - **網址**: [api.nasa.gov](https://api.nasa.gov) - **描述**:存取 NASA 資料集中的資料,包括天文照片、行星資料等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const nasaApiKey = 'YOUR_NASA_API_KEY'; const url = `https://api.nasa.gov/planetary/apod?api_key=${nasaApiKey}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### Wolfram Alpha API - **網址**: [products.wolframalpha.com/api](https://products.wolframalpha.com/api) - **描述**:提供對 Wolfram Alpha 的大量計算知識的存取,包括數學計算、資料分析等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const wolframAppId = 'YOUR_WOLFRAM_APP_ID'; const query = 'integrate x^2'; const url = `http://api.wolframalpha.com/v2/query?input=${encodeURIComponent(query)}&appid=${wolframAppId}&output=json`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 開放科學框架 API - **網址**: [developer.osf.io](https://developer.osf.io) - **描述**:從開放科學框架存取研究資料、專案管理工具和其他科學資源。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api.osf.io/v2/nodes/'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 體育 API ------ ### NBA應用程式介面 - **網址**: [any-api.com/nba\_com/nba\_com/docs/API\_Description](https://any-api.com/nba_com/nba_com/docs/API_Description) - **描述**:存取 NBA 球隊、球員和比賽的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api-nba-v1.p.rapidapi.com/teams/league/standard'; const options = { method: 'GET', headers: { 'X-RapidAPI-Key': 'YOUR_RAPIDAPI_KEY', 'X-RapidAPI-Host': 'api-nba-v1.p.rapidapi.com' } }; fetch(url, options) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 網路應用 API -------- ### 不和諧 API - **網址**: [discord.com/developers/docs/intro](https://discord.com/developers/docs/intro) - **描述**:將您的應用程式與 Discord 集成,允許用戶身份驗證、訊息傳遞等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const discordToken = 'YOUR_DISCORD_BOT_TOKEN'; const url = 'https://discord.com/api/users/@me'; fetch(url, { headers: { 'Authorization': `Bot ${discordToken}` } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 鬆弛API - **網址**: [api.slack.com](https://api.slack.com) - **描述**:存取 Slack 功能,例如訊息傳遞、使用者資料和工作區管理。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const slackToken = 'YOUR_SLACK_API_TOKEN'; const url = 'https://slack.com/api/conversations.list'; fetch(url, { headers: { 'Authorization': `Bearer ${slackToken}` } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 產品和事物 API --------- ### 汽車查詢API - **網址**: [carqueryapi.com](https://carqueryapi.com) - **描述**:存取汽車資料,包括 品牌、型號和年份資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://www.carqueryapi.com/api/0.3/?cmd=getMakes'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 叫喊 API - **網址**: [yelp.com/developers](https://yelp.com/developers) - **描述**:存取本地企業的資料,包括評論、評級和企業詳細資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const yelpApiKey = 'YOUR_YELP_API_KEY'; const url = 'https://api.yelp.com/v3/businesses/search?location=San Francisco'; fetch(url, { headers: { 'Authorization': `Bearer ${yelpApiKey}` } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 健康API ----- ### 醫療保健.gov API - **網址**: [healthcare.gov/developers](https://healthcare.gov/developers) - **描述**:存取醫療保健計劃、提供者目錄和其他健康相關資訊的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://data.healthcare.gov/resource/xyz123.json'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 政府和地理 API --------- ### 程式碼.gov API - **網址**: [code.gov](https://code.gov) - **描述**:存取聯邦政府軟體專案的資料,包括程式碼儲存庫和專案詳細資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api.code.gov/projects'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 資料政府API - **網址**: [data.gov/developers/apis](https://data.gov/developers/apis) - **描述**:存取美國政府提供的各種資料集,包括天氣、教育和健康資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api.data.gov/ed/collegescorecard/v1/schools.json?api_key=YOUR_DATA_GOV_API_KEY'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 資料.europa.eu API - **網址**: [data.europa.eu/en](https://data.europa.eu/en) - **描述**:存取歐盟機構和團體的開放資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://data.europa.eu/api/hub/search/datasets'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 傳輸定位API - **網址**: [rapidapi.com/transloc/api/openapi-1-2/details](https://rapidapi.com/transloc/api/openapi-1-2/details) - **描述**:存取即時公共交通資料,包括到達預測、車輛位置等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const translocApiKey = 'YOUR_TRANSLOC_API_KEY'; const url = 'https://transloc-api-1-2.p.rapidapi.com/agencies.json'; fetch(url, { headers: { 'X-RapidAPI-Key': translocApiKey, 'X-RapidAPI-Host': 'transloc-api-1-2.p.rapidapi.com' } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 食品原料藥 ----- ### 開放食品事實 API - **網址**: [world.openfoodfacts.org/data](https://world.openfoodfacts.org/data) - **描述**:存取全球食品資料,包括成分、營養成分和過敏原資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://world.openfoodfacts.org/api/v0/product/737628064502.json'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 塔克花式 API - **網址**: [github.com/evz/tacofancy-api](https://github.com/evz/tacofancy-api) - **描述**:存取玉米捲食譜資料,包括成分和製備方法。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'http://taco-randomizer.herokuapp.com/random/'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 開源專案 API -------- ### 圖書館.io API - **網址**: [libraries.io/api](https://libraries.io/api) - **描述**:存取開源專案的資料,包括相依性資訊、版本歷史記錄等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const librariesApiKey = 'YOUR_LIBRARIES_IO_API_KEY'; const url = `https://libraries.io/api/platforms?api_key=${librariesApiKey}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 電影和漫畫 API --------- ### 查克諾里斯笑話 API - **網址**: [api.chucknorris.io](https://api.chucknorris.io) - **描述**:參觀查克諾里斯笑話集。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api.chucknorris.io/jokes/random'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 最終空間 API - **網址**: [finalspaceapi.com](https://finalspaceapi.com) - **描述**:存取《最終太空》電視節目的資料,包括角色、劇集等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://finalspaceapi.com/api/v0/character'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 木津API - **網址**: [kitsu.docs.apiary.io](https://kitsu.docs.apiary.io) - **描述**:存取動漫和漫畫的資料,包括系列資訊、評論和用戶評分。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://kitsu.io/api/edge/anime'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 漫威API - **網址**: [developer.marvel.com](https://developer.marvel.com) - **描述**:存取有關 Marvel 漫畫、角色和創作者的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const marvelPublicKey = 'YOUR_MARVEL_PUBLIC_KEY'; const marvelPrivateKey = 'YOUR_MARVEL_PRIVATE_KEY'; const ts = new Date().getTime(); const hash = require('crypto').createHash('md5').update(ts + marvelPrivateKey + marvelPublicKey).digest('hex'); const url = `https://gateway.marvel.com/v1/public/characters?ts=${ts}&apikey=${marvelPublicKey}&hash=${hash}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 戳API - **網址**: [pokeapi.co](https://pokeapi.co) - **描述**:存取神奇寶貝的資料,包括物種、能力和遊戲資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://pokeapi.co/api/v2/pokemon/ditto'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 瑞克和莫蒂 API - **網址**: [rickandmortyapi.com](https://rickandmortyapi.com) - **描述**:存取瑞克和莫蒂電視節目的資料,包括角色、劇集和地點。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://rickandmortyapi.com/api/character'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 辛普森一家行情 API - **網址**: [thesimpsonsquoteapi.glitch.me](https://thesimpsonsquoteapi.glitch.me) - **描述**:造訪《辛普森家庭》電視節目中的台詞集。 #### 樣本 程式碼 ``` const fetch = require('node-fetch'); const url = 'https://thesimpsonsquoteapi.glitch.me/quotes'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 星際大戰 API - **網站**: [swapi.tech](https://swapi.tech) - **描述**:存取星際大戰宇宙的資料,包括電影、角色、星際飛船和行星。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://swapi.tech/api/people/1'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 超級英雄API - **網址**: [superheroapi.com](https://superheroapi.com) - **描述**:存取各種超級英雄的資料,包括他們的力量、傳記和圖像。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const superheroApiKey = 'YOUR_SUPERHERO_API_KEY'; const url = `https://superheroapi.com/api/${superheroApiKey}/1`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 結論 -- 這份 2024 年免費 API 的完整清單涵蓋了廣泛的類別,為開發人員提供了大量機會,透過強大且多樣化的功能來增強其應用程式。從遊戲和音樂到科學和政府資料,這些 API 為建立創新且引人入勝的專案提供了寶貴的資源。 請隨意探索這些 API 並將它們整合到您的專案中,以解鎖新的可能性和功能。快樂編碼! --- 💰 你可以透過捐贈來幫助我 ------------- [![給我買一杯咖啡](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/dk119819) --- 原文出處:https://dev.to/raajaryan/free-apis-you-need-to-know-about-in-2024-2ieg

我正在尋找 FullStack 軟體開發人員職位

嘿,大家,希望你們一直做得很好並且感覺很好!我叫 Cherry Ramatis,目前正在尋找成為 FullStack 軟體開發人員的機會。 我熱衷於學習新事物並成為社區中的積極人物以實現知識民主化,因為我發現這是成為更好的專業人士並同時認識很酷的人(雙贏)的關鍵。我透過參加聚會、發表演講、為初級和中級開發人員提供指導、撰寫友好而足智多謀的文章以及總體上成為一個對任何人都平易近人且樂於助人的人物來做到這一點。 就我個人而言,我有三隻漂亮的狗,我喜歡在海灘上散步,也喜歡和朋友一起去卡拉 OK 酒吧(這是享受涼爽快樂時光的好機會👀) 稍微了解一下我 ------- - **名稱:**櫻桃拉馬蒂斯 - **目前居住地:**巴西聖保羅 - **我在專業領域中積極使用的技術:** - 打字稿/Javascript - 反應 - 下一個 - 角 - 承載者 - 碼頭工人 - Github 操作 - PostgreSQL - MongoDB - **我願意使用的技術:** - 紅寶石 - 紅寶石 on Rails - 靈丹妙藥 - 鳳凰 - **時間編碼總計:**約10年 - **專業時間編碼:**目前我已工作 6 年 - **線上和現場進行的演講數量:** - 在[He4rt 開發者](https://discord.gg/he4rt)社群進行了 3 場線上演講 - 在[ElixirDays](https://x.com/elaine_nw/status/1795459111678570643)發表 1 場面對面演講 - **發表文章數量:**目前發表文章21篇,瀏覽量約6.7萬,接觸人數達1.1萬 我引以為傲的成就 -------- - **參與巴西播客「Elixir em Foco」:** https://www.youtube.com/watch?v=zYl6ec4G4k8 - **被 dev.to 評為 2023 年排名前 7 位的作者之一:** https://dev.to/devteam/top-7s-top-authors-of-the-year-120m - **對大型資料庫公司的開源貢獻:** https://cloud-getting-started.scylladb.com/stable/build-with-ruby 我最喜歡的專案 ------- - **Regexer - 從單行語言到正規表示式的編譯器:** https://github.com/cherryramatisdev/regexer - **使用 Ruby 進行依賴注入的 HTTP 伺服器模組化架構:** https://github.com/cherryramatisdev/api-with-dry-ruby - **rust 和 elixir 中從偽語言到有效字節碼 BEAM 檔案的編譯器:** https://github.com/cherryramatisdev/beam\_studies - **使用 ruby 將異常轉換為結果單子的實驗:** https://github.com/cherryramatisdev/monadic-exceptions 你如何聯絡我 ------ - **領英:** https://www.linkedin.com/in/cherryramatis/ - **推特:** https://x.com/cherryramatis - **開發者:** https://dev.to/cherryramatis --- 原文出處:https://dev.to/cherryramatis/im-looking-for-a-fullstack-software-developer-role-417m

您可以在開源中貢獻這 25 個專案

受資助計畫的聲譽非常好,因為它們獲得了大量資金並得到了風險投資的支持。 有很多開源專案,你絕對應該為這些專案做出貢獻,特別是因為它們的可信度要高得多。 也許你有機會獲得直接的工作機會,畢竟你真的不知道誰在開源中關注你! 我只保留了活躍的專案(最後一次提交不到 2 個月),所以它會很有用。讓我們保持簡短和直接。 --- 1. [Taipy](https://github.com/Avaiga/taipy) - 資料和人工智慧演算法融入生產級網路應用程式。 -------------------------------------------------------------------- ![打字](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wd10iiofzmt4or4db6ej.png) Taipy 是用於輕鬆、端到端應用程式開發的完美 Python 程式庫,具有假設分析、智慧型管道執行、內建調度和部署工具。 它用於為基於 Python 的資料和人工智慧應用程式建立 GUI 介面並改進資料流管理。 關鍵是性能,而 Taipy 是完美的選擇,尤其是與 Streamlit 相比。您可以閱讀 Marktechpost 發表的[Taipy 與 Streamlit](https://www.marktechpost.com/2024/03/15/taipy-vs-streamlit-navigating-the-best-path-to-build-python-data-ai-web-applications-with-multi-user-capability-large-data-support-and-ui-design-flexibility/)的詳細比較。 - 💰 獲得總資金 500 萬美元。 - 🚀 使用的主要語言是Python。 Taipy 在 GitHub 上有近 10k 顆星,並且正在發布`v3.1`版本。 https://github.com/Avaiga/taipy Star Taipy ⭐️ --- 2. [Hoppscotch](https://github.com/hoppscotch/hoppscotch) - API 開發生態系統。 ----------------------------------------------------------------------- ![跳房子](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75cjol6454uvrnth524y.png) Hoppscotch 是一個輕量級、基於 Web 的 API 開發套件。它是從頭開始建置的,考慮到了易用性和可存取性。 Hoppscotch 與 Postman 非常相似,但提供了一些不同的功能。這就是儀表板的樣子,您可以在[hoppscotch.io](https://hoppscotch.io/)上進行即時測試。 ![跳房子](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2f6ck92qdpd99in6wav.png) 即使測試本機 API,Postman 也要求您保持線上狀態。使用 Hoppscotch,您可以在沒有網路連線的情況下使用 API。 甚至 Web 應用程式也可以透過本機快取離線執行並充當 PWA,讓您可以隨時隨地測試 API! Hoppscotch 也提供私人工作空間。請參閱[完整功能清單](https://github.com/hoppscotch/hoppscotch?tab=readme-ov-file#features)。 ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d36kmr72z11h71nnvhf5.png) 最好的部分也是必要的部分是他們提供完整的[文件](https://docs.hoppscotch.io/),其中包括指南、文章、支援和變更日誌,以便您可以在這裡看到所有內容。 ![2023年已結束](https://hoppscotch.com/images/blog-hoppscotch-wrapped-2023.png) - 💰 獲得總資金 300 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Hoppscotch 在 GitHub 上擁有超過 60k 顆星,有 300 多個活躍問題和 200 多個貢獻者。 https://github.com/hoppscotch/hoppscotch 明星跳房子 ⭐️ --- 3. [Daily](https://github.com/dailydotdev/daily) - 每個開發者都值得擁有的首頁。 ----------------------------------------------------------------- ![日常的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qvzd1auk8wet7vv5ev37.png) 這是一個專業網絡,您可以在其中閱讀與開發者生態系統相關的文章和個人化動態訊息。 他們匯總了來自許多組織(例如 Hacker News、Dev、Hashnode 等)的各種主題的有價值的帖子。您可以投票、加書籤,甚至建立自己的小隊。 ![小隊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqqkl42pja53ssywltyl.png) 我是其中一些功能的粉絲,如果我解釋所有內容,我會花費幾個小時,所以最好檢查一下。 這是我個人最喜歡的開源專案之一。你可以查看我的[每日個人資料](https://app.daily.dev/anmolbaranwal)。 - 💰 獲得總資金 1100 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Dailydotdev 在 GitHub 上擁有 17k+ 顆星。 https://github.com/dailydotdev/daily 明星日報 ⭐️ --- 4. [Requestly](https://github.com/requestly/requestly) - 瀏覽器的 HTTP 攔截器。 ----------------------------------------------------------------------- ![請求地](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1jnfzpqe827qxm11a1tm.png) Requestly 的建置是為了透過攔截和修改 HTTP 請求來節省開發人員的時間。 Requestly 為前端開發人員提供必要的工具和整合協助,幫助他們以 10 倍的速度編寫、測試和偵錯程式碼。 Requestly 減少了對後端開發人員和開發和測試需求環境的依賴。 使用 Requestly,開發人員可以建立模擬、測試、驗證和覆蓋 API 回應,修改請求和回應標頭,設定重定向(映射本機、映射遠端),並使用 Requestly 會話進行更快的偵錯。 您可以看到[完整功能](https://github.com/requestly/requestly?tab=readme-ov-file#-features)的清單。 - 💰 獲得 50 萬美元的種子資金。 - 🚀 使用的主要語言是 TypeScript。 Requestly 在 GitHub 上擁有超過 1,800 顆星,並且正在快速成長。 https://github.com/requestly/requestly 為請求加星號 ⭐️ --- 5.[重新發送](https://github.com/resend)- 給開發人員的電子郵件。 ------------------------------------------------ ![重發](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a7diqqs4n4yrshxf22l3.png) 電子郵件可能是人們溝通的最重要的媒介。然而,我們需要停止像 2010 年那樣開發電子郵件,並重新思考 2022 年及以後如何開發電子郵件。它應該針對我們今天建立網頁應用程式的方式進行現代化。 他們提供了許多與我們正在使用的技術堆疊相對應的不同儲存庫。請隨意探索其中每一個。 ![重新發送集成](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4jmx7q5i4wrsnwgcuvwk.png) - 💰 獲得 350 萬美元種子資金。 - 🚀 使用的主要語言是 TypeScript(React 電子郵件)。 Resend(React email)在 GitHub 上擁有超過 12,500 顆星,並被超過 7,500 名開發者使用。 https://github.com/resend 星標重新發送 ⭐️ --- 6. [Buildship](https://github.com/rowyio/buildship/) - 由人工智慧驅動的低程式碼視覺後端建構器。 --------------------------------------------------------------------------- ![建造船](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzlrynz5xephv4t9layd.png) 對於您正在使用無程式碼應用程式建構器(FlutterFlow、Webflow、Framer、Adalo、Bubble、BravoStudio...)或前端框架(Next.js、React、Vue...)建立的應用程式,您需要一個後端來支援可擴展的 API、安全工作流程、自動化等。 BuildShip 為您提供了一種完全視覺化的方式,可以在易於使用的完全託管體驗中可擴展地建立這些後端任務。 這意味著您無需在雲端平台上爭論或部署事物或執行 DevOps。只需立即建造和發貨 🚀 他們甚至與 TypeSense 合作並且發展得非常快! ![建造船](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6oc3rc713mjg9cwqj7d4.png) 我嘗試過Buildship,它很強大。 - 💰 私人資金(由 Google、Vercel、Figma 等支持)。 - 🚀 使用的主要語言是 TypeScript。 它在 GitHub 上有 260 多顆星,使用 Rowy 完成,有 5800 顆星。 https://github.com/rowyio/buildship/ 明星 BuildShip ⭐️ --- 7. [Cal](https://github.com/calcom/cal.com) - 為所有人安排基礎設施。 --------------------------------------------------------- ![卡爾](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ccagnexb805xzpewfy5.png) 這是有史以來最活躍的專案之一。我也透過 Cal 的 Algora 看過很多付費演出。 早些時候,我使用 Calendly,但我將其切換到 Cal,特別是因為它們在您可以建立的連結方面提供了更大的靈活性。 例如,我有一個協作連結,人們可以在其中選擇會議的持續時間並修復其他連結中的時間安排。您可以將其附加到幾乎所有應用程式,例如 GMeet、Zoom,如果您想參加付費會議,甚至可以同步付款。應用程式整合的[總選項](https://cal.com/apps)幾乎令人難以置信:) ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/anesuu0ux6ejz886irnt.png) 您可以做很多事情,包括自動化工作流程,所以只需檢查一下即可。 ![工作流程儀表板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kc0x5vq54joov98wwq9h.png) - 💰 獲得總資金(A 輪)3240 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Cal 在 GitHub 上擁有超過 29,000 顆星,並擁有超過 600 名貢獻者。 https://github.com/calcom/cal.com Star Cal ⭐️ --- 8. [Penpot](https://github.com/penpot/penpot) - 完美協作的設計工具。 ---------------------------------------------------------- ![筆筒](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mooryn8zodod2mkpzefn.png) Penpot 是第一個用於設計和程式碼協作的開源設計工具。設計師可以大規模建立令人驚嘆的設計、互動式原型和設計系統,而開發人員則可以享受現成的程式碼,並使他們的工作流程變得簡單、快速。所有這一切都沒有任何切換戲劇性的情況。 完全免費並符合開放標準(SVG、CSS 和 HTML)。 一次性查看[庫、模板](https://penpot.app/libraries-templates)和[功能](https://penpot.app/features)的清單。 觀看以下影片體驗`Penpot 2.0` 。 - 💰 獲得總資金 800 萬美元。 - 🚀 使用的主要語言是 Clojure。 Penpot 在 GitHub 上擁有超過 28,500 顆星,目前已發布`v2.0`版本。 https://github.com/penpot/penpot 星星筆罐 ⭐️ --- 9. [Appsmith](https://github.com/appsmithorg/appsmith) - 建立管理面板、內部工具和儀表板的平台。 ---------------------------------------------------------------------------- ![應用史密斯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rt7s0r3wz2leec83cl17.png) 管理面板和儀表板是任何軟體創意(在大多數情況下)的一些常見部分,我嘗試從頭開始建立它,這會帶來很多痛苦和不必要的辛苦工作。 您可能已經看到組織建立了內部應用程式,例如儀表板、資料庫 GUI、管理面板、批准應用程式、客戶支援儀表板等,以幫助其團隊執行日常操作。正如我所說,Appsmith 是一個開源工具,可以實現這些內部應用程式的快速開發。 首先,請觀看這個 YouTube 影片,該影片在 100 秒內解釋了 Appsmith。 嵌入 https://www.youtube.com/watch?v=NnaJdA1A11s 他們提供拖放小部件來建立 UI。 您可以使用 45 多個可自訂的小工具在幾分鐘內建立漂亮的響應式 UI,而無需編寫一行 HTML/CSS。尋找[小部件的完整清單](https://www.appsmith.com/widgets)。 ![按鈕點擊小工具](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kqpnnslvsvjl4gifseon.png) ![驗證](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/489fly7tvknz2uv2mgei.png) 您可以閱讀[文件](https://docs.appsmith.com/)並使用這[20 多個範本](https://www.appsmith.com/templates)中的任何一個,以便您可以快速入門。 - 💰 獲得 500 萬美元種子資金。 - 🚀 使用的主要語言是 TypeScript。 Appsmith 在 GitHub 上擁有超過 32k 顆星,發布了 200 多個版本。 https://github.com/appsmithorg/appsmith Star Appsmith ⭐️ --- 10.[二十](https://github.com/twentyhq/twenty)- Salesforce 的現代替代品。 --------------------------------------------------------------- ![二十](https://framerusercontent.com/images/oclg8rdRgBnzeLnSJOfettLFjI.webp) 我們花了數千個小時來研究Pipedrive 和Salesforce 等傳統CRM,以使它們與我們的業務需求保持一致,但最終卻感到沮喪——定制非常複雜,而且這些平台的封閉生態系統可能會讓人感到受到限制。 Twenty 是一個現代化、功能強大、價格實惠的平台,用於管理您的客戶關係。您可以閱讀[使用者指南](https://twenty.com/user-guide)。 ![二十](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tucrt5pk9piyswnt9q77.png) - 💰 獲得 75.9 萬美元的種子資金。 - 🚀 使用的主要語言是 TypeScript。 Twenty 在 GitHub 上擁有超過 14,500 顆星,擁有 200 多名貢獻者。 https://github.com/twentyhq/twenty 二十星 ⭐️ --- 11.[繼續](https://github.com/continuedev/continue)-AI程式碼助手。 -------------------------------------------------------- ![繼續 gif](https://github.com/continuedev/continue/raw/main/docs/static/img/understand.gif) Continue 是領先的開源 AI 程式碼助理。您可以連接任何模型和任何上下文,以在[VS Code](https://marketplace.visualstudio.com/items?itemName=Continue.continue)和[JetBrains](https://plugins.jetbrains.com/plugin/22707-continue-extension)內建立自訂自動完成和聊天體驗。 > 選項卡可自動完成程式碼建議。 ![自動完成 gif](https://github.com/continuedev/continue/raw/main/docs/static/img/autocomplete.gif) > 重構您正在編碼的函數。 ![重構影像](https://github.com/continuedev/continue/raw/main/docs/static/img/inline.gif) > 詢問有關您的程式碼庫的問題。 ![程式碼庫](https://github.com/continuedev/continue/raw/main/docs/static/img/codebase.gif) > 快速使用文件作為上下文 ![文件上下文 gif](https://github.com/continuedev/continue/raw/main/docs/static/img/docs.gif) 閱讀[快速入門指南](https://docs.continue.dev/quickstart)。 - 💰 獲得 210 萬美元種子資金。 - 🚀 使用的主要語言是 TypeScript。 Continue 在 GitHub 上有 12k+ 顆星,並且發布了`v0.8`版本。 https://github.com/continuedev/continue 星繼續 ⭐️ --- [12.Refine](https://github.com/refinedev/refine) - 面向企業的開源 Retool。 ------------------------------------------------------------------ ![精煉](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wsti2yfikrhc9nggov5.png) Refine 是一個元 React 框架,可以快速開發各種 Web 應用程式。 從內部工具到管理面板、B2B 應用程式和儀表板,它可作為建立任何類型的 CRUD 應用程式(例如 DevOps 儀表板、電子商務平台或 CRM 解決方案)的全面解決方案。 ![電子商務](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xry9381y4s36emgb9psr.png) 您可以在一分鐘內使用單一 CLI 命令進行設定。 它具有適用於 15 多個後端服務的連接器,包括 Hasura、Appwrite 等。 但最好的部分是,Refine `headless by design` ,從而提供無限的樣式和自訂選項。 你可以看到[模板](https://refine.dev/templates/)。 ![範本](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/87vbx5tqyicb9gmgirka.png) - 💰 獲得總資金 380 萬美元。 - 🚀 使用的主要語言是 TypeScript。 它們在 GitHub 上擁有大約 25,000 顆星,並被超過 3,000 名開發人員使用。 https://github.com/refinedev/refine 星際精煉 ⭐️ --- 13. [Revideo](https://github.com/redotvideo/revideo) - 使用程式碼建立影片。 ----------------------------------------------------------------- ![審查](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttwzahj6kfgllj0aknt1.png) Revideo 是一個用於程式化影片編輯的開源框架。它是從令人驚嘆的 Motion Canvas 編輯器分叉出來的,將其從獨立的應用程式轉變為開發人員可以用來建立整個影片編輯應用程式的庫。 Revideo 可讓您在 Typescript 中建立視訊範本並部署 API 端點以使用動態輸入呈現它們。它還提供了一個React播放器元件來即時預覽瀏覽器中的變化。 - 💰 獲得總資金 500 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Revideo 在 GitHub 上有 1.2k 顆星,活躍問題非常少。簡而言之,這是一個完美的、不那麼擁擠的貢獻專案。 https://github.com/redotvideo/revideo 明星重錄 ⭐️ --- 14.[百萬](https://github.com/aidenybai/million)- 讓你的 React 速度提高 70%。 ------------------------------------------------------------------ ![百萬](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/afs9dm1eujmajxn0rng9.png) Million.js 是一個極其快速且輕量級的最佳化編譯器,可將元件速度提高 70%。自己探索吧! ![特徵](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vozcs5gd57rwlp3jjmr4.png) - 💰 獲得總計 50 萬美元的資金。 - 🚀 使用的主要語言是 TypeScript。 Million 在 GitHub 上擁有超過 15,500 顆星,並被超過 3000 名開發者使用。 https://github.com/aidenybai/million 明星百萬⭐️ --- 15. [FlowiseAI](https://github.com/FlowiseAI/Flowise) - 拖放 UI 來建立您的客製化 LLM 流程。 ------------------------------------------------------------------------------ ![弗洛伊薩伊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r5bp43nil764fhe4a05z.png) Flowise 是一款開源 UI 視覺化工具,用於建立客製化的 LLM 編排流程和 AI 代理程式。 ![整合](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ahk2ovjrpq1qk3r5pfot.png) 您可以閱讀[文件](https://docs.flowiseai.com/)。 ![流程化人工智慧](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/trkltpn5lk1y1pte0smd.png) - 💰 從 YCombinator 獲得資金(不知道多少)。 - 🚀 使用的主要語言是 TypeScript。 FlowiseAI 在 GitHub 上擁有超過 26,500 個 Star,並擁有超過 13,000 個分叉,因此具有良好的整體比率。 https://github.com/FlowiseAI/Flowise 明星 FlowiseAI ⭐️ --- 16.[觸發器](https://github.com/triggerdotdev/trigger.dev)——後台作業平台。 --------------------------------------------------------------- ![扳機](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iaoox3qwmc397x9ckmw4.png) Trigger.dev v3 可以輕鬆編寫可靠的長時間執行任務而不會逾時。 在它們所屬的地方建立作業:在您的程式碼庫中。像您已經習慣的那樣進行版本控制、本地主機、測試、審查和部署。 您可以選擇在自己的基礎架構上使用觸發器雲端或自架觸發器。 閱讀文件中的[快速入門指南](https://trigger.dev/docs/v3/quick-start)。 - 💰 獲得總資金 300 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Trigger 在 GitHub 上有 7,500 顆星,目前已發布`v3.1`版本。 https://github.com/triggerdotdev/trigger.dev 星觸發器 ⭐️ --- 17. [Tiptap](https://github.com/ueberdosis/tiptap) - 無頭富文本編輯器框架。 ---------------------------------------------------------------- ![尖擊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gdtmi7do65ks6f2mpsjd.png) Tiptap 編輯器是一個無頭、與框架無關的富文本編輯器,可以透過擴充功能進行自訂和擴充。它的無頭性質意味著它沒有固定的使用者介面,提供完全的設計自由(要快速入門,請參閱下面連結的 UI 模板)。 Tiptap 是基於高度可靠的 ProseMirror 庫。 Tiptap Editor 得到協作開源後端 Hocuspocus 的補充。 Editor 和 Hocuspocus 構成了 Tiptap Suite 的基礎。 我建議閱讀包含[範例](https://tiptap.dev/docs/editor/examples/default)和詳細程式碼的[文件](https://tiptap.dev/docs/editor/introduction)。 - 💰 獲得總資金 260 萬美元。 - 🚀 使用的主要語言是 TypeScript。 ![尖擊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/20c83ios6ugr1q6blqfq.png) Tiptap 在 GitHub 上擁有超過 24k 顆星,擁有 300 多名貢獻者。 https://github.com/ueberdosis/tiptap 明星 Tiptap ⭐️ --- 18. [Infisical](https://github.com/Infisical/infisical) - 秘密管理平台。 ----------------------------------------------------------------- ![內部的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrolzjdnkky1r694h9av.png) Infisical 是一個開源秘密管理平台,團隊可以用它來集中 API 金鑰、資料庫憑證和設定等秘密。 他們讓每個人(而不僅僅是安全團隊)都可以更輕鬆地進行秘密管理,這意味著從頭開始重新設計整個開發人員體驗。 ![內部](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) ,這是使用它的最佳方式。 在使用整個原始程式碼之前一定要檢查他們的[許可證](https://github.com/Infisical/infisical/blob/main/LICENSE),因為他們有一些受 MIT Expat 保護的企業級程式碼,但不用擔心,大部分程式碼都是免費使用的。 - 💰 獲得總資金 290 萬美元。 - 🚀 使用的主要語言是 TypeScript。 他們在 GitHub 上擁有超過 12,500 顆星,發布了 130 多個版本。另外,Infiscial CLI 的安裝次數超過 540 萬次,因此非常值得信賴。 https://github.com/Infisical/infisical 明星 Infisical ⭐️ --- 19. [HyperDX](https://github.com/hyperdxio/hyperdx) - 統一會話重播、日誌、指標、追蹤和錯誤的可觀察平台。 ------------------------------------------------------------------------------- ![超DX](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6r38lckflg0wmwlq6i4.png) HyperDX 透過將日誌、指標、追蹤、異常和會話重播集中並關聯到一處,幫助工程師快速找出生產中斷的原因。 Datadog 和 New Relic 的開源且開發人員友善的替代方案。閱讀[文件](https://www.hyperdx.io/docs)。 ![超DX](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9g83r7408vr2oawc8s8p.png) - 💰 獲得總計 50 萬美元的資金。 - 🚀 使用的主要語言是 TypeScript。 HyperDX 在 GitHub 上擁有超過 6k 顆星。 https://github.com/hyperdxio/hyperdx 明星 HyperDX ⭐️ --- 20.[亮點](https://github.com/highlight/highlight)-全端監控平台。 ------------------------------------------------------- ![強調](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3p2ecjnrwbtskuqrkjv7.png) highlight.io 是為下一代開發人員(像您一樣!)提供的監控工具。與現有的古老、過時的工具不同,它們的目標是建立一個有凝聚力的、現代的、功能齊全的監控解決方案。 ![支援框架](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/afaoao8954hobs7d2igw.png) - 💰 獲得總資金 850 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Highlight 在 GitHub 上有超過 7k 顆星。 https://github.com/highlight/highlight 星標亮點 ⭐️ --- 21. [Panora](https://github.com/panoratech/Panora) - 在幾分鐘內將整合目錄新增至您的 SaaS 產品。 ----------------------------------------------------------------------------- ![全景](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzhhyl8t0xy2ueln8d4t.png) Panora 協助您將產品置於客戶日常工作流程的核心。 您的客戶希望他們的所有工具都能很好地協同工作。 Panora 避免您的團隊花費數百小時來建立和維護集成,而不是核心產品。 查看[快速入門指南](https://docs.panora.dev/quick-start)。 - 💰 獲得了 50 萬美元的總資金(可能更多)。 - 🚀 使用的主要語言是 TypeScript。 Panora 在 GitHub 上擁有 300 多個 star,並且處於非常早期的階段。 https://github.com/panoratech/Panora 明星 Panora ⭐️ --- 22. [Fleet](https://github.com/fleetdm/fleet) - IT、安全和基礎設施團隊的平台。 ---------------------------------------------------------------- ![艦隊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d47vi9uyn2hq3kx6s2h6.png) 針對擁有數千台電腦的 IT 和安全團隊的開源平台。專為 API、GitOps、webhooks、YAML 和人類而設計。 Fastly 和 Gusto 等組織使用 Fleet 進行漏洞報告、偵測工程、裝置管理 (MDM)、裝置運作狀況監控、基於狀態的存取控制、管理未使用的軟體授權等。 ![艦隊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vfn75mjk5rfhb4bfjwp8.png) - 💰 獲得總資金 2500 萬美元。 - 🚀 使用的主要語言是 Go。 Fleet 在 GitHub 上擁有 2,500 顆星。 https://github.com/fleetdm/fleet 星際艦隊 ⭐️ --- 23. [Ballerine](https://github.com/ballerine-io/ballerine) - 用於風險決策的基礎設施和資料編排平台。 -------------------------------------------------------------------------------- ![舞者](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tnnrhyf6oj3dexdeyyuf.png) Ballerine 是一種開源風險管理基礎設施,可協助全球支付公司、市場和金融科技公司在整個客戶生命週期中自動為商家、賣家和使用者做出決策。 從開戶(KYC、KYB)、承銷和交易監控,使用靈活的規則和工作流程引擎、第 3 方插件系統、手動審核後台以及文件和資訊收集前端流程。 - 💰 獲得總資金 550 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Ballerine 在 GitHub 上擁有 2000 顆星,發布了 700 多個版本。 https://github.com/ballerine-io/ballerine 明星芭蕾舞者 ⭐️ --- 24. [Tooljet](https://github.com/ToolJet/ToolJet) - 用於建立業務應用程式的低程式碼平台。 ---------------------------------------------------------------------- ![工具噴射器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xhipvjl2wnthjccgrpij.png) 我們都建立前端,但它通常非常複雜,並且涉及許多因素。這樣可以省去很多麻煩。 ToolJet 是一個開源低程式碼框架,可以用最少的工程工作來建置和部署內部工具。 ToolJet 的拖放式前端建構器可讓您在幾分鐘內建立複雜的響應式前端。 您可以整合各種資料來源,包括PostgreSQL、MongoDB、Elasticsearch等資料庫;具有 OpenAPI 規範和 OAuth2 支援的 API 端點; SaaS 工具,例如 Stripe、Slack、Google Sheets、Airtable 和 Notion;以及 S3、GCS 和 Minio 等物件儲存服務來取得和寫入資料。一切 :) 這就是 Tooljet 的工作原理。 ![工具噴射器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r6vv09z7ioma1ce2ttei.png) 您可以在 ToolJet 中開發多步驟工作流程以自動化業務流程。除了建置和自動化工作流程之外,ToolJet 還可以在您的應用程式中輕鬆整合這些工作流程。 ![工作流程](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eh2vk3kih9fhck6okf67.png) 您可以閱讀[文件](https://docs.tooljet.com/docs/)並查看[操作指南](https://docs.tooljet.com/docs/how-to/use-url-params-on-load)。 - 💰 獲得總融資 620 萬美元(GitHub 是其中一名投資者)。 - 🚀 使用的主要語言是 JavaScript。 Tooljet 在 GitHub 上擁有超過 27,800 顆星和 500 多名貢獻者。 https://github.com/ToolJet/ToolJet Star Tooljet ⭐️ --- 25. [Mattermost-](https://github.com/mattermost/mattermost)整個軟體開發生命週期的安全協作。 --------------------------------------------------------------------------- ![最重要的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43p8f052h71ryhavrkms.png) Mattermost 是一個開源平台,用於在整個軟體開發生命週期中進行安全協作。 該儲存庫是 Mattermost 平台上核心開發的主要來源;它是用 Go 和 React 編寫的,並作為單一 Linux 二進位與 MySQL 或 PostgreSQL 一起執行。每個月 16 日都會在 MIT 許可下發布新的編譯版本。 - 💰 獲得總資金 7350 萬美元。 - 🚀 使用的主要語言是 TypeScript。 Mattermost 在 GitHub 上擁有超過 28,400 顆星,有 600 多個活躍問題和 900 多個貢獻者。 https://github.com/mattermost/mattermost Star Mattermost ⭐️ --- 我很驚訝這麼多受資助的專案使用 TypeScript 而不是 JavaScript。你是? 如果您知道任何其他資助專案或希望我製作第二部分。 請在評論中告訴我您最喜歡的清單。 祝你有美好的一天!直到下一次。 您可以加入我的開發者和技術作家社區,網址為[dub.sh/opensouls](https://dub.sh/opensouls) 。 關注 Taipy 以了解更多此類內容。 嵌入 https://dev.to/taipy --- 原文出處:https://dev.to/taipy/25-funded-projects-you-can-contribute-in-open-source-40lh

你的 side project 無法賺錢的 5 個原因以及如何避免它們

介紹 -- ![](https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExcjA0MGM0NjN0YjR3aGRicHM3YzUyc254ZmxxNjkxdzlnZWZ0NHRjbCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ljtfkyTD3PIUZaKWRi/giphy.webp) 你好呀!如果您像許多有抱負的企業家(包括我)一樣,您可能已經有不少聰明的想法,但很難將它們轉化為有利可圖的副業專案。你不是一個人。許多副業專案都無法賺錢,了解原因是邁向成功的第一步。因此,讓我們深入探討個人創業家/獨立駭客之旅中的常見陷阱,並學習如何避免它們。 開始這段旅程時,重要的是要記住失敗不是敵人。事實上,這是這個過程的關鍵部分。是的,這是殘酷的事實:沒有人是第一次嘗試就成功的。 擁抱失敗並從中學習可以幫助我們避免在未來犯下同樣的錯誤。所以請繫好安全帶,因為我們即將探討業餘專案失敗的常見原因以及如何解決這些問題。 錯誤#1——沒有嘗試 ---------- ![來自levelsio的推文](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2bcwyxlln68kmzv853oc.png) 這是來自[@levelsio](https://twitter.com/levelsio)的一條推文,他是一位成功的個體企業家,每月收入超過 15 萬美元,這是一個值得一看的好例子。對失敗的恐懼常常阻礙我們踏出第一步。不要讓這種恐懼阻止你!**嘗試但失敗比根本不嘗試好。** 此外,請記住,完全不嘗試意味著您會錯過寶貴的經驗和成長機會。即使您的專案沒有盈利,您獲得的技能和經驗確實是重點。無論是提高您解決問題的能力,請多了解新市場,還是了解其動態,這些技能都對您未來的專案和麵試非常有益。 所以,下次當你有一個業餘專案的想法時,就去做吧!讓你的好奇心和熱情驅動你,不要讓失敗的恐懼阻礙你。一次又一次地失敗並從錯誤中學習——這是成長的最佳方式,如[@levelsio](https://twitter.com/levelsio)所示。 錯誤#2-失敗的創意 ---------- ![](https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExMzZ5ejdzZWFhbHl6anF1NXNtN2ZwdXJvbmE5NDBxdjZjY2J1Mm84cSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/PbzwVUojP4d8RcRgK0/giphy.webp) 你有這個想法。但它是透過有效的腦力激盪和解決問題形成的嗎?業餘專案的一個常見陷阱是倉促的構思過程。徹底的腦力激盪過程對於確保您的想法的可行性至關重要。 試著用你自己的視角來過濾掉那些與你沒有太多共同點的想法。問題對你來說越是原生,解決方案看起來就越明顯可行。 - 驗證你的想法:僅僅認為它是好的還不夠。您至少需要保證它有市場。進行調查,詢問您信任的人,並收集盡可能多的初始資料。 - 確保你的想法能夠解決問題:一個好的商業想法是能夠填補市場空白或解決人們遇到的問題的想法。 - 評估您的資源:您是否有技能、時間和金錢將您的想法轉化為業務?不要自欺欺人。永遠記住,你可以做一個 MVP(最小可行產品),但是,如果 MVP 不能為用戶帶來真正的價值,那麼它是不夠的。 想要一個例子嗎?查看對[amicus.work](https://www.amicus.work/)的建立者 Erlis 的[訪談](https://wasp-lang.dev/blog/2023/02/14/amicus-indiehacker-interview)。它準確地表明了接近問題如何使解決方案變得直觀。如果您發現自己陷入困境,您可以快速閱讀另一篇[文章](https://dev.to/llxd/creating-a-more-than-minor-side-project-from-planning-to-release-3be8),或者,如果您希望更深入地了解, [Make Book](https://makebook.io/)或[The Lean Startup](https://www.amazon.com/Lean-Startup-Entrepreneurs-Continuous-Innovation/dp/0307887898)也是很好的參考資料,因為它們提供了寶貴的見解,幫助您避免在創業過程中出現常見錯誤。 錯誤 #3 - 無限建置 ------------ ![](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNmoxdm1nN2I4dml0OXNibTg5a2N3bGxhbGprZG10eHR4MmllNzJ0dSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/UAHZijO91QCl2/200.webp) 現在,您的腦海中浮現出技術選擇,您實際上正在考慮學習一種全新的程式語言,只是為了解決這個新問題。來吧,你已經讀過一篇[關於學習的文章](https://dev.to/wasp/the-art-of-self-learning-how-to-teach-yourself-any-programming-concept-5de4)了!沒有什麼可以阻止你! 可是等等!想一想。現在你必須同時處理兩個問題: 1. 學習一門新語言, 2. **並為您的問題建立解決方案。** 將一個奇妙的想法變成一項蓬勃發展的業務已經足夠具有挑戰性了。而且您已經知道許多副專案**在建置階段**都會失敗,那麼為什麼要對自己這樣做呢? 這裡的秘密?創新,但要謹慎! 嘗試那些總是能讓你加速的事情,而不是給你帶來負擔和減慢你的速度的事情。一個例子?已經了解 React 了?嘗試[Wasp](https://wasp-lang.dev/) ,這是一個全端框架,它可以為您處理 Boilerplate(例如 Auth),並使用 AI 生成功能來幫助您更快地建立產品。 當嘗試建立和測試一個想法時,我們不會過度專注於學習新東西,而是**更專注於建立想法本身。**因此,在選擇工具時,請選擇基於您已知的技術並能幫助您快速前進的工具! --- 順便一提: [Wasp](https://wasp-lang.dev/)使本文成為可能,最近,我們發布了 Open SaaS — 一種出色的、100% 免費的開源方式,可用於快速啟動新的 SaaS。一探究竟! https://github.com/wasp-lang/open-saas ⭐️ 使用 Open SaaS 建立您的 SaaS 🙏 [![打開 SaaS 橫幅](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9t2q03c6a86dd4oi1xt.png)](https://opensaas.sh) --- 其他真正常見的錯誤是追求完美,這通常會導致無休止的調整和延誤。請記住,「完成比完美更好」。完成您的專案並將其推向世界至關重要。如果你的專案沒有人看到,那麼它只是一個想法。 錯誤#4 - 從未到達的回饋 -------------- 延誤並不是此階段的唯一障礙。有時,我們過於專注於創造完美的產品,以至於我們忘記了與實際用戶一起驗證它。定期回饋至關重要 - 它可以幫助您做出必要的更改並確保您的產品滿足用戶的需求。 沒有回饋,您永遠不會知道自己是否中了大獎,或者是否正在為無人解決的問題建立解決方案。 ![](https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExM294bHQyaGN3NHVsaWFncW1lNWc3aGIzaG50YWR3c3d2bThxMHdkNyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/4LsN0YwgIsvaU/giphy.webp) 那麼,如何確保獲得必要的回饋呢?首先與一小群用戶測試您的產品。這可以是一群朋友、家人,甚至是一個專門的焦點團體。他們的回饋對於辨識任何問題或需要改進的領域非常有價值。 我們也面臨著收到負面回饋的恐懼,這很常見,這通常會導致產品被拒絕進入市場,直到它「完美」為止。然而,這種方法可能是有害的。儘早發布您的產品至關重要,即使它缺少您計劃加入的一些很酷的功能。用戶的早期回饋可以引導您加入以前沒有想到的功能,但這是實際用戶想要的功能。 請記住,回饋是一份禮物。它可以讓您改進您的產品,使其成為人們不僅使用而且喜歡的東西。所以,不要迴避它,擁抱它! 錯誤#5——羞澀的發布 ----------- 並談論害羞:所以,你已經建立了它,現在怎麼辦?是時候向世界展示它了。然而,請記住,時機就是一切。如果你的發布是羞澀的、計劃不周的,你就不會獲得你需要的用戶(也不會是收入)。 第一步是了解您的受眾並選擇合適的平台。 [Reddit](https://www.reddit.com/)非常適合開源或主要不是由利潤驅動的專案,而[Dev Hunt](https://devhunt.org/) 、 [Product Hunt](https://www.producthunt.com/)和[Hacker News (YC) 則](https://news.ycombinator.com/)非常適合更廣泛的專案。選擇正確的啟動地點可能意味著企業與空無一物之間的差異。 此外,制定策略發布計劃至關重要。儘管有可能發生,但僅發布您的專案並希望獲得最好的結果是不夠的。您需要規劃您的發布,考慮合適的發佈時間、平台的習慣等因素,並調整與目標受眾的溝通。 深思熟慮的啟動計劃不僅可以幫助您吸引更廣泛的受眾,還可以增加專案成功的機會。您應該使用[Screen Studio](https://www.screen.studio/)和[Canva](https://canva.com)等工具來幫助您建立精美的螢幕錄製和宣傳圖像/橫幅。 作為獎勵,這裡有一個啟動計劃範例,可以幫助您入門: - 第一周:準備所有宣傳材料,例如圖像和影片 - 第 2 週:在[Dev Hunt](https://devhunt.org/)上啟動 + 在社群媒體上進行推廣 - 第 3 週:推出[Product Hunt](https://www.producthunt.com/) + [Show HN](https://news.ycombinator.com/show) - 第 4 週及以後:大聲點!繼續在 Reddit、HN 和其他社交媒體平台上進行推廣(不被禁止)。 ![](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNmFzZG14azQ1cjJrc25mY3hoNnk1aWI3bHpnNW45MHkxOWJ6ejd6ciZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/P0ZRTYaCmPsJPNd3r0/giphy.webp) 嘿,你在網路上,所以,儘管你可能會得到很好的回饋,但有些用戶只會對你進行人身攻擊。這很正常,所以不要理會那些生氣的人。如果你的想法被一些隨機的 Reddit 用戶消滅,這絕對不是一種很好的感覺,但時不時地,你實際上也會從誠實的用戶那裡得到一些很棒的見解。這並不容易,但試著辨識哪些回饋應該認真對待,哪些回饋應該忽略:) --- 尋找更多? ----- ![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExNWNraHJwazF1cGtxZWI5YmZmaXc1YzZwZms3djJ0eXY4NDhkMGZjZyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/IwAZ6dvvvaTtdI8SD5/giphy.gif) 對更多這樣的內容有興趣嗎?關注我們在[Wasp - DEV Community 的](https://dev.to/wasp)博客,並在 github 上給我們一個星星。這是支持我們的最簡單的方式! https://www.github.com/wasp-lang/wasp ⭐️ GitHub 上的 Star Wasp 🙏 --- 結論 -- 總之,將業餘專案轉變為成功的企業是一個充滿挑戰和勝利的旅程。一路走來,每一步,無論是坎坷或勝利,都是一次寶貴的學習和成長的機會。 每一次失敗都不是終點,而是邁向更大成功的墊腳石,是推動我們前進的教訓。每一次挫折都是重新評估、完善並變得更強大的機會。擁抱這個過程的迭代本質:繼續完善你的想法,堅持不懈地努力改進,最重要的是,永遠不要停止嘗試和學習。 --- 原文出處:https://dev.to/wasp/5-reasons-why-your-side-projects-fail-to-make-money-and-how-to-avoid-them-4l5m

🙅 為什麼我不使用 AI 作為我的副駕駛 🤖

\*\*耶穌,掌管方向盤。 🚗 還有 Github Copilot,使用 IDE。 💻\*\* **[Github 表示](https://github.blog/2023-06-13-survey-reveals-ais-impact-on-the-developer-experience/)**,92% 的美國開發者都在使用 Copilot。 什麼。嚴重地? 什麼時候聽過 92% 的人口使用單一事物? 當然,除非…你說全世界**100%**的人都消耗過一氧化二氫。 *(這條線只有一種變黑的方式。不要去那裡。👀)* 和我一起快速旅行,我將談論: - [我真正擔心的是什麼。](#what-im-actually-worried-about) - [其他經驗豐富的開發人員對此有何看法?](#from-the-experienced-devs-point-of-view) - [也許我什麼都不擔心?](#lets-take-a-step-back-for-a-moment) - [以及我們如何對我們如何使用LLMs負責!](#where-the-heck-does-llmai-fit-in) ### 🔥 當機器在 2024 年佔領世界時 經過谷歌快速搜尋後,似乎大多數開發人員都在使用人工智慧輔助來編寫程式碼。如果我說我根本沒有使用人工智慧來編寫程式碼,**那我就是在撒謊**。當然,我有。我並不住在岩石下。 我發現開發人員對與第三方雲端服務共享程式碼相關資料的想法感到奇怪,這些第三方雲端服務通常沒有 SOC2(或類似的東西)認證,並且充其量只能做出模糊且無法證明的隱私聲明。 Github Copilot(和 Copilot 聊天)、Bito.ai 以及 VS Code 市場上的其他幾個 AI 程式碼擴充的安裝量已超過 3000 萬。瘋狂的! 🤯 然後是我。**我還沒有將人工智慧輔助**納入我的常規程式碼工作流程中。當然,我有幾次在 GPT 的幫助下編寫了一些樣板檔案。但那些時候是個例外。像 Github Copilot 這樣的東西,或任何類型的程式碼審查、程式碼產生工具、PR 建立或提交協助,都不屬於我的 IDE 或 CLI 流程的一部分。 也許它會隨著時間而改變。我們拭目以待。 > ## “但為什麼?” ![但為什麼](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bpc1fc4t5a10j0i5r3wj.gif) ### 😟我真正擔心的是 答案很簡單。 👇 #### 1.我擔心我的程式設計技能會生疏 我擔心如果我太習慣人工智慧的幫助,我編寫和閱讀程式碼的方式將會受到影響。 - 我擔心我會開始**忽略**程式碼中的缺陷,否則我可以發現這些缺陷。 - 我將開始認為人工智慧產生的程式碼是**理所當然的**。 - 尋找 API、內建方法或其他文件將開始變得像一件**苦差事**。 我擔心……我會開始滑倒。 #### 2. 我不願意與第三方服務分享我的所有程式碼 公司可以非常聰明地從你提供的資料中推斷出一些事情。有時他們會知道[你的家人不知道的](https://www.forbes.com/sites/kashmirhill/2012/02/16/how-target-figured-out-a-teen-girl-was-pregnant-before-her-father-did/)事。 敏感的業務邏輯可能會洩漏給第三方服務,最終可能會被用來做出我不滿意的推論,或者只是…直接洩漏?我的意思是,軟體總是被駭客攻擊。 我認為我很合理地認為我不想以不受限制的方式向第三方公司公開像程式碼這樣敏感的東西。即使那家公司是微軟,[因為即使他們也搞砸了](https://www.wired.com/story/total-recall-windows-recall-ai/)。 ### 👀 從經驗豐富的開發人員的角度來看 這也不是我獨有的想法! #### 1. 經驗豐富的開發人員往往**不想依賴**「拐杖」來寫程式碼。 我甚至很高興與不想在 IDE 上使用彩色主題的高級開發人員合作,因為他們認為這會損害他們掃描、閱讀或偵錯程式碼的能力! (這對我來說也有點太多了) 畢竟,「程式設計技能」**不僅僅是編寫程式碼**。 #### 2. 老開發者看過各種**軟體被駭**、資料外洩等。 我的意思是,十多年來, [haveibeenpwned.com](https://haveibeenpwned.com/)每年都會向您發送有關您的憑證、電子郵件和其他資料外洩的電子郵件…很多時候來自[價值數十億](https://en.wikipedia.org/wiki/2017_Equifax_data_breach)[美元的](https://www.news18.com/india/indias-biggest-data-leak-so-far-covid-19-test-info-of-81-5cr-citizens-with-icmr-up-for-sale-exclusive-8637743.html)[公司](https://www.nytimes.com/2017/10/03/technology/yahoo-hack-3-billion-users.html)… 當你無數次聽到**「當你不為產品付費時,你就是產品」** ,然後又得到另一家將資料出售給第三方的公司的支持... 是啊……會很累。 只需斷開盡可能多的電線即可輕鬆回到石器時代。 > ![老馬特達蒙](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/03pmbpqix6e199ewey5t.gif) > “老開發人員”?我是……我變老了嗎? > 不,我才 22 歲,現在已經是 2016 年了……對吧?正確的? **順便說一句,標題中問題的答案是👆這個。**恭喜!貼文結束了!轉到下一個… Buuuuut…如果你想繼續閱讀… ![喬伊還有更多](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jk0ywd7yjqukeokd0t2d.gif) ### 🚶 讓我們退後一步...... #### 我認為我的擔心可能被誇大了。 > *現在讓我們把整個資料隱私的角度放在一邊,因為這本身就是一個我非常熱衷的另一個主題。* 我個人沒有足夠的資料來經驗說使用人工智慧輔助會帶來我擔心的厄運……它會將我從今天的樣子降級為[SDE1](https://dev.to/middleware/going-from-sde1-to-sde2-and-beyond-what-it-actually-takes-1cld) 。 但我已經看到了模式。 - 我見過人工智慧生成的低於標準品質的程式碼經過程式碼審查並最終出現在`main`分支上。 - 我見過一些函式庫函數在沒有正確理解存在什麼或存在什麼替代方案的情況下被使用,只是因為LLMs產生了它。 - 我什至見過為解決某個問題而生成的程式碼,對於該問題,程式碼庫中已經存在一個實用程式函數,但沒有使用它,因為知道這個實用程式的存在比要求GPT 為您生成它要多得多的工作。 ### 💎 ~~鑽石是~~ 糟糕的程式碼是永遠的 **“等一下……我以前看過這部電影!”** ![似曾相識](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvun4635neb2dflv5yto.gif) - LLM 是一個相當新的事物…但是💩程式碼是**永恆的!** - 每一個。單身的。開發。曾經。在沒有完全**理解**或尋找替代方案的情況下使用了函式庫函數。你和我都對此有罪。 (什麼?您認為`Array.prototype.sort`是對任何內容進行排序的最佳方式?在大多數情況下它就足夠了!) - 一段邏輯總是被重新發明(重新複製貼上)!只是之前它來自**StackOverflow** ,現在它來自 ChatGPT 。 ### 🤷 那麼,有什麼好大驚小怪的呢? > “使用 ChatGPT 會讓我成為一個糟糕的程式設計師嗎?” 我想不是。 重點是您只需要關心您建立的內容。 為您所**建造的**東西感到**自豪**。 ### 🤖 LLM/AI 到底適合什麼? **LLM 本身並不是邪惡的。** 事實上,如果負責任地使用它們,它們會非常有用: - **品質程式碼:**LLMs可能會處理不太勤奮的開發人員不會考慮的邊緣情況。 - **綜合測試:**LLMs可能會編寫比某些開發人員編寫的測試更全面的測試。 - **綜合類型:**它甚至可能比普通開發人員自己編寫的類型或可能具有編寫技能的類型更「完整」地編寫類型。 然而,開發人員有責任確保程式碼輸出受到保護和良好監控。一個不在乎的人在歷史上的任何時候都會做得很糟糕。LLMs的存在並沒有改變這一點。 ### 😎 真正給予 a\*ck 的藝術 有很多開發者對此並不關心。 但你不是這樣的開發者。**你確實關心。** 否則你就不會在這裡開發並學習人們的經驗。 我最近寫了一篇關於新開發人員在職涯中應該關心什麼成長的文章。它不僅僅是程式碼。 https://dev.to/middleware/going-from-sde1-to-sde2-and-beyond-what-it-actually-takes-1cld **也許我會在 VSCode 中引入一些 AI。** 我認為這只是時間問題,而不是**是否有問題**。 更重要的是……只要我關心確保我的程式輸出**可讀、高效能、高品質且易於審查**,我想我會沒事的,你也一樣。 --- ### 👇 PS 如果您想要一個我非常關心的範例,並且具有出色的程式碼 💪 和…不太出色的程式碼 🤣,請查看我們的**開源**儲存庫! 它可以讓您了解交付程式碼需要多長時間、PR 陷入審查循環的次數以及您的團隊交付程式碼的整體情況。 https://github.com/middlewarehq/middleware --- 原文出處:https://dev.to/middleware/why-i-dont-use-ai-as-my-copilot-47k3

2024 年您需要了解的免費 API

API(應用程式介面)是開發人員必不可少的工具,使他們能夠將第三方服務整合到他們的應用程式中。以下是 2024 年跨不同類別的免費 API 的詳細列表,以及每個 API 的網站連結、描述和範例程式碼。 遊戲 API ------ ### Steam 社群 API - **網址**: [steamcommunity.com/dev](https://steamcommunity.com/dev) - **描述**:Steamworks Web API 提供了各種 Steam 功能的接口,例如使用者驗證、庫存管理和遊戲資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const steamApiKey = 'YOUR_STEAM_API_KEY'; const steamId = 'STEAM_USER_ID'; const url = `http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${steamApiKey}&steamids=${steamId}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### Riot 遊戲 API - **網址**: [developer.riotgames.com](https://developer.riotgames.com) - **描述**:存取《英雄聯盟》、《雲頂之弈》、《Valorant》等遊戲的資料。提供比賽、排名、冠軍和其他遊戲相關統計資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const riotApiKey = 'YOUR_RIOT_API_KEY'; const summonerName = 'SUMMONER_NAME'; const url = `https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/${summonerName}?api_key=${riotApiKey}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 語言API ----- ### 邪惡侮辱生成器 API - **網址**: [evilinsult.com/api](https://evilinsult.com/api) - **描述**:出於娛樂或測試目的,以各種語言產生隨機侮辱。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://evilinsult.com/generate_insult.php?lang=en&type=json'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 趣味翻譯 API - **網址**: [funtranslations.com/api](https://funtranslations.com/api) - **描述**:將文字翻譯成各種有趣的語言,如尤達語言、莎士比亞語言、小小兵語言等等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const text = 'Hello, world!'; const url = `https://api.funtranslations.com/translate/yoda.json?text=${encodeURIComponent(text)}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 音樂 API ------ ### Spotify 網路 API - **網址**: [developer.spotify.com/documentation/web-api](https://developer.spotify.com/documentation/web-api) - **描述**:存取音樂資料,例如專輯、藝術家、播放清單和用戶資料。控制 Spotify 播放等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const accessToken = 'YOUR_SPOTIFY_ACCESS_TOKEN'; const url = 'https://api.spotify.com/v1/me/player/recently-played'; fetch(url, { headers: { 'Authorization': `Bearer ${accessToken}` } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 安全API ----- ### 我被偷了嗎 API - **網址**: [haveibeenpwned.com/API/v2](https://haveibeenpwned.com/API/v2) - **描述**:檢查您的電子郵件或使用者名稱是否屬於資料外洩的一部分。提供有關違規、貼上和密碼洩露的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const email = '[email protected]'; const url = `https://haveibeenpwned.com/api/v2/breachedaccount/${email}`; fetch(url, { headers: { 'User-Agent': 'Node.js' } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 首丹API - **網址**: [developer.shodan.io](https://developer.shodan.io) - **描述**:Shodan 是一個針對網路連線裝置的搜尋引擎。它提供全球各種伺服器、設備和系統的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const shodanApiKey = 'YOUR_SHODAN_API_KEY'; const query = 'apache'; const url = `https://api.shodan.io/shodan/host/search?key=${shodanApiKey}&query=${query}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 科學與數學 API --------- ### 美國太空總署火災 - **網址**: [api.nasa.gov](https://api.nasa.gov) - **描述**:存取 NASA 資料集中的資料,包括天文照片、行星資料等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const nasaApiKey = 'YOUR_NASA_API_KEY'; const url = `https://api.nasa.gov/planetary/apod?api_key=${nasaApiKey}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### Wolfram Alpha API - **網址**: [products.wolframalpha.com/api](https://products.wolframalpha.com/api) - **描述**:提供對 Wolfram Alpha 的大量計算知識的存取,包括數學計算、資料分析等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const wolframAppId = 'YOUR_WOLFRAM_APP_ID'; const query = 'integrate x^2'; const url = `http://api.wolframalpha.com/v2/query?input=${encodeURIComponent(query)}&appid=${wolframAppId}&output=json`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 開放科學框架 API - **網址**: [developer.osf.io](https://developer.osf.io) - **描述**:從開放科學框架存取研究資料、專案管理工具和其他科學資源。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api.osf.io/v2/nodes/'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 體育 API ------ ### NBA應用程式介面 - **網址**: [any-api.com/nba\_com/nba\_com/docs/API\_Description](https://any-api.com/nba_com/nba_com/docs/API_Description) - **描述**:存取 NBA 球隊、球員和比賽的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api-nba-v1.p.rapidapi.com/teams/league/standard'; const options = { method: 'GET', headers: { 'X-RapidAPI-Key': 'YOUR_RAPIDAPI_KEY', 'X-RapidAPI-Host': 'api-nba-v1.p.rapidapi.com' } }; fetch(url, options) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 網路應用 API -------- ### Discord API - **網址**: [discord.com/developers/docs/intro](https://discord.com/developers/docs/intro) - **描述**:將您的應用程式與 Discord 集成,允許用戶身份驗證、訊息傳遞等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const discordToken = 'YOUR_DISCORD_BOT_TOKEN'; const url = 'https://discord.com/api/users/@me'; fetch(url, { headers: { 'Authorization': `Bot ${discordToken}` } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### Slack API - **網址**: [api.slack.com](https://api.slack.com) - **描述**:存取 Slack 功能,例如訊息傳遞、使用者資料和工作區管理。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const slackToken = 'YOUR_SLACK_API_TOKEN'; const url = 'https://slack.com/api/conversations.list'; fetch(url, { headers: { 'Authorization': `Bearer ${slackToken}` } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 產品和事物 API --------- ### 汽車查詢API - **網址**: [carqueryapi.com](https://carqueryapi.com) - **描述**:存取汽車資料,包括 品牌、型號和年份資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://www.carqueryapi.com/api/0.3/?cmd=getMakes'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### Yelp API - **網址**: [yelp.com/developers](https://yelp.com/developers) - **描述**:存取本地企業的資料,包括評論、評級和企業詳細資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const yelpApiKey = 'YOUR_YELP_API_KEY'; const url = 'https://api.yelp.com/v3/businesses/search?location=San Francisco'; fetch(url, { headers: { 'Authorization': `Bearer ${yelpApiKey}` } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 健康API ----- ### 醫療保健.gov API - **網址**: [healthcare.gov/developers](https://healthcare.gov/developers) - **描述**:存取醫療保健計劃、提供者目錄和其他健康相關資訊的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://data.healthcare.gov/resource/xyz123.json'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 政府和地理 API --------- ### 程式碼.gov API - **網址**: [code.gov](https://code.gov) - **描述**:存取聯邦政府軟體專案的資料,包括程式碼儲存庫和專案詳細資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api.code.gov/projects'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 資料政府API - **網址**: [data.gov/developers/apis](https://data.gov/developers/apis) - **描述**:存取美國政府提供的各種資料集,包括天氣、教育和健康資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api.data.gov/ed/collegescorecard/v1/schools.json?api_key=YOUR_DATA_GOV_API_KEY'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 資料.europa.eu API - **網址**: [data.europa.eu/en](https://data.europa.eu/en) - **描述**:存取歐盟機構和團體的開放資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://data.europa.eu/api/hub/search/datasets'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 傳輸定位API - **網址**: [rapidapi.com/transloc/api/openapi-1-2/details](https://rapidapi.com/transloc/api/openapi-1-2/details) - **描述**:存取即時公共交通資料,包括到達預測、車輛位置等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const translocApiKey = 'YOUR_TRANSLOC_API_KEY'; const url = 'https://transloc-api-1-2.p.rapidapi.com/agencies.json'; fetch(url, { headers: { 'X-RapidAPI-Key': translocApiKey, 'X-RapidAPI-Host': 'transloc-api-1-2.p.rapidapi.com' } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 食品原料藥 ----- ### 開放食品事實 API - **網址**: [world.openfoodfacts.org/data](https://world.openfoodfacts.org/data) - **描述**:存取全球食品資料,包括成分、營養成分和過敏原資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://world.openfoodfacts.org/api/v0/product/737628064502.json'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 塔克花式 API - **網址**: [github.com/evz/tacofancy-api](https://github.com/evz/tacofancy-api) - **描述**:存取玉米捲食譜資料,包括成分和製備方法。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'http://taco-randomizer.herokuapp.com/random/'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 開源專案 API -------- ### 圖書館.io API - **網址**: [libraries.io/api](https://libraries.io/api) - **描述**:存取開源專案的資料,包括相依性資訊、版本歷史記錄等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const librariesApiKey = 'YOUR_LIBRARIES_IO_API_KEY'; const url = `https://libraries.io/api/platforms?api_key=${librariesApiKey}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 電影和漫畫 API --------- ### 查克諾里斯笑話 API - **網址**: [api.chucknorris.io](https://api.chucknorris.io) - **描述**:參觀查克諾里斯笑話集。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://api.chucknorris.io/jokes/random'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 最終空間 API - **網址**: [finalspaceapi.com](https://finalspaceapi.com) - **描述**:存取《最終太空》電視節目的資料,包括角色、劇集等。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://finalspaceapi.com/api/v0/character'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 木津API - **網址**: [kitsu.docs.apiary.io](https://kitsu.docs.apiary.io) - **描述**:存取動漫和漫畫的資料,包括系列資訊、評論和用戶評分。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://kitsu.io/api/edge/anime'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 漫威API - **網址**: [developer.marvel.com](https://developer.marvel.com) - **描述**:存取有關 Marvel 漫畫、角色和創作者的資料。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const marvelPublicKey = 'YOUR_MARVEL_PUBLIC_KEY'; const marvelPrivateKey = 'YOUR_MARVEL_PRIVATE_KEY'; const ts = new Date().getTime(); const hash = require('crypto').createHash('md5').update(ts + marvelPrivateKey + marvelPublicKey).digest('hex'); const url = `https://gateway.marvel.com/v1/public/characters?ts=${ts}&apikey=${marvelPublicKey}&hash=${hash}`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 戳API - **網址**: [pokeapi.co](https://pokeapi.co) - **描述**:存取神奇寶貝的資料,包括物種、能力和遊戲資訊。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://pokeapi.co/api/v2/pokemon/ditto'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 瑞克和莫蒂 API - **網址**: [rickandmortyapi.com](https://rickandmortyapi.com) - **描述**:存取瑞克和莫蒂電視節目的資料,包括角色、劇集和地點。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://rickandmortyapi.com/api/character'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 辛普森一家行情 API - **網址**: [thesimpsonsquoteapi.glitch.me](https://thesimpsonsquoteapi.glitch.me) - **描述**:造訪《辛普森家庭》電視節目中的台詞集。 #### 樣本 程式碼 ``` const fetch = require('node-fetch'); const url = 'https://thesimpsonsquoteapi.glitch.me/quotes'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 星際大戰 API - **網站**: [swapi.tech](https://swapi.tech) - **描述**:存取星際大戰宇宙的資料,包括電影、角色、星際飛船和行星。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const url = 'https://swapi.tech/api/people/1'; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` ### 超級英雄API - **網址**: [superheroapi.com](https://superheroapi.com) - **描述**:存取各種超級英雄的資料,包括他們的力量、傳記和圖像。 #### 範例程式碼 ``` const fetch = require('node-fetch'); const superheroApiKey = 'YOUR_SUPERHERO_API_KEY'; const url = `https://superheroapi.com/api/${superheroApiKey}/1`; fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` 結論 -- 這份 2024 年免費 API 的完整清單涵蓋了廣泛的類別,為開發人員提供了大量機會,透過強大且多樣化的功能來增強其應用程式。從遊戲和音樂到科學和政府資料,這些 API 為建立創新且引人入勝的專案提供了寶貴的資源。 請隨意探索這些 API 並將它們整合到您的專案中,以解鎖新的可能性和功能。快樂編碼! --- 原文出處:https://dev.to/dk119819/free-apis-you-need-to-know-about-in-2024-2ieg

使用 Gemini AI + ToolJet 建置 SQL 報表產生器

介紹 -- 本教學將引導您完成使用[ToolJet](https://github.com/ToolJet/ToolJet) (一種低程式碼視覺化應用程式產生器)和 Gemini API(一種強大的自然語言處理 API)建立 AI 驅動的 SQL 自訂報告產生器的過程。由此產生的應用程式將使用戶能夠以簡單的英語輸入請求,然後將其翻譯成自訂報告。我們將使用 ToolJet 的視覺化應用程式建構器來建立使用者友善的 UI,並使用 ToolJet 的低程式碼查詢建構器將其連接到 Gemini API 端點和我們的資料來源。最終產品將使用戶能夠預覽生成的報告並以 PDF、Excel 或 CSV 格式下載。 --- 先決條件: ----- - **ToolJet** (https://github.com/ToolJet/ToolJet):一個開源、低程式碼的商業應用程式建構器。[註冊](https://www.tooljet.com/signup)免費的 ToolJet 雲端帳號或使用 Docker[在本機上執行 ToolJet](https://docs.tooljet.com/docs/setup/try-tooljet/) 。 - **Gemini API 金鑰**:使用您現有的 Google 憑證登入[Google AI Studio](https://aistudio.google.com/app/apikey) 。在 AI Studio 介面中,您可以找到並複製您的 API 金鑰。 以下是我們最終應用程式的快速預覽: ![SQL 報表產生器預覽](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xb7brsesfnu9t6ny61h1.png) --- 登入您的[ToolJet 帳號](https://app.tooljet.com/)。導覽至 ToolJet 儀表板,然後按一下左上角的「建立新應用程式」按鈕。 ToolJet 隨附 45 多個內建元件。這將讓我們立即設定我們的用戶界面。 建立我們的使用者介面 ---------- - 將右側元件庫中的**Container**元件拖曳到畫布上。適當調整**Container**元件的高度和寬度。 - 同樣,將**圖示**和三個**文字**元件拖曳到容器內。我們將使用這些**文字**元件作為標題和標籤文字。 - 對於**「圖示」**元件,導航到右側的屬性面板,然後在**「圖示」**屬性下選擇適當的圖示。 - 根據您的喜好變更**圖示**和**文字**元件的顏色。 - 適當地變更**文字**元件的字體大小和內容。 - 將**Textarea**元件拖曳到容器內。我們將使用此元件作為文字查詢的輸入。 - 將**Textarea**元件重新命名為*textPrompt* 。 - 接下來,將**表格**元件拖曳到容器上。我們將使用此元件來顯示報告的預覽。**表**元件內建了下載顯示資料的功能。這將使我們能夠下載產生的 PDF、Excel 或 CSV 格式的報告。 - 現在讓我們新增一個啟動報告產生過程的**Button**元件。適當改變顏色、大小和內容。 ![SQL 報表產生器 UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5b1r1pifxlt1kj74xe0e.png) --- 設定查詢 ---- 除了內建的資料庫和資料來源之外,ToolJet 還允許您連接到各種外部資料來源,包括資料庫、外部 API 和服務。在本教程中,我們將使用 ToolJet 的內建 PostgreSQL 範例資料來源。我們將設定的查詢也適用於外部 PostgreSQL 資料來源。 我們也將使用 REST API 查詢功能來連接**Gemini** API 端點。 - 在查詢面板中,按一下 + 新增按鈕並選擇範例資料來源選項。 - 將查詢重新命名為 getDatabaseSchema。 - 在下拉清單中,選擇 SQL 模式並輸入以下程式碼。這將獲取資料庫中的所有表名及其列名。 ``` SELECT table_name, string_agg(column_name, ', ') AS columns FROM information_schema.columns WHERE table_schema = 'public' GROUP BY table_name ``` - 若要確保每次載入應用程式時都執行查詢,請啟用**“在應用程式載入時執行此查詢?”**切換。 現在,讓我們建立另一個查詢,該查詢將連接到 Gemini AI API 並產生自訂 SQL 報表查詢。 - 使用 ToolJet 的[工作空間常數](https://docs.tooljet.com/docs/org-management/workspaces/workspace_constants/)功能,使用您的 Gemini API 金鑰建立一個名為**GEMINI\_API\_KEY 的**新常數。 - 在查詢面板中,按一下**+ 新增**按鈕並選擇**REST API**選項。 - 將查詢重新命名為*getSqlQuery* 。 - 在請求參數中,從下拉清單中選擇 POST 作為方法,然後貼上以下 URL。 ``` https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent?key={{constants.GEMINI_API_KEY}} ``` - 導航到*getSqlQuery*的 Body 部分。切換到原始 JSON 並輸入以下程式碼: ``` {{ `{ "contents": [{ "parts": [{ "text": "Data Schema: ${JSON.stringify(queries.getTablesWithColumns.data.map(item => ({ ...item, table_name: "public." + item.table_name }))).replace(/"([^"]+)":/g, '$1:').replace(/"/g, '\\"')}, Text Prompt: Write a standard SQL query for a custom SQL report that will ${components.textPrompt.value.replaceAll("\n"," ")}. Return without formatting and without any code highlighting and any backticks" },], },], }` }} ``` 讓我們新增最終查詢,該查詢將從自訂報表所需的範例資料來源中檢索資料。 - 同樣,建立另一個**Sample 資料來源**查詢,將其重新命名為*getReportData*並輸入以下程式碼: ``` {{queries.getSqlQuery.data.candidates[0].content.parts[0].text}} ``` --- 將查詢綁定到 UI 元件 ------------ 現在我們已經成功建立了 UI 和查詢,下一步就是整合它們。 - 選擇**Button**元件並導航到右側的屬性面板。點選**“+ 新事件處理程序”**按鈕。將**操作**變更為**執行查詢**並選擇*getSqlQuery*查詢。 - 接下來,導覽至*getSqlQuery*查詢並點擊**+ New event handler**按鈕。將**操作**變更為**執行查詢**並選擇*getReportData*查詢。 - 接下來,選擇**表格**元件。在右側的屬性面板中,在資料欄位中輸入以下程式碼。 ``` {{queries.getReportData.data}} ``` 我們已經成功地將查詢整合到我們的 UI 中。現在讓我們使用以下提示來測試應用程式: *列出客戶姓名以及他們訂購的產品,包括訂購日期和每種產品的訂購總數。* ![SQL 報表範例](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pbdvss1cd8b7mjucowym.png) 您可以點選**表格**頁腳上的**+**按鈕下載 PDF、Excel 或 CSV 格式的報表。 --- 結論 -- 恭喜您使用 ToolJet 和 Gemini API 成功建置了人工智慧驅動的 SQL 報表產生器。現在您可以用簡單的英文輸入提示並跨 PostgreSQL 實例中的多個表產生報表。 要了解和探索有關 ToolJet 的更多訊息,請查看[ToolJet 文件](https://docs.tooljet.com/docs/)或聯絡我們並在[Slack](https://join.slack.com/t/tooljet/shared_invite/zt-2ij7t3rzo-qV7WTUTyDVQkwVxTlpxQqw)上發布您的問題。 --- 原文出處:https://dev.to/tooljet/building-a-sql-report-generator-using-gemini-ai-tooljet-424p

少寫,永不修復:高度可靠程式碼的藝術

![被燒壞的工程師](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aygtgwad96xzq2pr944q.gif) 如果您是開發人員,不知疲倦地推出新的更改,卻被過去工作中的錯誤拖了回來,那麼這篇文章對您來說非常重要。 在過去的十年裡,在軟體開發中,我犯過並且看到其他人反覆犯過的關鍵錯誤之一是專注於做更多的工作,而不是確保完成的工作(無論多小)是穩健的並且將繼續正常工作。這些重複出現的錯誤會嚴重影響生產力和積極性。 從我自己的錯誤中,我學到了寶貴的教訓。在這裡,我想分享一些策略,它們不僅可以幫助您**交付強大的軟體**,還可以**讓您擺脫過去工作的束縛**。 ![告訴我更多](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a85h4md8p9xwd1ooq7zc.gif) 我們將討論對我最有效的 5 個策略: 1. [計劃 10 倍](#1-plan-for-10x) 2. [附註:您的舊工作出現錯誤,正在召回您](#2-psst-your-old-work-got-a-bug-and-is-calling-you-back) 3. [讓系統為您服務,而不是相反](#3-make-the-systems-work-for-you-not-the-other-way-around) 4. [始終用連結回答](#4-always-answer-with-a-link) 5. [了解軟體建置是一項團隊運動](#5-understand-software-building-is-a-team-sport)。 1. 10 次計劃 --------- 恕我直言,工程師有兩種:為今天而奮鬥的工程師和為遙遠的未來而設計的工程師。這兩種方法本身都不可持續。 您的程式碼應該能夠應對您的業務即將經歷的成長。然而,針對未來挑戰的過度設計可能會導致不必要的複雜性。有一個專門的術語 -[自行車脫落](https://thedecisionlab.com/biases/bikeshedding) ![擴大](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/edi9uv0o8bxjg58qr0wm.gif) 這是我的實用經驗法則:規劃目前規模的 10 倍,或考慮您的業務在未來 2-3 年內預計會成長多少。確保您的計劃與您的業務目標保持一致。 例如,如果您是一家設計預訂模組的計程車公司,現在您的公司每天處理 10,000 次乘車,並預計在 2 年內達到每天 100,000 次乘車,請以此作為基準。當您只進行 10,000 次騎行時,設計一個每天可進行 1000 萬次騎行的系統可能會導致解決方案過於複雜和昂貴。 2. 噓:您的舊工作出現了錯誤,正在召回您 --------------------- ![系統損壞](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/csf7rulcx55smffdqyyi.gif) 「幾天甚至幾週的除錯可以節省你編寫測試的幾個小時」——明智的人。 在不測試所有邊緣情況的情況下發布程式碼就像噴霧和祈禱策略。確保程式碼按預期工作的最簡單方法是新增單元測試。這聽起來似乎是顯而易見的,但徹底測試的重要性怎麼強調也不為過。 單元測試不僅充當針對明顯錯誤的第一道防線,而且還可以作為程式碼的保險,防止可能違反業務需求的意外更改。因此,減少每個衝刺分配給您的臨時錯誤 😉 **懶人(像我)的一個技巧**:在寫程式之前: - 編寫涵蓋您能想到的每個極端情況的測試。 - 假裝你正試圖破壞別人的系統。 - 在所有測試中編寫斷言 False 並執行它們。 - 當然,所有測試都會失敗。 現在,只需努力讓每個測試通過即可。這種方法總體上花費的時間較少,每次都會產生健壯的程式碼! 3. 讓系統為你服務,而不是相反 ---------------- ![監控系統](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8teb74yr1dgfq2tpolxf.gif) 我的一位經理曾經給了我最有影響力的建議:“採取行動,不要做出反應。”當我不斷在不同的 Slack 頻道上因問題、客戶投訴和付款失敗而被標記時,我提出了這個建議。我只是對每個請求做出反應,不知道接下來會發生什麼。 從那時起,我開始對我建造的每個功能提出三個問題: - 我怎麼知道它正在工作? - 我怎麼知道它失敗了? - 我怎麼知道它成功了? 然後,我透過將指標傳送到我們的 APM 工具(例如 Datadog 或 NewRelic)來回答各個層級(功能、螢幕、應用程式)的這些問題。 ![APM樣本](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8werj18bl8p6zhwc61d.png) 設定完畢後,我配置了警報,以便在出現任何問題時通知我。 透過這樣做,我在錯誤升級為重大問題之前就意識到了它們,從而防止了反應性措施、糟糕的客戶體驗以及我自己對接下來可能發生的事情的不確定性。 每次建造一些東西時,就開始回答這三個基本問題,以確保您始終採取行動而不是做出反應。 4. 總是用連結來回答 ----------- ![回覆文件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8utxvlj2pt1ojjq7kk8.gif) 就像糟糕的工作會讓你在各種 Slack 頻道上進行修復一樣,出色的工作會讓你在你所從事的領域中被貼上上下文標籤。 這可能會在你最意想不到的時候耗盡你的精力,或者更糟的是,它可能會讓你成為執行相同任務的首選人選,因為你了解完整的情況。 **請保留這個秘密技巧:** 記錄一切。包括您在建立功能時所做的上下文、架構和特定於業務的決策。當有人詢問某個區域的上下文(功能、螢幕、應用程式)時,只需向他們發送更新文件的連結即可。這每次都會為您節省幾個小時。 此外,完整的文件使新團隊成員的入職變得更加容易,並確保您的工作隨著時間的推移仍然可以存取和理解。 5. 了解軟體建置是一項團隊運動。 ----------------- ![特德·拉索欣賞](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/witndxix4fs05xy3fjie.gif) 軟體工程通常強調個人貢獻者路徑。然而,單獨實現最終目標是不可能的——你只能與你的團隊一起實現它(反之亦然)。 理解並採用流程卓越的思維方式可以幫助您充分利用團隊的集體生產力。 ![使困惑](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwk1ubf1tcuq8wio2v7x.gif) 對於這樣的措詞表示抱歉😄 簡而言之,確保審查、部署和任何涉及程式碼的協作活動不會有很長的等待時間,這可以大大提高您的工作效率! 辨識團隊中長時間等待或阻塞時間的最佳方法是衡量 DORA 指標。您可以使用像[Middleware](https://github.com/middlewarehq/middleware)這樣的開源工具,它提供開箱即用的[DORA 指標](https://www.middlewarehq.com/blog/what-are-dora-metrics-how-they-can-help-your-software-delivery-process)。 {% 嵌入 https://github.com/middlewarehq/middleware %} PS:我也是[Middleware](https://middlewarehq.com)的共同創辦人,我們的使命是讓工程師的工程變得順暢。如果您喜歡我們所建造的內容,請考慮給我們一顆星星! 像老闆一樣發布程式碼! ----------- ![老闆人](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2qrf8s8gmb9cx5f8b6f.gif) 透過採用這些建議,您可以大幅減少重新審視和修復過去工作所花費的時間。這不僅可以提高您的工作效率,還可以確保您始終專注於創新和提供新功能。 保持高效,而不是忙碌!祝一切順利😊 --- 原文出處:https://dev.to/middleware/write-less-fix-never-the-art-of-highly-reliable-code-5a0i

使用 Gemini API 和 ToolJet 在 10 分鐘內建立人工智慧商業提案編寫器 🚀

在本教學中,我們將引導您完成使用 ToolJet 和 Gemini API 建立 AI 商業提案編寫器的流程。我們將利用 ToolJet 的預先建置元件和簡單的整合流程來快速建立一個可以與 Gemini API 互動的應用程式。該應用程式將允許用戶輸入業務詳細資訊並產生專業的業務提案。 以下是最終應用程式的預覽: ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rghughfkz183bzjtqpou.png) ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewcpalt0obyfkvdh68xr.png) --- 先決條件 ---- **Gemini API 金鑰**:Gemini API 是[Google AI Studio](https://aistudio.google.com/app/apikey)提供的進階 AI 服務。它使開發人員能夠將強大的內容生成功能整合到他們的應用程式中。 **ToolJet** (https://github.com/ToolJet/ToolJet):一個開源、低程式碼的商業應用程式建構器。[註冊](https://www.tooljet.com/signup)免費的 ToolJet 雲端帳號或使用 Docker[在本機上執行 ToolJet](https://docs.tooljet.com/docs/setup/try-tooljet/) 。 首先建立一個名為*Business Proposal Writer 的*應用程式。 --- 1. 建立一個新應用程式 ------------ - 打開 ToolJet 並點擊**“建立新應用程式”** 。 - 將您的應用程式命名為*Business Proposal Writer* 。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5faoqkb5ab9ydfpbjt0n.png) 建立新應用程式後,您將看到一個空白畫布,右側有一個元件庫,底部有一個查詢面板。 --- 2. 設計使用者介面 ---------- 將以下元件拖曳到畫布上: - **容器**:組織標題、輸入欄位和輸出部分。 - **文字和文字輸入**:用於公司名稱、服務描述、預算、截止日期和公司專業知識。 - **按鈕**:產生提案。 - **文字**:以 HTML 格式顯示產生的提案。 - **圖示**:用於徽標並使 UI 更具吸引力。 為了清楚起見,重新命名輸入欄位: - `companyNameInput` - `serviceDescriptionInput` - `budgetInput` - `deadlineInput` - `companyExpertiseInput` 將按鈕命名為`createButton` 。 命名將把產生的提案顯示為`output`的文字元件。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dki3r05jwejzr62mlbws.png) *ToolJet 的預先建置[元件](https://docs.tooljet.com/docs/tooljet-concepts/what-are-components)在功能和樣式自訂方面提供了完全的靈活性。* --- 3. 透過查詢與Gemini API集成 -------------------- - 建立一個[工作區常數](https://docs.tooljet.com/docs/tooljet-concepts/workspace-constants/)來保存您的 Gemini API 金鑰。將其命名為`GEMINI_API_KEY` 。 - 展開查詢面板,建立一個新查詢,並命名為`generateProposal` 。 - 將請求方法變更為`POST`並將以下 URL 貼到 URL 輸入下: `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent?key={{constants.GEMINI\_API\_KEY}} ` - 導航到`getContent`查詢的正文部分。切換到原始 JSON 並輸入以下程式碼: ``` { "contents": [ { "parts": [ { "text": " 1. **Client/Company Name:** {{components.companyNameInput.value}} 2. **Project/Service Description:** {{components.serviceDescriptionInput.value}} 3. **Budget Range (if applicable):** {{components.budgetInput.value}} 4. **Deadline:** {{components.deadlineInput.value}} 5. **Company Expertise:** {{components.companyExpertiseInput.value}} Based on these inputs, generate a well-structured and comprehensive business proposal document in HTML format. The generated proposal should include the following sections, each with ample padding and spacing: 1. **Executive Summary** 2. **Company Overview and Qualifications** 3. **Project Understanding and Approach** 4. **Proposed Solution and Methodology** 5. **Timeline and Deliverables** 6. **Team Structure and Bios** 7. **Cost Breakdown and Budget** (Include charts as needed) 8. **Terms and Conditions** 9. **Conclusion and Call to Action** Ensure that the HTML output is properly formatted and visually appealing." } ] } ] } ``` ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71f02ensa53tr3g6ponl.png) *ToolJet 中的[查詢](https://docs.tooljet.com/docs/tooljet-concepts/what-are-queries)提供了一種連接[資料庫、API 和雲端儲存服務的](https://docs.tooljet.com/docs/tooljet-concepts/what-are-datasources)簡單方法。* --- 4. 將 UI 元件與查詢連接 --------------- - 選擇`createButton`元件。 - 新增事件處理程序以在點擊按鈕時觸發`generateProposal`查詢。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4cuayj8aq73tdg0zbhrc.png) *事件用於執行查詢、顯示警報以及基於觸發器(例如按鈕單擊或查詢完成)的其他功能。* - 選擇為顯示查詢輸出而建立的文字元件。 - 在其 Data 屬性下,輸入以下程式碼: `{{queries.generateProposal.data.candidates[0].content.parts[0].text}}` 現在,在輸入欄位中輸入所需的詳細訊息,然後按一下按鈕。您應該在輸出元件中看到產生的業務提案。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jjzuk15d30x9036nyhki.png) ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyfbp9ltgyn1zqmsezsu.png) --- 結論 -- 您已在短短 10 分鐘內使用 Gemini API 和 ToolJet 成功建立了一個商業提案編寫器。該工具將簡化專業商業提案的建立,節省您的時間和精力。如有任何問題或支持,請加入[ToolJet Slack 社群](https://join.slack.com/t/tooljet/shared_invite/zt-2l2i9tuls-NNCZPBlPAi2flYIhrjBqHA)。您也可以查看[ToolJet 文件](https://docs.tooljet.com/docs/)以了解更多資訊。 --- 原文出處:https://dev.to/tooljet/build-an-ai-business-proposal-writer-using-gemini-api-and-tooljet-in-10-minutes-4j3j

如何使用 Ollama 和打開 WebUI 在本地執行 Llama 3

https://youtu.be/GT-Fwg124-I 我是 Llama 的忠實粉絲。 Meta 發布其 LLM 開源程式碼對整個科技界來說是一項淨收益,其寬鬆的許可證允許大多數中小型企業在幾乎沒有任何限制的情況下使用其 LLM(當然,在法律範圍內)。他們的最新版本是備受期待的 Llama 3。 Llama 3 有兩種大小:80 億和 700 億參數。這種模型經過大量文字資料的訓練,可用於各種任務,包括生成文字、翻譯語言、編寫不同類型的創意內容以及以資訊豐富的方式回答您的問題。 Meta 宣稱 Llama 3 是最好的開放模型之一,但它仍在開發中。這是與 Mistral 和 Gemma 相比的 8B 模型基準(根據 Meta)。 ![基準測試](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ax9r9z2w2zghv81grbh7.png) 這就引出了一個問題:作為一個普通人,我如何在我的電腦上本地執行這些模型? 開始使用 Ollama ----------- 這就是[奧拉瑪](https://ollama.com/)登場的地方! Ollama 是一款免費的開源應用程式,可讓您在自己的電腦上執行各種大型語言模型,包括 Llama 3,即使資源有限。 Ollama 利用了 llama.cpp 的效能提升,llama.cpp 是一個開源程式庫,旨在允許您以相對較低的硬體要求在本地執行 LLM。它還包括一種套件管理器,使您只需一個命令即可快速有效地下載和使用 LLM。 第一步是[安裝 Ollama](https://ollama.com/download) 。它支援所有 3 個主要作業系統,其中[Windows 是「預覽版」](https://ollama.com/blog/windows-preview) (更好的說法是「測試版」)。 安裝完成後,打開您的終端。在所有平台上,命令都是相同的。 ``` ollama run llama3 ``` 等待幾分鐘,它會下載並載入模型,然後開始聊天!它應該會帶您進入與此類似的聊天提示。 ``` ollama run llama3 >>> Who was the second president of the united states? The second President of the United States was John Adams. He served from 1797 to 1801, succeeding George Washington and being succeeded by Thomas Jefferson. >>> Who was the 30th? The 30th President of the United States was Calvin Coolidge! He served from August 2, 1923, to March 4, 1929. >>> /bye ``` 您可以在這個終端聊天中整天聊天,但是如果您想要更像 ChatGPT 的東西怎麼辦? 打開網頁介面 ------ Open WebUI 是一個可擴充的、自架的 UI,完全在[Docker](https://docs.docker.com/desktop/)內部運作。它可以與 Ollama 或其他 OpenAI 相容的 LLM 一起使用,例如 LiteLLM 或我自己的[Cloudflare Workers OpenAI API](https://github.com/chand1012/openai-cf-workers-ai) 。 假設您的電腦上已經執行了[Docker](https://docs.docker.com/desktop/)和 Ollama,[安裝](https://docs.openwebui.com/getting-started/#quick-start-with-docker-)非常簡單。 ``` docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main ``` 只要造訪 http://localhost:3000,建立帳戶,然後開始聊天! ![OpenWebUI 範例](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdi1d35zh09s78o8vqvb.png) 如果您之前沒有執行過 Llama 3,則必須先關閉一些模型才能開始聊天。最簡單的方法是點擊左下角您的名字後點擊設定圖示。 ![設定](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqyetksyn0y4a0p12ylu.png) 然後點擊模式左側的“模型”,然後貼上[Ollama 註冊表](https://ollama.com/models)中的模型名稱。以下是我推薦用於一般用途的一些模型。 - `llama3` - `mistral` - `llama2` ![機型設定頁面](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txc581jf4w3xszymjfbg.png) 奧拉馬 API ------- 如果您想將 Ollama 整合到您自己的專案中,Ollama 提供自己的 API 以及 OpenAI 相容 API。 API 會自動將本機儲存的 LLM 載入到記憶體中,執行推理,然後在一定的逾時後卸載。您必須先拉取您想要使用的任何模型,然後才能透過 API 執行模型,這可以透過命令列輕鬆完成。 ``` ollama pull mistral ``` ### 奧拉馬 API Ollama 有自己的 API,其中還有[一些用於 Javascript 和 Python 的 SDK](https://github.com/ollama/ollama?tab=readme-ov-file#libraries) 。 以下是如何使用 API 進行簡單的文字產生推理。 ``` curl http://localhost:11434/api/generate -d '{ "model": "mistral", "prompt":"Why is the sky blue?" }' ``` 以下是如何使用 API 進行聊天產生推論。 ``` curl http://localhost:11434/api/chat -d '{ "model": "mistral", "messages": [ { "role": "user", "content": "why is the sky blue?" } ] }' ``` 將`model`參數替換為您要使用的任何模型。請參閱[官方 API 文件](https://github.com/ollama/ollama/blob/main/docs/api.md)以取得更多資訊。 ### OpenAI 相容 API 您也可以使用 Ollama 作為 OpenAI 庫的替代品(取決於用例)。這是[他們文件](https://github.com/ollama/ollama/blob/main/docs/openai.md)中的一個範例。 ``` # Python from openai import OpenAI client = OpenAI( base_url='http://localhost:11434/v1/', # required but ignored api_key='ollama', ) chat_completion = client.chat.completions.create( messages=[ { 'role': 'user', 'content': 'Say this is a test', } ], model='mistral', ) ``` 這也適用於 JavaScript。 ``` // Javascript import OpenAI from 'openai' const openai = new OpenAI({ baseURL: 'http://localhost:11434/v1/', // required but ignored apiKey: 'ollama', }) const chatCompletion = await openai.chat.completions.create({ messages: [{ role: 'user', content: 'Say this is a test' }], model: 'llama2', }) ``` 結論 -- Meta 的 Llama 3 的發布及其大型語言模型 (LLM) 技術的開源標誌著技術社群的一個重要里程碑。現在,透過 Ollama 和 Open WebUI 等本地工具可以存取這些先進的模型,普通個人可以挖掘其巨大潛力來生成文字、翻譯語言、創作創意寫作等。此外,API 的可用性使開發人員能夠將 LLM 無縫整合到新專案或增強現有專案。最終,LLM 技術透過 Llama 3 等開源專案實現民主化,釋放了廣泛的創新可能性,並激發了科技業的創造力。 --- 原文出處:https://dev.to/timesurgelabs/how-to-run-llama-3-locally-with-ollama-and-open-webui-297d