🔍 搜尋結果:API

🔍 搜尋結果:API

進階 CI/CD 管道配置策略

\_歡迎參加 DevSecOps in 5 的第 3 週:您獲得安全開發超級大國的門票! 嘿,安全冠軍和編碼戰士! 您是否渴望提升 DevSecOps 水平並成為堅如磐石的軟體架構師?好吧,您來對地方了!這個為期 5 週的部落格系列是您掌握安全開發和部署的快速通道。 --- 在當今快節奏的開發環境中,持續整合和持續交付(CI/CD)管道已成為高效軟體交付的基石。它們會自動執行重複性任務,例如建置、測試和部署程式碼,使團隊能夠更快、更可靠地交付功能和錯誤修復。但除了基本功能之外,還有一個進階配置的世界,可以釋放更高的效率和控制力。本部落格深入探討了先進的 CI/CD 管道策略,為您提供了根據您的特定需求建立強大且可擴展的管道的知識。 部署策略:超越藍/綠 ---------- 雖然藍/綠部署是最大限度地減少更新期間停機時間的熱門選擇,但它們並不是唯一的選擇。讓我們探討一些進階部署策略: #### 藍/綠部署(深入): 在藍/綠部署中,您維護兩個相同的生產環境(藍色和綠色)。新程式碼首先部署到綠色環境中,並經過嚴格的測試。一旦穩定,流量就會逐漸從藍色環境轉向綠色環境,有效取代舊版本。這種方法可以最大限度地減少停機時間,並在出現問題時允許快速回滾。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51im761vqe814tob58tw.png) #### 金絲雀版本(擴充): 金絲雀發布涉及首先向一小部分用戶(金絲雀)部署應用程式的新版本。這允許在全面推出之前進行實際測試和監控。您可以使用先進的技術,例如透過基於百分比的流量轉移進行分階段部署。首先將新版本部署到一小部分用戶(例如 1%),隨著效能和穩定性的確認逐漸增加流量,最後推廣到整個用戶群。 A/B 測試可以與金絲雀版本集成,以比較不同的應用程式版本並在全面推出之前收集用戶回饋。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7v6gstbyayfspqah7ldy.png) #### 紅帽部署堆疊 (OpenShift): OpenShift 是一個容器編排平台,提供內建部署功能。它可以與 CI/CD 管道集成,以利用藍/綠部署和金絲雀發布等高級部署策略。 OpenShift 管理容器化應用程式的擴充和運作狀況,從而簡化部署工作流程。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/81v097cqxon85xcl084j.png) CI/CD 管道中的基礎設施配置: ----------------- 自動化基礎設施配置和部署是一種強大的實踐。以下是如何實現它: #### 基礎設施即程式碼 (IaC) 工具: Terraform、Ansible 或 CloudFormation 等流行的 IaC 工具可讓您將基礎架構定義為程式碼。這些配置可以與 CI/CD 管道集成,從而在部署期間實現基礎設施資源(例如虛擬機器、儲存)的自動配置和管理。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9limw1f3ew3xudrjkum.png) #### 多雲基礎設施管理: 跨不同雲端供應商(多雲)管理基礎架構可能很複雜。 IaC 工具可以透過定義與雲端無關的配置來提供協助,這些配置可以透過最小的變更來適應不同的雲端供應商。與多雲 IaC 工具整合的 CI/CD 管道可以跨各種雲端環境自動化基礎設施配置和部署。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysyfl6vi2juabenjgmr4.png) 管道中 IaC 的安全注意事項: ---------------- 使用 IaC 時,安全性至關重要。安全實踐包括: 使用 HashiCorp Vault 等機密管理工具在 IaC 配置中安全地儲存敏感資訊(API 金鑰、密碼)。 實施存取控制以限制誰可以修改 IaC 配置和配置資源。 定期掃描 IaC 設定是否有漏洞,以防止安全漏洞。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgx2mbbzj9zotcnz3dfl.png) #### 功能標誌和分支切換: 功能標誌是允許您在執行時啟用或停用應用程式中的特定功能的機制。它們可以與 CI/CD 管道和 Git 分支策略整合。例如,您可以將新功能的程式碼部署到特定分支,並使用功能標誌透過 CI/CD 管道控制其對不同環境或使用者群組的可見性。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dohg04gfnfg7f1cftmtq.png) #### 持續交付與持續部署(深入探討): 雖然持續交付 (CD) 和持續部署 (CD) 經常互換使用,但它們之間存在細微的差異。 CD 專注於自動化整個建置、測試和打包管道直至部署就緒狀態。通常需要人工幹預來批准和觸發部署。另一方面,持續部署使整個流程自動化,包括部署到生產環境。這需要在管道內進行強大的測試和驗證,以確保只有穩定的程式碼才能投入生產。對於需要手動批准的部署或較高風險的環境,請選擇 CD;對於頻繁、低風險的部署,請考慮 CD。 #### 無伺服器應用程式的 CI/CD: 無伺服器函數是在雲端中按需執行的事件驅動的程式碼片段。將 CI/CD 管道與無伺服器功能整合可以在程式碼變更時自動部署這些功能。考慮使用 AWS 無伺服器應用程式模型 (SAM) 或 Google Cloud Functions 等無伺服器框架來簡化無伺服器部署的 CI/CD 工作流程。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a597bj2j3j22nf4j21an.png) 監控和效能優化: -------- 以下是如何確保 CI/CD 管道的最佳性能和運作狀況: #### 監控 CI/CD 管道: 持續監控您的 CI/CD 管道以辨識瓶頸和潛在問題。監控指標,例如: #### 建置時間: 追蹤建置完成所需的平均時間。辨識並解決執行緩慢的建置,以提高整體管道效率。 #### 部署持續時間: 監控將新程式碼部署到生產環境所需的時間。研究並優化耗時過長的部署。 #### 錯誤率: 追蹤管道階段內發生錯誤的頻率(建置失敗、測試失敗)。分析錯誤以確定根本原因並實施解決方案來預防錯誤。 #### CI/CD 的指標和儀表板: 利用儀表板視覺化 CI/CD 管道中的關鍵指標。這樣可以快速辨識趨勢和潛在問題。用於 CI/CD 監控的流行工具包括 Prometheus、Grafana 和 Datadog。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4tja96vhhc36vp4umzq.png) #### 效能優化技術: 實施策略來優化 CI/CD 管道: #### 快取: 快取常用的依賴項、建置工件和測試結果,以減少冗餘下載並縮短建置時間。 #### 並行化: 將管道階段分解為可以並發執行的較小任務,以加快建置和部署速度。 #### 容器化建置: 利用 Docker 等容器化技術建立隔離的建置環境,確保跨不同環境的一致性和更快的建置。 ### 機器學習 (ML) 計畫的 CI/CD: 將 ML 模型和資料管道與 CI/CD 工作流程整合需要具體考慮。這些包括: 在管道內自動化訓練資料版本控制和管理。 整合 ML 模型的單元和整合測試,以確保其準確性和功能。 自動化模型部署和回滾過程。 ### CI/CD 安全最佳實踐: 在整個 CI/CD 管道中實施安全性: 實作程式碼簽章以驗證透過管道部署的程式碼的完整性。 整合漏洞掃描工具來辨識程式碼相依性中的安全缺陷。 實施嚴格的存取控制,以限制誰可以觸發部署並存取管道內的敏感資源。 ### CI/CD 的未來: CI/CD 的新興趨勢包括: AI/ML 整合用於管道內的自動化決策,例如最佳化資源分配或預測潛在問題。 自癒管道可以自動偵測故障並從故障中恢復。 與 GitOps 整合以進行聲明式基礎架構管理,利用 Git 作為程式碼和基礎架構配置的真實來源。 不同考慮因素的 CI/CD 管道配置 ------------------ 除了核心功能之外,CI/CD 管道還可以根據各種開發方法和專案要求進行客製化: ### 微服務架構的 CI/CD: 微服務架構涉及將應用程式分解為小型的獨立服務。微服務的 CI/CD 管道需要支援這些服務的獨立部署和測試。這可能涉及使用容器化和服務發現等技術來有效管理部署和依賴項。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mxbp17lc7tlbteoqiz9q.png) #### 用於敏捷開發的 CI/CD: 敏捷開發方法強調頻繁的程式碼變更和迭代。 CI/CD 管道可以配置為透過在每次程式碼提交時啟用快速建置、自動化測試和快速部署來支援這一點。 #### 遺留應用程式的 CI/CD: 將 CI/CD 實踐與遺留應用程式整合可能具有挑戰性。它可能涉及分階段的方法,在過渡到完整的 CI/CD 整合之前,逐步為開發生命週期的特定部分(例如單元測試)引入自動化。 進階安全注意事項: --------- #### 軟體組成分析(SCA): SCA 工具與 CI/CD 管道集成,以掃描程式碼依賴項以查找已知漏洞。這使您可以在部署之前辨識並解決潛在的安全風險。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9fj3qqc1lj594borrhw.png) #### 秘密管理和保險庫整合: 利用 HashiCorp Vault 或基於雲端的機密管理器等工具,安全地管理 CI/CD 管道中使用的機密(API 金鑰、密碼)。這些工具為敏感資訊提供安全儲存和存取控制機制。 #### 合規性和監理要求: 可以配置 CI/CD 管道以滿足您的行業或安全標準的特定合規性和監管要求。這可能涉及實施審核日誌記錄、實施存取控制以及與合規性掃描工具整合。 CI/CD 管道優化以實現可擴展性 ----------------- 隨著您的專案和部署的成長,您的 CI/CD 管線處理增加的工作負載的能力也應該隨之成長: #### 使用容器編排器進行水平擴展: Kubernetes 等容器編排平台可透過跨叢集執行管道代理程式的多個實例來水平擴展 CI/CD 管道。這允許並行執行任務並在繁重的工作負載下提高效能。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/td28dh0cskt6fn6f00t6.png) #### 提高效能的快取策略: 在整個管道中實施快取以減少冗餘操作: 快取建置工件(編譯後的程式碼),以避免在原始程式碼未更改的情況下在每個後續建置中重建它們。 快取依賴項下載以避免為每個建置重新下載它們。 #### 管道健康狀況監控和警報: 建立全面的監控和警報系統來辨識 CI/CD 管道中的問題。這可能涉及: 監控 CI/CD 基礎設施的資源利用率以辨識潛在的瓶頸。 針對管道故障、建置緩慢或錯誤設定警報,以確保及時幹預和故障排除。 CI/CD 的新興趨勢 ----------- 透過探索 CI/CD 的這些新興趨勢來保持領先地位: #### GitLab 和 GitHub 操作的 CI/CD: GitLab 和 GitHub 都提供內建的 CI/CD 功能。利用這些功能直接在 Git 儲存庫中進行自動化部署和程式碼測試。 #### 測試環境的基礎設施即程式碼: 利用 IaC 在 CI/CD 管道中配置和管理臨時測試環境。這樣可以根據需要有效率地建立和銷毀測試環境,從而減少基礎設施開銷。 #### 資料管道的 CI/CD: 將資料管道與 CI/CD 工作流程集成,以自動執行資料測試、版本控制和部署以及應用程式程式碼。這可確保資料管道與應用程式變更保持同步並保持資料品質。 ### 用於災難復原的 CI/CD: CI/CD 管道可用於自動化災難復原工作流程。透過在管道內編寫基礎架構配置、應用程式部署和資料復原過程的腳本,您可以在發生中斷或事件時加快復原時間。 ### A/B 測試與 CI/CD 整合: 將 A/B 測試工具與 CI/CD 管道集成,以促進受控部署和功能實驗。這使您可以將不同版本的功能部署到一部分用戶並收集其效能資料,然後再將其推廣到整個用戶群。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t22zepxcrskevzi2l470.png) ### CI/CD 成本優化策略: 優化與 CI/CD 管道相關的成本: 利用 CI/CD 基礎架構的隨選資源(雲端實例、容器實例),只需按使用量付費。 優化管道配置以最大限度地減少建置和部署期間的資源消耗。 考慮在雲端中使用現貨實例或搶佔式虛擬機器來實現經濟高效的 CI/CD 基礎架構。 結論 -- CI/CD 管道是強大的工具,可顯著提高軟體交付過程的速度、可靠性和效率。透過利用本部落格中探討的進階策略和注意事項,您可以釋放 CI/CD 的全部潛力並簡化您的開發工作流程。請記住根據您的特定專案需求和開發環境自訂 CI/CD 管道配置。隨著 CI/CD 的不斷發展,請隨時了解新興趨勢和最佳實踐,以確保您的管道在不斷變化的軟體開發世界中保持穩健和高效。 --- 我很高興今天有機會與您一起深入研究高級 CI/CD 管道配置策略。這是一個令人著迷的領域,具有改善安全狀況的巨大潛力。 感謝您和我一起探索進階 CI/CD 管道配置策略。您持續的興趣和參與推動了這趟旅程! 如果您發現有關進階 CI/CD 管道配置策略的討論有幫助,請考慮與您的網路分享!知識就是力量,尤其是在安全方面。 讓我們繼續談話吧!在下面的評論中分享您對進階 CI/CD 管道配置策略的想法、問題或經驗。 渴望了解有關 DevSecOps 最佳實踐的更多資訊?請繼續關注下一篇文章! 透過共同努力並採用安全的開發實踐,我們可以建立一個更具彈性和值得信賴的軟體生態系統。 請記住,安全開發之旅是一個持續學習的過程。這是為了持續改進! --- 原文出處:https://dev.to/gauri1504/advanced-cicd-pipeline-configuration-strategies-4mjh

Angular 18 的新增功能

介紹 -- 2024 年 5 月 22 日星期三,Angular 核心團隊發布了 Angular 新版本:版本 18。 該版本不僅穩定了最新的API,還引入了許多旨在簡化框架的使用並改善開發人員體驗的新功能。 這些新功能是什麼?請仔細閱讀,找出答案。 新的控制流程語法現已穩定 ------------ 當最新版本的 Angular 發佈時,引入了一種管理視圖流的新方法。提醒一下,這個新的控制流程直接整合到 Angular 模板編譯器中,使以下結構指令成為可選: - 動圖 - ngFor - ngSwitch / ngSwitchCase ``` <!-- old way --> <div *ngIf="user">{{ user.name }}</div> <!-- new way --> @if(user) { <div>{{ user.name }}</div> } ``` 這個新的 API 現已穩定,我們建議使用這個新語法。 如果您想將應用程式遷移到這個新的控制流,可以使用原理圖。 ``` ng g @angular/core:control-flow ``` 此外,新的 @for 語法取代了 ngFor 指令,迫使我們使用 track 選項來優化清單的渲染,並避免在變更期間完全重新建立清單。 開發模式中新增了兩個新警告: - 如果追蹤鍵重複,則會發出警告。如果所選鍵值在您的集合中不唯一,則會引發此警告。 - 如果追蹤鍵是整個專案並且選擇此鍵會導致整個清單的破壞和重新建立,則會發出警告。如果認為該操作成本太高(但門檻較低),則會出現此警告。 Defer 語法現已穩定 ------------ @defer 語法也在最新版本的 Angular 中引入,讓您定義一個在滿足條件時延遲載入的區塊。當然,此區塊中使用的任何第三方指令、管道或庫也將被延遲載入。 這是它的使用範例 ``` @defer(when user.name === 'Angular') { <app-angular-details /> }@placeholder { <div>displayed until user.name is not equal to Angular</div> }@loading(after: 100ms; minimum 1s) { <app-loader /> }@error { <app-error /> } ``` 提醒一句, - 只要不滿足@defer區塊條件,就會顯示@Placeholder區塊 - 當瀏覽器下載@defer區塊的內容時,將顯示@loading區塊;在我們的例子中,如果下載時間超過 100 毫秒,就會顯示區塊加載,並且顯示的最短持續時間為 1 秒。 - 如果下載@defer區塊時發生錯誤,將顯示@error區塊 Zone js 會發生什麼 ------------- Angular 18 引進了一種觸發偵測變更的新方法。此前,毫不奇怪,檢測更改完全由 Zone Js 處理。現在,偵測變化由框架本身直接觸發。 為了實現這一點,框架中加入了一個新的變更檢測調度程序 ( *ChangeDetectionScheduler* ),並且該調度程序將在內部使用來引發變更檢測。這個新的調度程序不再基於 Zone Js,並且預設與 Angular 版本 18 一起使用。 這個新的調度程序將引發檢測更改,如果 - 觸發範本或主機偵聽器事件 - 附加或刪除視圖 - 非同步管道接收新值 - 呼叫 markForCheck 函數 - 訊號的值發生變化等。 小文化時刻:此偵測變更是由於內部呼叫*ApplicationRef.tick*函數所致。 正如我上面提到的,由於Angular 18 版本一直基於這個新的調度程序,因此當您遷移應用程式時,不會出現任何問題,因為Angular 可能會收到Zone Js 和/或這個新調度程序的檢測更改通知。 但是,要回到 Angular 18 之前的行為,您可以使用provideZoneChangeDetection 函數,並將*ignoreChangesOutsideZone* setter 選項設為true。 ``` bootstrapApplication(AppComponent, { providers: [ provideZoneChangeDetection({ ignoreChangesOutsideZone: true }) ] }); ``` 另外,如果您希望僅依賴新的排程器而不依賴 Zone Js,則可以使用*ProvideExperimentalZonelessChangeDetection*函數。 ``` bootstrapApplication(AppComponent, { providers: [ provideExperimentalZonelessChangeDetection() ] }); ``` 透過實現*provideExperimentalZonelessChangeDetection*函數,Angular不再依賴Zone Js,這使得 - 如果專案的其他依賴項均不依賴它,則刪除 Zone js 依賴項 - 從 angular.json 檔案中的 polifills 中刪除區域 js 棄用 HttpClientModule ------------------- 自從 Angular 14 版本和獨立元件的到來以來,模組在 Angular 中已成為可選的,現在是時候看到第一個模組已棄用:我將其命名為 HttpClientModule 此模組負責為整個應用程式註冊 HttpClient 單例,以及註冊攔截器。 該模組可以輕鬆地替換為*ProvideHttpClient*函數,並提供支援 XSRF 和 JSONP 的選項。 這個函數有一個用於測試的孿生姊妹: *provideHttpClientTesting* ``` bootstrapApplication(AppComponent, { providers: [ provideHttpClient() ] }); ``` 像往常一樣,Angular 團隊提供了原理圖來幫助您遷移應用程式。 當發出*ng update @Angular/core @Angular /cli*命令時,如果在應用程式中使用,將發出遷移 HttpClientModule 的請求 內容後備 ---- ng-content 是 Angular 中的一個重要功能,尤其是在設計通用元件時。 此標籤可讓您投影自己的內容。然而,這項功能有一個重大缺陷。您無法為其指定預設內容。 從版本 18 開始,情況就不再如此。您可以在其中包含內容如果開發者沒有提供任何內容,將顯示的標籤。 我們以按鈕元件為例 ``` <button> <ng-content select=".icon"> <i aria-hidden="true" class="material-icons">send</i> </ng-content> <ng-content></ng-content> </button> ``` 使用按鈕元件時,如果沒有提供圖示類別的元素,則會顯示圖示傳送 表單事件:一種對表單事件進行分組的方法 ------------------- 這是社群很久以前提出的請求:有一個 api 將表單中可能發生的事件組合在一起;當我說事件時,我指的是以下事件 - 原始的 - 感動 - 狀態改變 - 重置 - 提交 Angular 18 版本公開了 AbstractControl 類別中的一個新事件屬性(允許 FormControl、FormGroup 和 FormArray 繼承該屬性),該屬性傳回一個 observable ``` @Component() export class AppComponent { login = new FormControl<string | null>(null); constructor() { this.login.events.subscribe(event => { if (event instanceof TouchedChangeEvent) { console.log(event.touched); } else if (event instanceof PristineChangeEvent) { console.log(event.pristine); } else if (event instanceof StatusChangeEvent) { console.log(event.status); } else if (event instanceof ValueChangeEvent) { console.log(event.value); } else if (event instanceof FormResetEvent) { console.log('Reset'); } else if (event instanceof FormSubmitEvent) { console.log('Submit'); } }) } } ``` 路由:重定向作為函數 ---------- 在最新版本的 Angular 之前,當您想要重新導向到另一個路徑時,可以使用*redirectTo*屬性。該屬性僅將一個字串作為其值 ``` const routes: Routes = [ { path: '', redirectTo: 'home', pathMath: 'full' }, { path: 'home', component: HomeComponent } ]; ``` 現在可以傳遞具有此屬性的函數。該函數將*ActivatedRouteSnapshot*作為參數,讓您可以從url中檢索queryParams或params。 另一個有趣的點是,這個函數是在註入上下文中呼叫的,使得注入服務成為可能。 ``` const routes: Routes = [ { path: '', redirectTo: (data: ActivatedRouteSnapshot) => { const queryParams = data.queryParams if(querParams.get('mode') === 'legacy') { const urlTree = router.parseUrl('/home-legacy'); urlTree.queryParams = queryParams; return urlTree; } return '/home'; }, pathMath: 'full' }, { path: 'home', component: HomeComponent }, { path: 'home-legacy', component: HomeLegacyComponent } ]; ``` 伺服器端渲染:兩個很棒的新功能 --------------- Angular 18 引進了兩個重要且期待已久的新伺服器端渲染功能 - 事件回放 - 國際化 ### 重播事件 當我們建立伺服器端渲染應用程式時,該應用程式會以 html 格式傳送回瀏覽器,顯示一個靜態頁面,然後由於水化現象而變得動態。在此水合階段期間,無法傳送對互動的回應,因此使用者互動會遺失,直到水合完成為止。 Angular 能夠記錄此水合作用階段的用戶交互,並在應用程式完全加載並交互後重播它們。 若要解鎖此功能,仍處於開發者預覽版,您可以使用 ServerSideFeature *withReplayEvents*函數。 ``` providers: [ provideClientHydration(withReplayEvents()) ] ``` ### 國際化 隨著 Angular 16 的發布,Angular 改變了頁面水合的方式。破壞性水合作用已被漸進性水合作用所取代。然而,當時缺乏一個重要的功能:國際化支持。 Angular 跳過了標記為 i18n 的元素。 有了這個新版本,這種情況就不再是這樣了。請注意,此功能仍處於開發預覽階段,可以使用*withI18nSupport*函數啟動。 ``` providers: [ provideClientHydration(withI18nSupport()) ] ``` 國際化 --- Angular 建議使用 INTL 原生 javascript API 來處理與 Angular 應用程式國際化相關的所有事務。 根據此建議, **@angular/common**套件公開的函數助手已被棄用。因此,不再建議使用 getLocaleDateFormat 等函數。 新的建構器包和棄用 --------- 到目前為止,自從 Angular 中出現 vite 以來,用於建立 Angular 應用程式的建構器位於以下套件中: **@angular-devkit/build-angular** 該套件包含 Vite、Webpack 和 Esbuild。對於將來僅使用 Vite 和 Esbuild 的應用程式來說,這個套件太重了。 考慮到這一潛在的未來,一個僅包含 Vite 和 Esbuild 的新包被建立,名稱為**@angular/build** 遷移到 Angular 18 時,如果應用程式不依賴 webpack(例如,沒有基於 Karma 的單元測試),則可以執行可選原理圖。此原理圖將修改 angular.json 檔案以使用新套件,並透過新增套件和刪除舊套件來更新 package.json。 重要的是,舊包可以繼續使用,因為它為新包提供了別名。 透過在專案的 node\_modules 中加入必要的依賴項,Angular 開箱即用地支援 Less Sass Css 和 PostCss。 然而,隨著新的**@angular/build**套件的到來,Less 和 PostCss 成為可選的,並且必須在 package.json 中明確作為開發依賴項。 當您遷移到 Angular 18 時,如果您希望使用新包,這些依賴項將自動新增。 不再需要降級非同步/等待 ------------ Zone js 不支援 Javascript 功能*async/await* 。 為了不限制開發人員使用此功能,Angular 的 CLI 將使用*async/await 的*程式碼轉換為「常規」Promise。 這種轉換稱為降級,就像它將 Es2017 程式碼轉換為 Es2015 程式碼一樣。 隨著應用程式不再基於 Zone Js,即使目前仍處於實驗階段,如果不再在 polyfill 中聲明 ZoneJs,Angular 將不再降級。 因此,應用程式的建置將更快、更輕。 新別名:by dev ---------- 從現在開始,當執行*ng dev*命令時,應用程式將以開發模式啟動。 實際上,ng dev 指令是*ngserve*指令的別名。 建立此別名是為了與 Vite 生態系統保持一致,特別是 npm run dev 指令。 未來 -- Angular 團隊再次交付了一個充滿新功能的版本,無疑將大大增強開發人員的體驗,並向我們展示 Angular 的未來一片光明。 未來我們可以期待什麼? 毫無疑問,性能和開發人員體驗持續改進。 我們還將看到基於訊號的表單、基於訊號的元件的引入,以及很快使用 @let 區塊聲明模板變數的能力。 --- 原文出處:https://dev.to/this-is-angular/whatnew-in-angular-18-60j

探索 JavaScript 中的解構

什麼是解構? ------ **解構**是 JavaScript 中一個非常酷的特殊語法功能,它允許我們從*陣列*、*物件*或其他可迭代結構中提取值並將它們指派給變數。 這是一種存取資料結構的屬性或元素的簡寫方式,而無需使用點表示法或陣列索引。 它對我們(用 JavaScript 寫程式的人)有什麼好處? ------------------------------ 解構有幾個好處,可以讓我們的程式碼更加簡潔、可讀和可維護! - ***提高可讀性***:解構透過減少複雜變數賦值和點符號的需要來簡化程式碼。 - ***更少的樣板程式碼***:您可以直接從資料結構中提取值,而無需建立中間變數。 - ***更簡潔的程式碼***:解構可以減少實現相同結果所需的程式碼行數。 - ***靈活性***:您可以解構任何類型的資料結構(物件、陣列、迭代),使其成為 JavaScript 工具包中的多功能工具。 有效的解構🚀使我們能夠編寫更具***表現力***、***可維護性***和***高效性的***程式碼,並且更容易理解和除錯。 基本範例 ---- ``` const person = { name: 'John', age: 30 }; const { name, age } = person; console.log(name); // "John" console.log(age); // 30 ``` 在這裡,我們解構了一個具有兩個屬性的物件`person` : `name`和`age` 。 解構 JavaScript 物件時,我們提取的值必須與物件中的鍵完全相同。您不能將`userName`取代該行中的`name` `const { name, age } = person;` 。這只是意味著 - `const { userName, age } = person;`行不通的。 但是,是的!我們可以在解構物件時套用別名。 EG- ``` const person = { name: 'John', age: 30 }; const { name:userName, age:userAge } = person; console.log(userName); // "John" console.log(userAge); // 30 ``` 您很可能在導入模組時第一次看到物件的解構。例如,當導入 exec 函數時 - ``` import { exec } from "node:child_process"; // ES Module syntax ``` ``` const { exec } = require("child_process"); // commonJS syntax ``` **同樣,我們也可以解構陣列**- ``` const numbers = [4, 5, 6]; const [x, y, z] = numbers; console.log(x); // 4 console.log(y); // 5 console.log(z); // 6 ``` 在這裡,當解構陣列時,您不需要使用別名將任何元素指派給自訂變數名稱。因為陣列元素只是值,所以它們不與某些鍵綁定。 預設值 --- 如果物件中不存在屬性,則解構允許您為變數指派預設值。 ``` const person = { name: 'John' }; const { name = 'Anonymous', age } = person; // age will be undefined console.log(name); // "John" console.log(age); // undefined ``` 這裡,字串值`'John'`沒有被變數`name`中的值`'Anonymous'`替換,因為它已經存在於物件中。 然而 - ``` const person = { name: 'John' }; const { name, age = 30 } = person; // age defaults to 30 if not present console.log(name); // "John" console.log(age); // 30 ``` 傳播文法 ---- **擴展**語法或**運算子**`(...)`可以與解構一起使用,以將陣列的剩餘元素或物件的屬性捕獲到新變數中。 - 使用陣列的擴充語法 - ``` const numbers = [1, 2, 3, 4, 5]; const [first, second, ...rest] = numbers; console.log(first); // 1 console.log(second); // 2 console.log(rest); // [3, 4, 5] (remaining elements) ``` - 物件的擴展語法 - ``` const person = { name: 'John', age: 30, city: 'New York' }; const { name, ...info } = person; console.log(name); // "John" console.log(info); // { age: 30, city: "New York"} (remaining properties) ``` 嵌套解構 ---- 解構可以嵌套以從深度嵌套的物件或陣列中提取值。 ``` const data = { user: { name: 'Alicia', origin: 'Romania', eyes: 'blue', address: { city: 'London', } } }; const { user: { name, address: { city } } } = data; console.log(name); // "Alicia" console.log(city); // "London" ``` 函數參數列表中的解構 ---------- 假設我們有一個名為`credentials`的JavaScript物件 - ``` const credentials = { name: 'Debajyati', age: 20, address: { city: 'Kolkata', state: 'West Bengal', country: 'India' }, phone: '', email: '', hobbies: ['reading', 'listening to music', 'coding', 'watching Anime'], skills: { programming: true, blogging: true, singing: false } } ``` 名為`showCredentials`的函數只接受 1 個參數值,該參數值是一個物件,而 Standard 會根據某些物件屬性輸出一個字串。 好吧,我們可以這樣寫函數定義 - ``` function showCredential(obj) { const hasSkill = (skill) => obj.skills[skill]; console.log( `${obj.name} is ${obj.age} years old.\n Lives in ${obj.address.city}, ${obj.address.country}.\n`, `He has the following hobbies: ${obj.hobbies.join(", ")}`, ); if (hasSkill("programming")) { console.log(`He is a programmer.`); } if (hasSkill("singing")) { console.log(`He is a singer.`); } if (hasSkill("blogging")) { console.log(`He is also a tech blogger.`); } } ``` 用 - 來呼叫它 ``` showCredential(credentials); ``` 得到這個輸出 - ``` Debajyati is 20 years old. Lives in Kolkata, India. He has the following hobbies: reading, listening to music, coding, watch ing Anime He is a programmer. He is also a tech blogger. ``` 相反,我們可以在定義函數時解構參數清單中的物件參數。像這樣 - ``` function showCredential({ name, age, address: { city, country}, hobbies, skills }) { const hasSkill = (skill) => skills[skill]; console.log( `${name} is ${age} years old.\n Lives in ${city}, ${country}.\n`, `He has the following hobbies: ${hobbies.join(", ")}`, ); if (hasSkill("programming")) { console.log(`He is a programmer.`); } if (hasSkill("singing")) { console.log(`He is a singer.`); } if (hasSkill("blogging")) { console.log(`He is also a tech blogger.`); } } ``` 給出相同的輸出。 &gt; | :資訊來源: 注意| |----------------------------------------| 函數仍然只接受一個參數。解構不會增加函數參數清單中的參數數量。 此外,呼叫該函數也沒有改變。依然是—— ``` showCredential(credentials); ``` ### 那麼,為什麼要解構函數參數列表中的物件呢? 雖然函數參數清單中的解構一開始可能看起來很麻煩或乏味,但它有非常重要的好處。 #### 需要考慮的要點 - ***更安全的程式碼:*** 解構可以清楚地表明函數需要哪些屬性,有助於防止錯誤。如果傳遞的物件中缺少屬性,解構將導致函數執行期間出現錯誤,有助於及早發現潛在問題。 - ***減少冗長:*** 透過直接將屬性提取到參數清單中的變數中,可以避免使用點表示法重複存取物件屬性。這導致函數定義更清晰、更簡潔。 - ***注重功能:*** 透過在參數清單中進行解構,您可以將資料存取邏輯與函數的核心功能分開。這改進了程式碼組織並使函數的目的更加清晰。 解構字串 ---- 就像我們如何解構陣列一樣,我們也可以將字串解包為陣列元素。巧妙地運用我們的智慧。 ``` const fruit = 'grape'; const [first, second, ...rest] = fruit; const animal = rest.join(''); console.log(animal); // ape ``` > | :警告:記住! |------------------------| 當您使用展開運算子`(...)`捕獲字串中的剩餘字元時,您不會得到字串。您將會得到這些字元的陣列。 解構的一些方便的應用範例 ------------ - ***沒有第三個變數的交換解構***: JavaScript 傳統上需要一個臨時變數來交換兩個變數的值。解構提供了一種更簡潔、更易讀的方式來實現這一目標。 ``` - Before Destructuring: ``` ``` let a = 10; let b = 20; let temp = a; a = b; b = temp; console.log(a, b); // Output: 20 10 ``` ``` - After Destructuring: ``` ``` let a = 10; let b = 20; [a, b] = [b, a]; console.log(a, b); // Output: 20 10 ``` ``` So nifty & elegant✨! Isn't it? ``` - ***解構函數傳回值***:函數可以以陣列或物件的形式傳回多個值。解構允許您將這些返回值解包到單獨的變數中,從而提高程式碼清晰度。 假設您有一個從 API 取得資料並傳回回應物件的函數: ``` function getUserUpdates(id) { // Simulating some API call with a GET request return { data: { player: response.group.names[id], brain: "rotting", powerLevel: Number(response.group.power[id]), useAsDecoy: true, }, statusCode: Number(response.status), }; } ``` 在建立 API 或處理伺服器回應的上下文中,它提供了增強程式碼品質和可維護性的獨特優勢。 存取各個屬性將變得輕而易舉,因為您可以在函數呼叫本身期間直接將所需的屬性從函數的返回值提取到單獨的變數中。 ``` const { data: {player, useAsDecoy, powerLevel}, statusCode, } = getUserUpdates(1); ``` 每當函數傳回物件並且您對特定屬性值感興趣時,請始終立即套用解構。 如果您仍然認為返回值的解構不是一個好主意,那麼這另外兩個優點可能會說服您 - (A)***簡化的心智模型:***解構簡化了將使用您的函數的開發人員理解資料流所需的思考過程。開發人員可以專注於解構模式中使用的變數名稱所傳達的含義,而不是記住複雜的屬性存取鏈。這減少了認知負擔並促進更好的程式碼理解。 (B)***簡化複雜回傳物件的樣板程式碼:*** 當函數傳回具有大量或嵌套屬性的物件時,解構會顯著減少單獨存取它們所需的樣板程式碼。這使得程式碼庫更加簡潔、更簡潔,從而提高了整體程式碼品質。 - ***帶條件的解構***:解構可以與條件語句結合起來,根據物件的結構來處理不同的場景。如果您有一個接收具有可選屬性的物件的函數: ``` function greetUser(user) { const { name = "Anonymous" } = user || {}; // Destructuring with default value console.log(`Hello, ${name}!`); } greetUser({ name: "Bob" }); // Output: "Hello, Bob!" greetUser({}); // Output: "Hello, Anonymous!" (no name property) greetUser(undefined); // Output: "Hello, Anonymous!" (function receives no argument) ``` 結論 -- 在整篇文章中,我們了解到**「解構」**是 JavaScript 中一個強大且多功能的功能,可以顯著提高程式碼的可讀性、可維護性和效率。透過有效地使用解構技術,您可以編寫更乾淨、更簡潔且不易出錯的程式碼。因此,擁抱解構並將您的 JavaScript 技能提升到一個新的水平! 如果您發現這篇文章有幫助,如果這個部落格為您的時間和精力增加了一些價值,請透過給這篇文章點讚來表達一些愛,並與您的朋友分享。 請隨時透過[Twitter](https://twitter.com/ddebajyati) 、 [LinkedIn](https://www.linkedin.com/in/debajyati-dey)或[GitHub](https://github.com/Debajyati)與我聯繫:) 快樂編碼🧑🏽‍💻👩🏽‍💻!祝你有個美好的一天! 🚀 --- 原文出處:https://dev.to/ddebajyati/exploring-destructuring-in-javascript-5a24

您可以在開源中貢獻這 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

🙅 為什麼我不使用 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

讓我們練習在 React 中編寫乾淨、可重複使用的元件

🔑 關鍵概念 ------ **什麼是可重複使用的 React 元件?**將它們視為建置塊。 它們是您可以在網站的不同部分使用的程式碼片段,以節省時間。它們可以是從簡單按鈕到複雜表單的任何內容。 ### **為什麼要使用可重複使用的元件?** 它們可以輕鬆加入新功能並提高程式碼的可擴展性。另外,您可以在未來的專案中使用它們而無需重寫。 --- 🧩 如何寫出乾淨、可重複使用的 React 元件 ------------------------ 兩個關鍵點: **1. 避免副作用:**不要在元件中直接包含與外部資料互動的邏輯(例如 API 呼叫)。相反,將此邏輯作為`props`傳遞。 簡單但不可重複使用的按鈕範例: ``` const Button = () => { return ( <button>Click Me</button> ); } ``` 該按鈕缺乏靈活性,因為文字是硬編碼的。 **2. 使用 Props:** Props 是傳遞給元件以對其進行自訂的參數。 更好的按鈕範例: ``` const Button = ({ color, label }) => { return ( <button style={{ backgroundColor: color }}>{label}</button> ); } ``` 此按鈕可以有不同的顏色和標籤,使其更易於重複使用。 ### **挑戰:** 考慮如何在不同情況下使用您的元件,並將其設計得靈活。 --- 🍃 可重複使用 React 元件的範例 ------------------- **1. 按鈕:**自訂不同樣式和功能的按鈕。 ``` const Button = ({ color, label, onClick }) => { return ( <button style={{ backgroundColor: color }} onClick={onClick}> {label} </button> ); }; // Using the Button component <Button color="blue" label="Click Here" onClick={() => console.log("Button clicked!")} /> ``` **2. 導覽列:**整個網站的一致導覽。 ``` const Navbar = ({ isLoggedIn }) => { return ( <div className="navbar"> <a href="/">Home</a> <a href="/about">About</a> <a href="/contact">Contact</a> {isLoggedIn ? <a href="/profile">Profile</a> : <a href="/login">Login</a>} </div> ); }; // Using the Navbar component <Navbar isLoggedIn={true} /> ``` **3. 為什麼要避免在元件中呼叫 API** 在元件中包含 API 呼叫等副作用會降低可重複使用性。將副作用作為 prop 傳遞: ``` const SaveButton = ({ onClick, label }) => { return ( <button onClick={onClick}> {label} </button> ); }; // Using SaveButton <SaveButton onClick={saveUser} label="Save User" /> <SaveButton onClick={saveProject} label="Save Project" /> ``` --- 在沒有適當可視化的情況下建立元件可能會讓人不知所措。對於設計而言,Figma 是開發人員用來建立網頁設計元件和原型的絕佳工具。它因其簡潔的用戶介面和協作功能而廣受歡迎。您可以[在這裡免費註冊](https://psxid.figma.com/0s98tq)。 ![菲格瑪](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/io4stx0ue62guwclfksb.png) --- 👏 結論 ---- 恭喜!您已經學習如何建立乾淨、可重複使用的 React 元件。它們是穩健 React 開發的基礎。您練習得越多,您就越能在專案中更好地使用它們。 如果你喜歡這個,請關注我[𝕏](https://twitter.com/shahancd)以獲取更多前端開發技巧。 **閱讀更多:**[前端開發的未來](https://dev.to/codewithshahan/the-future-of-frontend-development-1amd) --- 原文出處:https://dev.to/codewithshahan/lets-practice-clean-reusable-components-in-react-5flj

掌握整潔程式碼:開發人員的基本實踐

乾淨的程式碼是每個成功的軟體專案的基石。作為開發人員,編寫乾淨、可維護的程式碼的能力對於應用程式的效率和壽命至關重要。在本文中,我們將深入研究 JavaScript 中好的和壞的編碼實踐的十個範例,強調編寫乾淨程式碼並提供可操作的見解以幫助您提高開發技能的重要性。 例子 -- - 描述性變數名稱: ``` // Good: const totalPrice = calculateTotalPrice(quantity, unitPrice); ``` ``` // Bad: const t = calcPrice(q, uP); ``` 在一個很好的例子中,變數名稱具有描述性並清楚地表達了它們的目的,從而增強了程式碼的可讀性。相反,糟糕的範例使用神秘的縮寫,使其他人難以理解程式碼的意圖。 - 一致的格式: ``` // Good: function greet(name) { return `Hello, ${name}!`; } ``` ``` // Bad: function greet(name){ return `Hello, ${name}!` } ``` 一致的格式提高了程式碼的可讀性和可維護性。在一個很好的例子中,採用了適當的縮排和間距,並增強了程式碼結構。相反,壞例子缺乏一致性,使得程式碼更難遵循。 - 避免魔法數字: ``` // Good: const TAX_RATE = 0.1; const totalPrice = subtotal + (subtotal * TAX_RATE); ``` ``` // Bad: const totalPrice = subtotal + (subtotal * 0.1); ``` 幻數掩蓋了值的含義,並使程式碼更難維護。在很好的例子中,常數用於表示幻數,提高了程式碼的清晰度和可維護性。 - 單一責任原則: ``` // Good: function calculateTotalPrice(quantity, unitPrice) { return quantity * unitPrice; } function formatPrice(price) { return `$${price.toFixed(2)}`; } ``` ``` // Bad: function calculateAndFormatTotalPrice(quantity, unitPrice) { const totalPrice = quantity * unitPrice; return `$${totalPrice.toFixed(2)}`; } ``` 函數應該有單一的責任來提高程式碼的可重複使用性和可維護性。在這個很好的例子中,每個函數都執行特定的任務,並遵循單一職責原則。相反,壞例子將多個職責組合到一個函數中,違反了這個原則。 - 錯誤處理: ``` // Good: function fetchData(url) { return fetch(url) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .catch(error => { console.error('Error fetching data:', error); throw error; }); } ``` ``` // Bad: function fetchData(url) { return fetch(url) .then(response => response.json()) .catch(error => console.error(error)); } ``` 正確的錯誤處理可以提高程式碼的穩健性,並有助於更有效地辨識和解決問題。在好的範例中,錯誤得到了妥善處理,為開發人員提供了有意義的回饋。相反,壞範例缺乏全面的錯誤處理,可能導致靜默故障。 - 評論和文件: ``` // Good: // Calculate the total price based on quantity and unit price function calculateTotalPrice(quantity, unitPrice) { return quantity * unitPrice; } ``` ``` // Bad: function calculateTotalPrice(quantity, unitPrice) { // calculate total price return quantity * unitPrice; } ``` 註釋和文件增強了程式碼的可理解性並促進了開發人員之間的協作。在一個很好的範例中,清晰的註解描述了函數的用途,有助於程式碼理解。相反,壞例子提供的模糊評論幾乎沒有什麼價值。 - 適當的模組化: ``` // Good: export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; } ``` ``` // Bad: function add(a, b) { return a + b; } function subtract(a, b) { return a - b; } ``` 模組化程式碼透過將功能組織成內聚的單元來提高可重複使用性和可維護性。在好的例子中,函數被正確地封裝和匯出,促進程式碼重用。相反,壞例子缺乏模組化,使其更難以管理和擴展。 - DRY 原則(不要重複): ``` // Good: const greeting = 'Hello'; function greet(name) { return `${greeting}, ${name}!`; } ``` ``` // Bad: function greet(name) { const greeting = 'Hello'; return `${greeting}, ${name}!`; } ``` 重複的程式碼會增加錯誤的風險並使維護變得困難。一個很好的例子是,將重複的字串提取為常數,遵循DRY原則並提高程式碼的可維護性。相反,壞範例在函數內冗餘地定義了問候語。 - 有意義的函數名稱: ``` // Good: function calculateArea(radius) { return Math.PI * radius ** 2; } ``` ``` // Bad: function calc(r) { return Math.PI * r ** 2; } ``` 函數名稱應準確反映其用途,以增強程式碼可讀性。在這個很好的例子中,函數名稱“calculateArea”清楚地表明了它的功能。相反,糟糕的例子使用了神秘的縮寫(“calc”),讓人不清楚函數的作用。 - 可測試性: ``` // Good: function sum(a, b) { return a + b; } module.exports = sum; ``` ``` // Bad: function sum(a, b) { console.log(a + b); } ``` 編寫可測試的程式碼有利於自動化測試,確保程式碼的可靠性和穩定性。在很好的範例中,函數被匯出用於測試目的,從而可以輕鬆設定和執行測試。相反,壞範例包含副作用(console.log),使得測試函數的行為變得具有挑戰性。 - 正確使用資料結構: ``` // Good: const studentGrades = [90, 85, 95, 88]; const averageGrade = studentGrades.reduce((total, grade) => total + grade, 0) / studentGrades.length; ``` ``` // Bad: const grade1 = 90; const grade2 = 85; const grade3 = 95; const grade4 = 88; const averageGrade = (grade1 + grade2 + grade3 + grade4) / 4; ``` 使用適當的資料結構可以增強程式碼的可讀性和可維護性。在很好的例子中,陣列用於儲存學生成績,以便於操作和計算。相反,壞範例依賴單一變數,導致重複且容易出錯的程式碼。 - 處理非同步操作: ``` // Good: async function fetchData(url) { try { const response = await fetch(url); if (!response.ok) { throw new Error('Network response was not ok'); } return await response.json(); } catch (error) { console.error('Error fetching data:', error); throw error; } } ``` ``` // Bad: function fetchData(url) { return fetch(url) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .catch(error => { console.error('Error fetching data:', error); throw error; }); } ``` 正確處理非同步操作可確保程式碼的可靠性和健全性。在一個很好的例子中,async/await 語法用於簡化非同步程式碼並優雅地處理錯誤。相反,壞範例使用嵌套的 Promise,導致回調地獄並降低程式碼可讀性。 - 依賴管理: ``` // Good: import { format } from 'date-fns'; ``` ``` // Bad: const dateFns = require('date-fns'); ``` 有效的依賴管理可以促進程式碼模組化和可擴展性。在一個很好的範例中,ES6 導入語法用於僅從“date-fns”庫導入所需的功能,從而減少不必要的導入並提高效能。相反,糟糕的範例使用 CommonJS require 語法,該語法導入整個“date-fns”模組,可能會使應用程式套件膨脹。 - 效能優化: ``` // Good: const sortedNumbers = [5, 2, 8, 1, 9]; sortedNumbers.sort((a, b) => a - b); ``` ``` // Bad: const unsortedNumbers = [5, 2, 8, 1, 9]; const sortedNumbers = unsortedNumbers.sort(); ``` 優化程式碼效能可確保高效執行並增強使用者體驗。在一個很好的範例中,使用自訂比較函數呼叫 sort() 方法來按升序對數字進行排序,與預設排序演算法相比,可以獲得更好的效能。相反,壞範例依賴於預設排序演算法,這對於數值陣列可能不是最有效的。 - Node.js API 中的正確錯誤處理: ``` // Good: app.get('/user/:id', async (req, res) => { try { const user = await getUserById(req.params.id); if (!user) { return res.status(404).json({ error: 'User not found' }); } res.json(user); } catch (error) { console.error('Error fetching user:', error); res.status(500).json({ error: 'Internal server error' }); } }); ``` ``` // Bad: app.get('/user/:id', async (req, res) => { const user = await getUserById(req.params.id); if (!user) { res.status(404).json({ error: 'User not found' }); } res.json(user); }); ``` 在 Node.js API 中,正確的錯誤處理對於確保穩健性和可靠性至關重要。在好的範例中,錯誤被捕獲並記錄,並且適當的 HTTP 狀態程式碼被返回到客戶端。相反,壞範例無法處理錯誤,可能導致未處理的承諾拒絕和不一致的錯誤回應。 - 高效率的檔案系統操作: ``` // Good: const fs = require('fs').promises; async function readFile(filePath) { try { const data = await fs.readFile(filePath, 'utf-8'); console.log(data); } catch (error) { console.error('Error reading file:', error); } } ``` ``` // Bad: const fs = require('fs'); function readFile(filePath) { fs.readFile(filePath, 'utf-8', (error, data) => { if (error) { console.error('Error reading file:', error); return; } console.log(data); }); } ``` 在檔案系統操作中使用 Promise 可以增強程式碼可讀性並簡化錯誤處理。在一個很好的範例中,fs.promises.readFile() 用於非同步讀取文件,並使用 try-catch 處理錯誤。相反,壞範例使用基於回調的方法,這可能導致回調地獄和可讀性較差的程式碼。 - 高效率的記憶體管理: ``` // Good: const stream = fs.createReadStream('bigfile.txt'); stream.pipe(response); ``` // 壞的: ``` fs.readFile('bigfile.txt', (error, data) => { if (error) { console.error('Error reading file:', error); return; } response.write(data); }); ``` 在 Node.js 中使用流進行大檔案處理可以節省記憶體並提高效能。在一個很好的例子中,fs.createReadStream() 和stream.pipe() 用於有效地將資料從檔案串流傳輸到HTTP 回應。相反,壞示例在將整個文件寫入響應之前將其讀入內存,這可能會導致大文件出現內存問題。 - 正確的模組導出和導入: ``` // Good: module.exports = { add: (a, b) => a + b, subtract: (a, b) => a - b }; ``` ``` // Bad: exports.add = (a, b) => a + b; exports.subtract = (a, b) => a - b; ``` 一致的模組導出和導入實踐提高了程式碼的可讀性和可維護性。在好的例子中, module.exports 用來匯出包含函數的物件,而在壞的例子中,直接使用exports。儘管這兩種方法都有效,但堅持一種約定可以增強程式碼的一致性。 - 非同步控制流程: ``` // Good: async function processItems(items) { for (const item of items) { await processItem(item); } } ``` ``` // Bad: function processItems(items) { items.forEach(item => { processItem(item); }); } ``` 適當的非同步控制流程可確保操作依需求順序或併發執行。在一個很好的範例中,非同步函數與 for...of 迴圈一起使用來順序處理專案,等待每個操作。相反,壞的例子使用了 forEach,它不能很好地處理非同步操作,並且可能會導致意外的行為。 --- 原文出處:https://dev.to/mahabubr/mastering-clean-code-essential-practices-for-developers-1287

掌握 JavaScript 生成器 🔥

JavaScript 是一種以其多功能性和易用性而聞名的語言,它具有多種功能,對於新手和經驗豐富的開發人員來說都非常強大。其中一項功能就是生成器。 ECMAScript 2015 (ES6) 中引入的生成器提供了一種處理迭代和非同步程式設計的獨特方法。在本文中,我們將探討什麼是生成器、它們如何運作以及它們的實際應用。 --- 什麼是 generator? ------- 生成器是一種特殊類型的函數,可以暫停和恢復執行。與呼叫時執行完成的常規函數不同,生成器在指定點將控制權交還給呼叫者。這種暫停和恢復的能力使它們對於需要一系列值或需要更優雅地處理非同步操作的任務特別有用。 --- 文法和基本用法 ------- 生成器函數是使用`function*`語法定義的,並使用`yield`關鍵字來暫停執行。 ``` function* myGenerator() { yield 1; yield 2; yield 3; } const gen = myGenerator(); console.log(gen.next()); // { value: 1, done: false } console.log(gen.next()); // { value: 2, done: false } console.log(gen.next()); // { value: 3, done: false } console.log(gen.next()); // { value: undefined, done: true } ``` 在此範例中, `myGenerator`是產生三個值的生成器函數。 `gen`物件是透過呼叫生成器函數所建立的迭代器。呼叫`gen.next()`傳回一個具有兩個屬性的物件: `value` (產生的值)和`done` (一個布林值,指示生成器是否已完成)。 --- `yield`的力量 ---------- `yield`關鍵字不僅暫停產生器,還允許將值傳回產生器。 ``` function* countingGenerator() { let count = 0; while (true) { count = yield count + 1; } } const counter = countingGenerator(); console.log(counter.next()); // { value: 1, done: false } console.log(counter.next(10)); // { value: 11, done: false } console.log(counter.next(20)); // { value: 21, done: false } ``` 在這裡,每次呼叫`counter.next()`都會恢復生成器,並且可以傳遞一個值來替換變數`count` 。這演示了生成器如何在暫停期間維護和更新其狀態。 --- 實際應用 ---- ### 📌 迭代 生成器在需要自訂迭代邏輯的場景中大放異彩。例如,您可以建立一個生成器來迭代一系列數字甚至複雜的資料結構。 ``` function* range(start, end) { for (let i = start; i <= end; i++) { yield i; } } for (const num of range(1, 5)) { console.log(num); // 1, 2, 3, 4, 5 } ``` --- ### 📌 非同步編程 生成器與 Promise 結合可以簡化非同步程式碼。像`co`這樣的函式庫使用這種模式比嵌套回呼或承諾鏈更自然地管理非同步流。 ``` const fetch = require('node-fetch'); function* fetchData(url) { const response = yield fetch(url); const data = yield response.json(); return data; } const co = require('co'); co(fetchData, 'https://api.example.com/data') .then(data => console.log(data)) .catch(err => console.error(err)); ``` --- ### 📌 無限序列 生成器可以建立無限序列,而由於陣列的有限性,這是不可能的。這在模擬、資料流或任何需要無限系列值的場景中非常有用。 ``` function* fibonacci() { let [prev, curr] = [0, 1]; while (true) { yield curr; [prev, curr] = [curr, prev + curr]; } } const fib = fibonacci(); console.log(fib.next().value); // 1 console.log(fib.next().value); // 1 console.log(fib.next().value); // 2 console.log(fib.next().value); // 3 console.log(fib.next().value); // 5 ``` --- 結論 -- JavaScript 中的生成器提供了一個強大的機制來處理序列、管理函數呼叫之間的狀態以及簡化非同步程式碼。 它們在 ES6 中的引入為該語言增添了顯著的靈活性和強大功能,使複雜的迭代和非同步模式變得更加平易近人。 隨著您深入研究 JavaScript,掌握生成器可以增強您編寫高效且可維護程式碼的能力。無論您是處理資料流、自訂迭代器還是非同步操作,生成器都提供了一個強大的工具來提升您的程式設計工具包。 --- ***快樂編碼!*** 🔥 **[領英](https://www.linkedin.com/in/dev-alisamir)** **[X(推特)](https://twitter.com/dev_alisamir)** **[電報](https://t.me/the_developer_guide)** **[Youtube](https://www.youtube.com/@DevGuideAcademy)** **[不和諧](https://discord.gg/s37uutmxT2)** **[Facebook](https://www.facebook.com/alisamir.dev)** **[Instagram](https://www.instagram.com/alisamir.dev)** --- 原文出處:https://dev.to/alisamirali/mastering-javascript-generators-15g3

同步引擎是 Web 應用程式的未來嗎?

請看下面的 GIF — 它顯示了一個即時[Todo-MVC 演示](https://todo-replicache-sveltekit.onrender.com/),跨視窗同步並平滑地進出離線模式。雖然它只是一個簡單的演示應用程式,但它展示了每個 Web 開發人員都應該了解的重要的前沿概念。這是一個[Replicache](https://replicache.dev/)演示應用程式,我將其從 Express 後端和 Web 元件前端移植到 SvelteKit,以了解背後的技術和概念。我想與您分享我的學習成果。原始碼可[在 Github 上](https://github.com/isaacHagoel/todo-replicache-sveltekit)取得。 ![sveltekit-replicache-演示](https://github.com/isaacHagoel/todo-replicache-sveltekit/assets/20507787/11b5ae10-049d-4cc7-82bf-45d8287701f0) 背景和動機 ----- Web 應用程式面臨一些根本性的難題,而大多數 Web 框架似乎都忽略了這些問題。這些問題非常困難,以至於只有很少的應用程式能夠真正很好地解決它們,並且這些應用程式在各自的領域中遙遙領先於其他應用程式。 以下是我在實際開發的商業應用程式中必須處理的一些此類問題: 1. 讓應用程式感覺敏捷,即使它與伺服器通信,即使在緩慢或不穩定的網路上。這不僅適用於初始載入時間,也適用於應用程式載入後的互動。 [SPA](https://developer.mozilla.org/en-US/docs/Glossary/SPA)是解決這個問題的早期嘗試,但最終還不夠。 2. 為使用者產生的內容(例如網站建立、電子商務、線上課程建構器)實施撤銷/重做和版本歷史記錄。 3. 當同一用戶在多個分頁/裝置上同時開啟應用程式時,請讓應用程式正常運作。 4. 處理執行舊版本前端的長期會話,使用者可能不想刷新以避免丟失工作。 5. 使協作功能/多人遊戲功能正確且近乎即時地工作,包括解決衝突。 我在開發完全正常的 Web 應用程式時遇到了這些問題,沒有什麼太瘋狂的,而且我相信大多數 Web 應用程式在獲得吸引力時都會遇到部分或全部問題。 我在開始開發新產品的開發團隊中註意到的一個模式是完全忽略這些問題,即使團隊已經意識到這些問題。推理通常是這樣的:“當我們真正開始遇到這些問題時,我們會處理它。”然後,團隊將繼續選擇一些完善的框架(選擇您最喜歡的),認為這些工具肯定能為可能出現的任何常見問題提供解決方案。幾個月後,當應用程式達到一萬名活躍用戶時,現實就浮出水面:團隊必須引入部分的、不完整的解決方案,這些解決方案會增加複雜性,使系統更加緩慢和錯誤,或者重寫核心部分(之後沒有人立即這樣做)發射)。哎喲。 我感受到了這種痛苦。痛苦是真實的。 輸入“同步引擎”。 同步引擎到底是什麼? ---------- 還記得我說過有些應用程式比其他應用程式更好地解決這些問題嗎?最近著名的例子是[Linear](https://linear.app/isaach)和[Figma](https://www.figma.com/) 。兩者都透過技術優勢擾亂了競爭異常激烈的市場。其他例子有[Super human](https://superhuman.com/)和十年前的[Trello](https://trello.com/) 。當您研究他們所做的事情時,您會發現它們都集中在非常相似的模式上,並且它們都在內部開發了各自的實現。您可以在以下連結中了解他們是如何做到的(強烈推薦): [Figma](https://www.figma.com/blog/how-figmas-multiplayer-technology-works/) 、 [Linear](https://www.youtube.com/live/WxK11RsLqp4?feature=share&t=2175) 、 [Super human](https://blog.superhuman.com/superhuman-is-built-for-speed/) 、 [Trello(系列)](https://www.atlassian.com/engineering/sync-architecture) 。 在系統的核心,始終有一個同步引擎,可作為前端和後端之間的持久緩衝區。從高層次來看,它是這樣運作的: - 客戶端始終讀取和寫入引擎提供的本地儲存。就應用程式程式碼而言,它在記憶體中本地執行。 - 該儲存負責樂觀地更新狀態,將資料本地保存在瀏覽器的儲存中,並與後端來回同步,包括處理潛在的複雜情況和邊緣情況。 - 後端實作引擎的另一半,以允許拉取和推播資料、在資料變更時通知客戶端、將資料保存在資料庫中等。 同步引擎的不同實作會做出不同的權衡,但基本概念始終是相同的。 這不是一個新想法,但... ------------- If you've been following trends in the web-dev world, you'd know that sync engines have been a centrepiece in several of them, namely: [progressive web apps](https://web.dev/articles/what-are-pwas) , [offline-first apps](https://offlinefirst.org/) , and the lately trending term: [local-first軟體](https://www.inkandswitch.com/local-first/).您甚至可能研究過一些提供內建同步引擎的資料庫,例如[PouchDb](https://pouchdb.com/)或具有相同功能的線上服務(例如[Firestore](https://firebase.google.com/docs/firestore) )。我也有,但過去幾年我的整體感覺是,這些都不是切中要害的。漸進式網頁應用程式是關於用戶在主螢幕上「安裝」網站的快捷方式,就好像它們是本機應用程式一樣,儘管不需要安裝可能是網路的「好處」。 「離線優先」聽起來離線模式比線上模式更重要,但對於 99% 的網路應用程式來說,情況並非如此。 「本地優先」無疑是迄今為止最好的名字,但官方的[本地優先宣言](https://www.inkandswitch.com/local-first/)談論了點對點通信和[CRDT](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) (一個超級酷的想法,但除了協作文本編輯之外很少用於任何其他用途)。客戶端-伺服器Web 應用程式的世界正在嘗試解決像我上面描述的那樣的實際問題。諷刺的是,許多屬於當前「本地優先」浪潮一部分的工具都採用了這個名稱,但沒有採用所有原則。 最引起我注意和興趣的是「Replicache」。具體來說,我對它很感興趣,因為它不是一個自我複製的資料庫,也不是一個你必須圍繞它來建立整個應用程式的黑盒 SaaS 服務。相反,與我在這個領域遇到的任何現成解決方案相比,它提供了更多的控制、靈活性和關注點分離。 什麼是複製快取? -------- Replicache 是一個函式庫。在前端,它只需要很少的佈線,並且可以有效地充當普通的全局商店(想想 Zustand 或 Svelte 商店)。它有一個狀態區塊(在我們的範例中,每個清單都有自己的儲存)。它可以使用一組稱為“mutators”(認為是reducers)的用戶定義函數進行變異,例如“addItem”、“deleteItem”或任何您想要的東西,並公開一個訂閱函數(我[在這裡](https://doc.replicache.dev/api/classes/Replicache)簡化了完整的API)。 在這個熟悉的介面背後是一個強大且高效能的客戶端同步引擎,它可以處理: 1. 初步將相關資料完整下載到客戶端。 2. 從後端拉動和推送“突變”。突變是一個事件,指定應用哪個突變器以及哪些參數(加上一些元資料)。 ``` - When pushing, these changes are applied optimistically on the client, and rolled back if they fail on the server. Any other pending changes would be applied on top (rebase). ``` ``` - The sync mechanism also includes queuing changes if the connection is lost, retry mechanisms, applying changes in the right order, and de-duping. ``` 3. 將所有內容快取在記憶體中(效能)並將其保存到瀏覽器儲存(特別是 IndexedDB)以進行備份。 4. 由於可以從同一應用程式的所有選項卡存取相同的存儲,因此引擎會處理其中的所有含義,例如當架構發生更改但某些選項卡已刷新而某些選項卡尚未刷新且仍在使用時該怎麼辦舊模式。 5. 使用廣播通道立即保持所有選項卡同步(因為依賴共用儲存不夠快)。 6. 處理瀏覽器決定清除本地儲存的情況。 您可能已經注意到,這裡解決了我在本文頂部列出的大部分問題。基於突變也適合撤銷/重做等功能。 為了讓所有這些都能發揮作用,後端的工作就是實作 Replicache 定義的協定。具體來說: 1. 您需要實作[推送](https://doc.replicache.dev/reference/server-push)和[拉取](https://doc.replicache.dev/reference/server-pull)API。這些端點需要能夠像前端一樣啟動變異器(儘管它們不必執行相同的邏輯)。後端是權威的,衝突解決是由您的 mutator 實作中的程式碼完成的。 2. 您的資料庫需要支援快照隔離並在事務內執行操作。 3. Replicache 用戶端定期輪詢伺服器以檢查更改,但如果您希望用戶端之間接近即時同步,則需要實作「poke」機制,即通知客戶端某些內容已更改並且需要進行更改的方法。拉。這可以透過[伺服器發送的事件](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)或[websockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)來完成。這是一個有趣的 API 設計選擇——更改永遠不會推送到客戶端;客戶總是拉他們。我相信這樣做是為了簡單且易於對系統進行推理。有一點可以肯定:他們沒有強制使用Websocket,這是件好事,因為這會使協議與HTTP(伺服器透過正常HTTP 連接發送的事件流)不相容,這將需要額外的基礎設施並帶來額外的集成挑戰。 4. 根據[版本控制策略](https://doc.replicache.dev/strategies/overview),您可能需要實作其他操作(例如,createSpace)。 如果這對您來說並不平凡,那麼您是對的。我認為我還沒有完全理解它如何與資料庫一起操作的所有細節。我需要做一個後續專案,在其中完全重構資料庫結構和/或向範例加入有意義的功能(例如版本歷史記錄),以便更接近完全理解它。問題是,我知道在建立和維護實際生產應用程式時這種控制層級有多麼有價值。在我的書中,花一兩週的時間深入思考和設定應用程式的核心部分,如果它為建立和擴展奠定了堅實的基礎,那麼它就是一筆巨大的投資。 移植一個重要的範例 --------- 學習新事物的最好(也可以說是唯一)方法就是親自動手,親自體驗一些會影響真正應用程式的權衡和影響。當我查看[Replicache 網站上的範例](https://doc.replicache.dev/examples/todo)時,我注意到沒有 Sveltekit 的範例。自從 Svelte 3 發布以來,我一直是 Svelte 的忠實粉絲,但最近才開始使用 Sveltekit。我認為這將是一個透過實踐學習並同時建立有用的參考來實現的絕佳機會。 將現有程式碼庫移植到不同的技術具有教育意義,因為在翻譯程式碼時,您被迫理解並質疑它。在整個過程中,我經歷了多次靈光一現的時刻,因為一些起初看起來很奇怪的事情都發生了。 學習內容 ---- #### 斯維爾特基特 1. Sveltekit[本身並不支援 WebSockets](https://github.com/sveltejs/kit/issues/1491) ,即使它確實支援伺服器發送事件,但它的[方式也很笨拙](https://stackoverflow.com/questions/74879852/how-can-i-implement-server-sent-events-sse-in-sveltekit)。 Express 很好地支援兩者。因此,我使用[svelte-sse](https://github.com/razshare/sveltekit-sse)來處理伺服器發送的事件。我遇到的一個有點煩人的怪癖是,由於 svelte-sse 返回一個 Svelte 商店,而我的應用程式沒有訂閱該商店(應用程式不需要讀取該值,只需觸發如上所述的拉取),整件事情只是被編譯器優化掉了。起初我很困惑為什麼訊息沒有通過。我最終不得不針對這種行為實施解決方法。我不怪圖書館的作者;我只是怪罪圖書館的作者。他們假設一個有意義的值將發送給客戶端,但「poke」的情況並非如此。 2. 與原始 Express 後端相比,SvelteKit 基於檔案系統的路由、載入函數、佈局和其他功能可以實現更好組織的程式碼庫和更少的樣板程式碼。不用說,在前端,Svelte 遠遠領先於 Web 元件,導致前端程式碼庫更小、更易讀,儘管它具有更多功能(原始示例 TodoMVC 缺少諸如“將所有內容標記為完成”等功能) “刪除完成”)。 3. 總的來說,我喜歡 Sveltekit 並計劃在未來繼續使用它。如果您還沒有嘗試過,[官方教學](https://learn.svelte.dev/tutorial/introducing-sveltekit)是一個很棒的介紹。 ### 複製快取 總的來說,Replicache 給我留下了非常深刻的印象,並建議嘗試一下。在基本層面上(這是我目前要做的所有嘗試),它運作良好並兌現了所有承諾。話雖如此,以下是我的一些普遍擔憂(與待辦事項應用程式無關)以及與之相關的想法: - **性能相關:** ``` - **Initial load time** (first time, before any data was ever pulled to the client) might be long when there is a lot of data to download (think tens of MBs). Productivity apps in which the user spends a lot of time after the initial load are less sensitive to this, but it is still something to watch for. Potential mitigation: partial sync (e.g., Linear only sends open issues or ones that were closed over the last week instead of sending all issues). ``` ``` - **Chatty network (?)** - Initially, it seemed to me that there was a lot of chatter going back and forth between the client and the server with all the push, pull, and poke calls flying around. On deeper inspection, I realized my intuition was wrong. There is frequent communication, yes, but since the mutations are very compact and the poke calls are tiny (no payload), it amounts to much less than your normal REST/GraphQL app. Also, a browser full reload (refresh button or opening the page again in a new tab/window after it was closed) loads most of the data from the browser's storage and only needs to pull the diffs from the server, which leads me to the next point. ``` ``` - **Coming back after a long period of time offline**: I haven't tested this one, but it seems like a real concern. What happens if I was working offline for a few days making updates while my team was online and also making changes? When I come back online, I could have a huge amount of diffs to push and pull. Additionally, conflict resolution could become super difficult to get right. This is a problem for every collaborative app that has an offline mode and is not unique to Replicache. The Replicache docs [warn about this situation](https://doc.replicache.dev/concepts/offline) and propose implementing "the concept of history" as a potential mitigation. ``` ``` - What about **bundle size**? Replicache is [34kb gzipped](https://bundlephobia.com/package/[email protected]), and for what you get in return, it's easily worth it. ``` ``` - [This page](https://doc.replicache.dev/concepts/performance) on the Replicache website makes me think that, in the general case, performance should be very good. ``` - **功能相關:** ``` - Unlike native mobile or desktop apps, it is possible for users to **lose the local copy of their work** because the browser's storage doesn't provide the same guarantees as the device's file system. Browsers can just decide to delete all the app's data under certain conditions. If the user has been online and has work that didn't have a chance to get pushed to the server, that work would be lost in such a case. Again, this problem is not unique to Replicache and affects all web apps that support offline mode, and based on what I read, it is unlikely to affect most users. It's just something to keep in mind. ``` ``` - I was surprised to see that the **schema in the backend database** in the Todo example I ported doesn't have the "proper" relational definitions I would expect from a SQL database. There is no "items" table with fields for "id", "text", or "completed". The reason I would want that to exist is the same reason I want a relational database in the first place—to be able to easily slice and dice the data in my system (which I always missed down the line when I didn't have). I don't think it is a major concern since Replicache is supposed to be backend-agnostic as long as the protocol is implemented according to spec. I might try to refactor the database as a follow-up exercise to see what that means in terms of complexity and ergonomics. ``` ``` - I find **version history and undo/redo** super useful and desirable in apps with user-editable content. With regards to undo/redo there is an [official package](https://github.com/rocicorp/undo) but it seems to [lack support for the multiplayer usecase](https://github.com/rocicorp/replicache/issues/1008) (which is where the problems come from). As for version-history, the Replicache documentation mentions "the concept of history" but [suggests talking to them](https://doc.replicache.dev/concepts/offline) if the need arises. That makes me think it might not be straightforward to achieve. Another idea for a follow-up task. ``` ``` - **Collaborative text editing** - the existing conflict resolution approach won't work well for collaborative text editing, which requires [CRDTs](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) or [OT](https://en.wikipedia.org/wiki/Operational_transformation). I wonder how easy it would be to integrate Replicache with something like [Yjs](https://yjs.dev/). There is an [official example repo](https://github.com/rocicorp/replicache-yjs), but I haven't looked into it yet. ``` - **縮放相關:** ``` - Since the server is stateful (holds open HTTP connections for server-sent events), I wonder how well it would scale. I've worked on production systems with >100k users that used WebSockets before, so I know it is not that big of a deal, but still something to think about. ``` - **其他:** ``` - - In theory, Replicache can be **added into existing apps** without rewriting the frontend (as long as the app already uses a similar store). The backend might be trickier. If your database doesn't support snapshot isolation, you are out of luck, and even if it does, the existing schema and your existing endpoints might need some serious rework. If you're going to use it, do it from day one (if you can). ``` ``` - Replicache is **not open source** (yet! see the point below) and is [free only as long as you're small or non-commercial](https://replicache.dev/#pricing). Given the amount of work (>2 years) that went into developing it and the quality of engineering on display, it seems fair. With that said, it makes adopting Replicache more of a commitment compared to picking up a free, open library. If you are a tier 2 and up paying customer, you get a [source license](https://doc.replicache.dev/howto/source-access) so that if Replicache shuts down for some reason, your app is safe. Another option is to roll out your own sync engine, like the big boys (Linear, Figma) have done, but getting to the quality and performance that Replicache offers would be anything but easy or quick. ``` ``` - **Crazy plot twist** (last minute edit): As I was about to publish this post I discovered that Replicache is going to be opened sourced in the near future and that its parent company is planning to launch a new sync-engine called "Zero". [Here is the official announcement](https://zerosync.dev/). It reads: "We will be open sourcing [Replicache](https://replicache.dev/) and [Reflect](https://reflect.net/). Once Zero is ready, we will encourage users to move." ``` ``` Ironically, Zero seems to be yet another solution that automagically syncs the backend database with the frontend database, which at least for me personally seems less attractive (because I want separation of concerns and control). With that said, these guys are experts in this domain and I am just a dude on the internet so we'll have to wait and see. In the meanwhile, I plan on playing with Replicache some more. ``` 同步引擎應該用於所有事情嗎? -------------- 不,同步引擎不應該用於所有事情。好訊息是,您可以讓應用程式的某些部分使用它,而其他部分仍然以傳統方式提交表單並等待伺服器的回應。 SvelteKit 和其他全端框架使這種整合變得容易。 使用同步引擎的明顯情況是一個壞主意: 1. 只有當客戶端更改很可能成功(回滾很少)並且客戶端擁有足夠的資訊來預測結果時,樂觀更新才有意義。例如,在線上測驗中,學生的答案必須傳送到伺服器進行評分,樂觀更新(因此同步引擎)是不可行的。這同樣適用於下訂單或交易股票等關鍵操作。一個好的經驗法則是,任何依賴伺服器且無法離線運作的操作都不應該依賴同步引擎。 2. 任何處理無法安裝在使用者電腦上的龐大資料集的應用程式。例如,建立本地優先版本的 Google 或處理千兆位元組資料以產生結果的分析工具是不切實際的。然而,在部分同步就足夠的情況下,同步引擎仍然是有益的。例如,Google地圖可以在客戶端裝置上下載和快取地圖以進行離線操作,而無需始終提供全球每個位置的高解析度地圖。 關於開發人員生產力和 DX 的一句話 ------------------ 我的印像是,擁有同步引擎可以讓 DX(開發人員體驗)變得更好。前端工程師只需與普通商店合作即可訂閱更新,並且 UI 始終保持最新狀態。無需考慮為同步引擎控制的應用程式部分取得任何內容、呼叫 API 或伺服器操作。至於後端,我還不能說太多。看起來它不會比傳統後端難,但我不能肯定。 ### 結束語 令人興奮的是,將網路應用程式的未來想像為全球範圍內的即時多人協作工具,無論網路條件如何,都可以可靠地工作,同時解決這些令人討厭的問題,我以過去的事情開始這篇文章。 我強烈建議網頁開發人員熟悉這些新概念,嘗試它們,甚至做出貢獻。 謝謝閱讀。如果您有任何問題或想法,請發表評論。和平。 。 **聚苯乙烯** 建立 Replicache 公司的創辦人 Aaron Boodman 的[訪談](https://youtu.be/cgTIsTWoNkM?si=Sssrbj09Z936QxEf)非常棒。觀看並稍後感謝我。 --- 原文出處:https://dev.to/isaachagoel/are-sync-engines-the-future-of-web-applications-1bbi

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

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

只需 2GB 記憶體即可將後端擴展到 1M 請求 ⚡️

本部落格介紹了我如何解鎖效能,使我能夠在最少的資源(2 GB RAM 1v CPU 和最小網路頻寬 50-100 Mbps)上將後端從 50K 請求擴展到 1M 請求(~16K 請求/分鐘)。 ![迷因](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b0m1kiuyq575f2qzyweu.png) 它將帶你踏上一段與過去的自己的旅程。這可能是一段漫長的旅程,所以請繫緊安全帶,享受這段旅程! 🎢 *它假設您熟悉後端和編寫 API。如果你了解一點 Go,這也是一個優勢。如果你不這樣做,也沒關係。您仍然可以按照我提供的資源來幫助您理解每個主題。 (如果您不知道 GO,這裡有一個*[*快速介紹*](https://www.youtube.com/watch?v=446E-r0rXHI)*)* 長話短說;博士, 首先,我們建立一個[可觀察性管道](https://www.observo.ai/post/what-is-an-observability-pipeline),幫助我們監控後端的所有面向。然後,我們開始對後端進行壓力測試,直到斷點測試(當一切最終崩潰時)。 →[連接輪詢以避免達到最大連接閾值](#optimization-1-connection-pooling-️) →[實施資源限制以避免非關鍵服務佔用資源](#optimization-2-unblocking-resources-from-alloy-open-telemetry-collector) →[新增索引](#optimization-3-adding-indexes-🏎️) →[禁用隱式事務](#optimization-4-ensure-while-testing-there-is-no-blocking-transaction) →[增加 Linux 的最大檔案描述符限制](#optimization-6-increasing-the-max-file-descriptor-limit) →[限制 Goroutines](#optimization-7-avoid-overloading-goroutines) →[未來計劃](#next-steps) 後端簡介🤝 ----- 讓我簡單介紹一下後端, - 它是一個用 Golang 寫的整體 RESTful API。 - 使用[GIN](https://github.com/gin-gonic/gin)框架編寫,並使用[GORM](https://gorm.io/)作為[ORM](https://www.theserverside.com/definition/object-relational-mapping-ORM) 。 - 使用 Aurora Postgres 作為託管在 AWS RDS 上的唯一主資料庫。 - 後端是[Docker 化的](https://dev.to/documatic/how-to-dockerize-your-application-536i#:~:text=Dockerizing%20an%20application%20is%20the,for%20developers%20and%20organizations%20alike.),我們在 AWS 上的`t2.small`實例中執行它。它具有 2GB RAM、50-100mb/s 網路頻寬、1 個 vCPU。 - 後端提供身份驗證、CRUD 操作、推播通知和即時更新。 - 對於即時更新,我們打開一個非常輕量級的[Web 套接字連接](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API),通知設備實體已更新。 我們的應用程式主要是讀取密集型,具有下降的寫入活動,如果我必須給它一個比率,它將是 65% 讀取/35% 寫入。 我可以寫一篇單獨的部落格來解釋我們為什麼選擇 - 整體架構、golang 或 postgress,但為了向您介紹[MsquareLabs 的](www.msquarelabs.com)tl;dr,我們相信「保持簡單,並建立允許我們以驚人的快節奏前進的程式碼。 資料資料資料🙊 ------- 在進行任何模擬負載生成之前,我首先將可觀察性建置到我們的後端中。其中包括追蹤、指標、分析和日誌。這使得找到問題並準確地找出造成疼痛的原因變得非常容易。當您對後端擁有如此強大的監控能力時,您也可以更輕鬆地更快地追蹤生產問題。 在我們繼續之前,讓我先簡單介紹一下指標、分析、日誌和追蹤: - 日誌:我們都知道日誌是什麼,它只是我們在事件發生時建立的大量文字訊息。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/94b2970c-34fc-4135-bed0-bf763ef098c8) - 追蹤:這是高度可見性的結構化日誌,有助於我們以正確的順序和時間封裝事件。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/9ee944e8-0637-4aa9-b076-5ff35990a8e2) - 指標:所有數字攪動資料,例如 CPU 使用率、活動請求和活動 goroutine。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/ec9a493d-6344-4c10-80e6-0db8c5c1d219) - 分析:為我們提供程式碼的即時指標及其對機器的影響,幫助我們了解正在發生的情況。 (WIP,下一篇部落格會詳細講) 要了解有關我如何將可觀察性建置到後端的更多訊息,您可以研究下一個博客(WIP),我將此部分移至另一個博客,因為我想避免讀者不知所措並只關註一件事 -**優化**) 這就是追蹤、日誌和指標的視覺化的樣子, ![截圖 2024-05-30 下午 4.53.29.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/20883b44-6f0f-42a1-b4f0-ae6ac2c04642) 所以現在我們有一個強大的監控管道+一個像樣的儀表板作為開始🚀 嘲笑高級用戶 x 100,000 🤺 ------------------ 現在真正的樂趣開始了,我們開始嘲笑愛上該應用程式的用戶。 「只有當你把你的愛(後端)置於極大的壓力時,你才會發現它的真正本質✨」 - 某個偉大的人,哈哈,idk Grafana 還提供了一個負載測試工具,因此我決定使用它,因為它只需要幾行程式碼的最少設置,因此您已經準備好了模擬服務。 我沒有觸及所有 API 路線,而是專注於最關鍵的路線,這些路線負責我們 90% 的流量。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/e42d706f-fc61-4cdd-8b0e-35113761f09c) 關於[k6](https://k6.io)的簡單介紹,它是一個基於 javascript 和 golang 的測試工具,您可以在其中快速定義要模擬的行為,它負責對其進行負載測試。無論您在主函數中定義什麼,都稱為*迭代*,k6 會啟動多個虛擬使用者單元(VU)來處理此迭代,直到達到給定的週期或迭代計數。 每次迭代構成4個請求,建立任務→更新任務→取得任務→刪除任務 ![iLoveIMG 下載 (1).jpg](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/32cb71fb-d549-48c9-88a0-ecaf48296593/c7dcc3cb-4128-44d4-b3ad-e736c96e377b) 慢慢開始,讓我們看看大約 10K 請求 → 100 VU 和 30 iter → 3000 iters x 4reqs → 12K 請求情況如何 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/84f31eec-79d5-49f9-915f-bb97b6d5f517) 這是輕而易舉的事情,沒有任何記憶體洩漏、CPU 過載或任何類型瓶頸的跡象,萬歲! 這是 k6 的摘要,發送了 13MB 資料,接收了 89MB,平均超過 52 req/s,平均延遲為 278ms,考慮到所有這些都在單台機器上執行,這還不錯。 ``` checks.........................: 100.00% ✓ 12001 ✗ 0 data_received..................: 89 MB 193 kB/s data_sent......................: 13 MB 27 kB/s http_req_blocked...............: avg=6.38ms min=0s med=6µs max=1.54s p(90)=11µs p(95)=14µs http_req_connecting............: avg=2.99ms min=0s med=0s max=536.44ms p(90)=0s p(95)=0s ✗ http_req_duration..............: avg=1.74s min=201.48ms med=278.15ms max=16.76s p(90)=9.05s p(95)=13.76s { expected_response:true }...: avg=1.74s min=201.48ms med=278.15ms max=16.76s p(90)=9.05s p(95)=13.76s ✓ http_req_failed................: 0.00% ✓ 0 ✗ 24001 http_req_receiving.............: avg=11.21ms min=10µs med=94µs max=2.18s p(90)=294µs p(95)=2.04ms http_req_sending...............: avg=43.3µs min=3µs med=32µs max=13.16ms p(90)=67µs p(95)=78µs http_req_tls_handshaking.......: avg=3.32ms min=0s med=0s max=678.69ms p(90)=0s p(95)=0s http_req_waiting...............: avg=1.73s min=201.36ms med=278.04ms max=15.74s p(90)=8.99s p(95)=13.7s http_reqs......................: 24001 52.095672/s iteration_duration.............: avg=14.48s min=1.77s med=16.04s max=21.39s p(90)=17.31s p(95)=18.88s iterations.....................: 3000 6.511688/s vus............................: 1 min=0 max=100 vus_max........................: 100 min=100 max=100 running (07m40.7s), 000/100 VUs, 3000 complete and 0 interrupted iterations _10k_v_hits ✓ [======================================] 100 VUs 07m38.9s/20m0s 3000/3000 iters, 30 per VU ``` 讓我們增加 12K → 100K 請求,發送 66MB,接收 462MB,CPU 使用率峰值達到 60%,記憶體使用率達到 50%,執行需要 40 分鐘(平均 2500 個請求/分鐘) ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/838e351e-ac9e-47a1-af51-4f69f75f5de0) 一切看起來都很好,直到我在日誌中看到一些奇怪的東西,“::gorm: 連接太多::”,快速檢查RDS 指標,確認打開的連接已達到410,即最大打開連接的限制。它是由 Aurora Postgres 本身[根據實例的可用記憶體](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Managing.html#AuroraPostgreSQL.Managing.MaxConnections)設定的。 您可以透過以下方法檢查, `select * from pg_settings where name='max_connections';` ⇒ 410 Postgres 為每個連接產生一個進程,考慮到它會在新請求到來時打開一個新連接並且之前的查詢仍在執行,因此這是極其昂貴的。因此 postgress 對可以開啟的並發連線數進行了限制。一旦達到限制,它會阻止任何進一步連接資料庫的嘗試,以避免實例崩潰(這可能會導致資料遺失) ### 優化一:連接池⚡️ 連接池是一種管理資料庫連接的技術,它重用打開的連接並確保它不會超過閾值,如果客戶端請求連接並且超過最大連接限制,它會等待直到連接被釋放或拒絕該請求。 這裡有兩個選項,要么執行客戶端池,要么使用單獨的服務,例如[pgBouncer](pgbouncer.org) (充當代理)。當我們規模較大且我們有連接到相同資料庫的分散式架構時,pgBouncer 確實是一個更好的選擇。因此,為了簡單性和我們的核心價值觀,我們選擇繼續進行客戶端池化。 幸運的是,我們使用的 ORM GORM 支援連接池,但[在幕後使用資料庫/SQL](https://gorm.io/docs/connecting_to_the_database.html#Connection-Pool) (golang 標準套件)來處理它。 有一些非常簡單的方法可以處理這個問題, ``` configSQLDriver, err := db.DB() if err != nil { log.Fatal(err) } configSQLDriver.SetMaxIdleConns(300) configSQLDriver.SetMaxOpenConns(380) // kept a few connections as buffer for developers configSQLDriver.SetConnMaxIdleTime(30 * time.Minute) configSQLDriver.SetConnMaxLifetime(time.Hour) ``` - `SetMaxIdleConns` → 保留在記憶體中的最大空閒連接,以便我們可以重複使用它(有助於減少開啟連接的延遲和成本) - `SetConnMaxIdleTime` → 我們應該在記憶體中保留空閒連接的最長時間。 - `SetMaxOpenConns` → 與資料庫的最大開啟連接,因為我們在同一個 RDS 實例上執行兩個環境 - `SetConnMaxLifetime` → 任何連線保持開啟的最長時間 現在更進一步,500K 請求(4000 個請求/分鐘)和 20 分鐘伺服器崩潰💥,最後讓我們調查一下🔎 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/39787835-b83d-441a-a3aa-a3b9fb03fc26) 快速查看指標,然後砰! CPU 和記憶體使用量激增。 Alloy(開放遙測收集器)佔用了所有 CPU 和內存,而不是我們的 API 容器。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/e8e764e4-31ea-44fa-b930-1bd1746d131b) ### 優化二:合金資源解鎖(開放式遙測收集器) 我們在小型 t2 實例中執行三個容器, - API開發 - API 分期 - 合金 當我們將大量負載轉儲到 DEV 伺服器時,它開始以相同的速率產生日誌和跟踪,從而呈指數級增加 CPU 使用率和網路出口。 因此,確保合金容器不會超出資源限制並妨礙關鍵服務非常重要。 由於合金在 docker 容器內執行,因此更容易強制執行此約束, ``` resources: limits: cpus: '0.5' memory: 400M ``` 此外,這次日誌不為空,存在多個上下文取消錯誤 - 原因是請求逾時,並且連接突然關閉。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/ace0ce7e-990e-43ea-a871-dc18888e3968) 然後我檢查了延遲,這太瘋狂了 😲 經過一段時間後,平均延遲為 30 - 40 秒。多虧了跟踪,我現在可以準確地找出是什麼導致瞭如此巨大的延遲。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/04be9892-5791-4834-b418-e9f417c0781d) 我們在 GET 操作中的查詢非常慢,讓我們對查詢執行[`EXPLAIN ANALYZE`](https://www.postgresql.org/docs/current/sql-explain.html) , ![截圖 2024-06-11 9.55.10 PM.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/3cf82d23-53c5-4976-aacc-2fa0d6ab2353) LEFT JOIN 花了 14.6 秒,而 LIMIT 又花了 14.6 秒,我們如何優化它 - INDEXING ### 優化3:新增索引🏎️ 為`where`或`ordering`子句中常用的欄位新增索引可以將查詢效能提高五倍。在新增 LEFT JOIN 表和 ORDER 欄位的索引後,相同查詢花費了 50 毫秒。你能從**14.6 秒 ⇒ 50 毫秒**開始思考嗎? (但要注意盲目加入索引,會導致CREATE/UPDATE/DELETE慢死) 它還可以更快地釋放連接,並有助於提高處理巨大並發負載的整體能力。 ### 最佳化 4:確保測試時沒有阻塞 TRANSACTION 🤡 從技術上講不是優化而是修復,您應該記住這一點。當您進行壓力測試時,您的程式碼不會嘗試同時更新/刪除相同實體。 在檢查程式碼時,我發現了一個錯誤,該錯誤導致每次請求時都會對用戶實體進行更新,並且當在事務內執行每個更新呼叫時,這會建立一個鎖,幾乎所有更新呼叫都被以前的更新呼叫阻止。 僅此一項修復就將吞吐量提高至 2 倍。 ### 最佳化5:跳過 GORM 的隱式 TRANSACTION 🎭 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/ab40af5b-c0fd-4c18-9067-859df56c4ec0) 預設情況下,GORM 在事務中執行每個查詢,這會降低效能,因為我們擁有極其強大的事務機制,在關鍵區域丟失事務的機會幾乎是不可能的(除非他們是實習生🤣)。 我們有一個中間件可以在到達模型層之前建立事務,並且有一個集中函數來確保控制器層中該事務的提交/回滾。 透過停用此功能,我們可以獲得[至少約 30% 的效能提升](https://gorm.io/docs/transactions.html#Disable-Default-Transaction)。 “我們卡在每分鐘 4-5K 請求的原因是這個,我認為這是我的筆記型電腦網路頻寬的問題。” - 愚蠢的我 所有這些優化帶來了 5 倍的吞吐量增益 💪,現在光是我的筆記型電腦就可以每分鐘產生 12K-18K 請求的流量。 ![截圖 2024-06-12 7.20.27 PM.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/fd440164-255f-4a4d-8389-c14365472372) ### 百萬點次數🐉 最後,每分鐘 10k-13K 請求達到 100 萬次,大約需要 2 小時,本來應該早點完成,但隨著合金重新啟動(由於資源限制),所有指標都會隨之丟失。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/6561ab09-1eb6-4b6f-92f2-92b5b2818590) 令我驚訝的是,該時間段內的最大 CPU 使用率為 60%,而記憶體使用量僅為 150MB。 Golang 的效能如此之高且處理負載的能力如此出色,這真是太瘋狂了。它具有最小的記憶體佔用。就是愛上了 golang 💖 每個查詢需要 200-400 毫秒才能完成,下一步是找出為什麼需要這麼多時間,我的猜測是連接池和 IO 阻塞減慢了查詢速度。 平均延遲降至約 2 秒,但仍有很大改進空間。 隱式優化🕊️ ------ ### 優化6:增加最大檔案描述子限制🔋 當我們在 Linux 作業系統中執行後端時,我們打開的每個網路連線都會建立一個檔案描述符,預設為 Linux 將每個進程限制為 1024 個,這阻礙了它達到峰值效能。 當我們開啟多個 Web 套接字連線時,如果有大量並發流量,我們很容易就會達到此限制。 Docker compose 提供了一個很好的抽象, ``` ulimits: core: soft: -1 hard: -1 ``` ### 優化 7:避免 goroutine 過載 🤹 作為一個 Go 開發者,我們經常認為 Goroutine 是理所當然的,只是盲目地在 Goroutine 中執行許多非關鍵任務,我們在函數之前加入`go` ,然後忘記它的執行,但在極端情況下它可能會成為瓶頸。 為了確保它永遠不會成為我的瓶頸,對於經常在 goroutine 中執行的服務,我使用帶有 n-worker 的記憶體佇列來執行任務。 ![圖片.png](https://res.craft.do/user/full/66854ea9-b711-5e28-ddbd-8d28e1defc9f/doc/355f2532-e0ec-485f-97e2-472751298750/b00e6636-6b3f-472e-99fc-f6c66ee87186) 後續步驟🏃‍♀️ -------- ### 改進:從 t2 移動到 t3 或 t3a t2是老一代的AWS通用機器,而t3和t3a、t4g是新一代。它們是可突發的實例,與 t2 相比,它們為長時間的 CPU 使用提供更好的網路頻寬和更好的效能 了解突發實例, [AWS 引入了可突發執行個體](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances.html)類型,主要針對大多數時間不需要 100% CPU 的工作負載。因此,這些實例以基準效能 (20% - 30%) 運作。當您的實例不需要 CPU 時,他們會維護一個積分系統,它會累積積分。當 CPU 峰值發生時,它會使用該積分。這可以降低您的 AWS 運算成本和浪費。 t3a 將是一個值得堅持的好系列,因為它們的成本/效率比在可突發實例係列中好得多。 這是一個比較[t2 和 t3 的](https://www.cloudzero.com/advisor/t2-vs-t3/)不錯的部落格。 ### 改進:查詢 我們可以對查詢/模式進行許多改進來提高速度,其中一些是: - 在插入重型表中批量插入。 - 透過非規範化避免 LEFT JOIN - 快取層 - 著色和分區,但這要晚得多。 ### 改進:分析 釋放效能的下一步是啟用分析並弄清楚執行時到底發生了什麼。 ### 改進:斷點測試 為了發現我的伺服器的限制和容量,下一步是斷點測試。 ### 尾註👋 如果你讀到最後,你已經破解了,恭喜你🍻 這是我的第一篇博客,如果有不清楚的地方,或者您想更深入地了解該主題,請告訴我。在我的下一篇部落格中,我將深入研究分析,敬請關注。 您可以在[X](x.com/_rikenshah)上關注我,以獲取最新資訊:) --- 原文出處:https://dev.to/rikenshah/scaling-backend-to-1m-requests-with-just-2gb-ram-4m0c

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

系統設計面試中 Docker、Kubernetes 和 Podman 有何不同?

*揭露:這篇文章包含附屬連結;如果您透過本文中提供的不同連結購買產品或服務,我可能會獲得補償。* ![Docker、Kubernetes 和 Podman 之間的差異?](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7lmxnjetsoayumogkorw.png) 朋友們大家好,如果您正在準備技術面試,那麼您必須為 Docker 和 Kubernetes 等容器技術做好準備,因為容器現在用於部署大多數應用程式,包括微服務和單體應用。 如今,系統設計和軟體開發人員面試中最常見的問題之一是**Docker、Kubernetes 和 Podman 之間的差異?它們是什麼以及何時使用它們**。 過去我討論過[API網關與負載平衡器、](https://dev.to/somadevtoo/difference-between-api-gateway-and-load-balancer-in-system-design-54dd)[水平與垂直擴展](https://dev.to/somadevtoo/horizontal-scaling-vs-vertical-scaling-in-system-design-3n09)、 [正向代理與反向代理](https://dev.to/somadevtoo/difference-between-forward-proxy-and-reverse-proxy-in-system-design-54g5)等系統設計問題,今天我將回答Docker、Kubernetes和Podman之間的差異。 Docker、Kubernetes 和 Podman 都是受歡迎的容器化工具,讓開發人員和 DevOps 以一致且高效的方式打包和部署應用程式。 **Docker**是流行的容器化平台,允許開發人員在容器中建立、部署和執行應用程式。 Docker 提供了一組工具和 API,使開發人員能夠建置和管理容器化應用程式,包括 Docker Engine、Docker Hub 和 Docker Compose。 另一方面, **Kubernetes**是一個開源容器編排平台,可以自動化容器化應用程式的部署、擴展和管理。 Kubernetes 還提供了一組 API 和工具,使開發人員能夠在多個主機和環境中大規模部署和管理容器化應用程式。 而\*\*,Podman\*\*是一個相對較新的容器化工具,與Docker類似,但架構不同。 Podman 不需要守護程序來執行容器,並且它與 Docker 映像和註冊表相容。 Podman 提供了一個簡單的命令列介面來建立和管理容器,在許多情況下它可以用作 Docker 的直接替代品。 現在我們已經基本了解它們是什麼以及它們的作用,讓我們深入研究它們以了解它們是如何工作的。 順便說一句,如果您正在準備系統設計面試並想深入學習系統設計,那麼您還可以查看[**ByteByteGo**](https://bit.ly/3P3eqMN) 、 [**Design Guru**](https://bit.ly/3pMiO8g) 、 [**Exponent**](https://bit.ly/3cNF0vw) 、 [**Educative**](https://bit.ly/3Mnh6UR)和[**Udemy**](https://bit.ly/3vFNPid)等網站,它們有許多很棒的系統設計課程 [![如何回答系統設計問題](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%2Fxd9nfio7kl57gyevndql.jpg)](https://bit.ly/3pMiO8g) PS 繼續閱讀直到最後。我有一份免費獎金給你。 --- 什麼是 Docker?它是如何運作的? ------------------- 正如我所說,Docker 是一個開源平台,使開發人員能夠在容器內自動部署和管理應用程式。 它提供了*一種將應用程式及其相依性打包到稱為容器的標準化單元中的方法,*該單元可以在任何相容的系統上執行,而無需擔心作業系統或底層基礎設施的差異。 身為開發人員或 DevOps 工程師,您應該了解以下幾個重要的 Docker 概念: **1. 容器化** Docker 利用容器化技術建立隔離的環境(稱為容器)來執行應用程式。容器是輕量級的,封裝了執行應用程式所需的應用程式程式碼、執行時間、系統工具、程式庫和相依性。 這使得應用程式能夠在不同的環境中一致地執行,確保無論底層系統如何,它們的行為都是相同的。 **2. Docker 映像** Docker 映像可作為建立容器的範本。它是一個只讀快照,包含應用程式程式碼和所有必要的依賴項。 Docker 映像是使用`Docker file`建立的,該文件是一個文字文件,指定建置映像的步驟。 `Dockerfile`中的每個步驟代表映像中的一個層,從而實現映像的高效儲存和共用。 **3.Docker引擎** Docker Engine是Docker的核心元件。它負責建置和執行基於Docker映像的容器。 Docker 引擎包括管理容器的伺服器和允許使用者與 Docker 互動的命令列介面 (CLI)。 **4. Docker 註冊表** Docker 映像可以儲存在登錄中,例如 Docker Hub 或私有註冊表。註冊表是`Docker`映像的集中儲存庫,可輕鬆地在不同系統之間共用和分發映像。開發人員可以從登錄中提取預先建置的映像,或推送自己的自訂映像供其他人使用。 **5. 容器生命週期** 為了執行應用程式, [Docker](https://medium.com/javarevisited/5-best-docker-courses-for-java-and-spring-boot-developers-bbf01c5e6542)從映像建立容器。容器是隔離的,有自己的檔案系統、流程和網路介面。 它們可以根據需要啟動、停止、暫停和刪除。 Docker 提供了一組命令和 API 來管理容器的生命週期,從而可以輕鬆擴展、更新和監控。 **6. 容器編排** 雖然[Docker](https://medium.com/javarevisited/why-every-developer-should-learn-docker-in-2023-ac27fac5fd6f)本身提供了容器管理功能,但它還可以與 Kubernetes 等容器編排平台無縫協作。 這些平台支援管理大型容器集群,處理負載平衡、擴展和跨多個主機的自動部署等任務。 總體而言, **Docker 利用容器化技術簡化了應用程式的打包、分發和執行過程。**它幫助開發人員實現應用程式的一致性、可移植性和可擴展性,使其成為現代軟體開發和部署工作流程中的熱門選擇。 這也是[ByteByteGo](https://bit.ly/3P3eqMN)的一個很好的圖表,它突出顯示了 Docker 的關鍵元件及其工作原理: [ ![Docker 是如何運作的](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i8jbisa4dxd0k9tju7va.jpg)](https://bit.ly/3P3eqMN) --- 什麼是 Kubernetes?它是如何運作的? ----------------------- Docker 和 Kubernetes 就像兄弟一樣,經常被一起提及,但它們卻有很大不同。 [Kubernetes](https://medium.com/javarevisited/10-best-kubernetes-courses-for-developers-and-devops-engineers-94c35cd3a2fd)是一個開源容器編排平台,可自動執行容器化應用程式的部署、擴充和管理。 它**提供了一個框架,用於跨機器叢集執行和協調多個容器**,從而更輕鬆地管理複雜的分散式系統。 以下是我認為每個開發人員或 DevOps 都應該學習和了解的重要 Kubernetes 或 K8 概念: **1. 集群架構** Kubernetes 以叢集架構執行,由一個主節點和多個工作節點組成。主節點管理叢集並協調整體操作,而工作節點負責執行容器。 **2. Pod** Kubernetes 中的基本部署單元是 Pod。 Pod 是一個或多個容器的邏輯群組,這些容器位於同一位置並共享相同的資源,例如網路命名空間和儲存。 Pod 內的容器可以使用 localhost 相互通訊。 Pod 被視為臨時單元,可輕鬆建立、更新或終止。 **3. 副本集和部署** 副本集定義了在任何給定時間執行的相同 Pod 副本的所需數量。 它們透過自動管理和維護所需數量的 Pod 執行個體來確保高可用性和可擴充性。 部署是一種更高層次的抽象,可讓您以聲明方式管理和更新副本集,從而實現應用程式版本的無縫滾動更新和回滾。 **4. 服務** Kubernetes 服務提供穩定的網路端點來連接到一組 Pod。它們支援負載平衡並將 Pod 內的容器公開給其他服務或外部用戶端。 服務抽象化了底層的 Pod 實例,允許應用程式與其他元件進行通信,而無需擔心它們的動態特性。 **5. 標籤和選擇器** Kubernetes 使用標籤和選擇器來實現靈活、動態的物件分組和選擇。標籤是附加到 Pod、部署、服務和其他 Kubernetes 物件的鍵值對。 選擇器用於根據物件的標籤過濾和匹配物件,從而可以進行有針對性的操作並對相關資源進行分組。 **6. 縮放和自動縮放** Kubernetes 可讓您透過調整 pod 副本的數量來擴展應用程式。 Pod 水平自動擴展 (HPA) 是一項根據資源利用率指標(例如 CPU 或記憶體使用情況)自動擴展 Pod 副本數量的功能。 **7. 容器網絡** Kubernetes 也管理 Pod 和節點之間的網路。每個 Pod 都有自己的 IP 位址,Pod 內的容器可以使用`localhost`相互通訊。 Kubernetes 提供了**網路插件**,可以促進容器網路並實現跨 Pod 和叢集的通訊。 **8. 集群管理** Kubernetes 還提供廣泛的叢集管理功能,包括捲動更新、機密管理、設定管理和執行狀況監控。 它提供了一種聲明式方法來定義系統的所需狀態,使 Kubernetes 能夠持續監控實際狀態並將其與所需狀態進行協調。 **9. 貨櫃存放** Kubernetes 支援各種儲存選項,包括持久磁碟區和儲存類別。持久卷提供了一種將儲存與 Pod 生命週期分離的方法,從而實現跨 Pod 和容器重新啟動的資料持久化和共享。 透過抽象化*大規模管理容器的複雜性,Kubernetes 使開發人員能夠專注於應用程式邏輯*而不是基礎架構管理。 它提供了一個強大且可擴展的平台,用於部署和管理容器化應用程式,使其成為建置現代雲端原生系統的流行選擇。 這是一個很好的圖表,顯示了 K8 或 Kubernetes 的不同元件以及它們如何協同工作: ![什麼是 Kubernetes](https://miro.medium.com/v2/resize:fit:609/0*pRm7KUB_3307GXS2.png) --- Podman 是什麼?它是如何運作的? --------------- 現在您已經知道什麼是 Docker 和 Kubernetes,是時候看看另一個流行的工具 Podman,它通常被視為 Docker 的替代品。 Podman 是一個開源容器執行時間和管理工具,提供用於管理容器的命令列介面 (CLI)。 它旨在成為 Docker 的兼容替代方案,提供與 Docker 相容的 API,並允許熟悉 Docker 的用戶輕鬆過渡\*。 Podman 設計提供安全且輕量的容器體驗。 以下概述了 Podman 的工作原理以及您應該了解的重要 Podman 概念: **1. 容器運作時** Podman 作為容器執行時,這意味著它可以建立和執行容器。它使用相容於開放容器計劃 (OCI) 的容器格式,確保與其他容器執行時的兼容性,並允許 Podman 執行符合 OCI 的容器。 **2. CLI 相容性** Podman 的 CLI 旨在讓 Docker 用戶熟悉。它提供類似於 Docker CLI 的命令,讓使用者可以輕鬆管理容器、映像、磁碟區和網路。 這種相容性使開發人員和系統管理員可以更輕鬆地從 Docker 過渡到 Podman,而無需對其工作流程進行重大更改。 **3.無根容器** Podman 的一項顯著功能是它對無根容器的支援。它允許非 root 用戶無需特權存取即可執行容器。 這透過將容器與主機系統隔離並降低容器逃逸的風險來增強安全性。 **4. 容器管理** Podman 提供一系列管理功能,例如建立、啟動、停止和刪除容器。它支援網路配置,允許容器之間以及主機系統之間進行通訊。 Podman 還提供了管理容器磁碟區、環境變數和資源限制的選項。 **5. 容器鏡像** 與 Docker 一樣,Podman 依賴容器映像作為建立容器的基礎。它可以從各種容器註冊表(包括 Docker Hub)中提取和推送容器映像。 Podman 也可以使用 Dockerfile 在本機建置映像或從其他容器執行時匯入映像。 **6. Pod 支持** Podman 超越了單一容器,支援 Pod 的概念,類似 Kubernetes。 Pod 是一組共享相同網路命名空間和資源的容器。 Podman 讓使用者可以建立和管理 Pod,從而實現容器之間更複雜的部署和通訊模式。 **7. 與編排平台集成** 雖然 Podman 可以用作獨立的容器執行時,但它也可以與 Kubernetes 等容器編排平台整合。它可以充當 Kubernetes Pod 的容器執行時,允許使用者在 Kubernetes 叢集中利用 Podman 的功能和相容性。 **8. 安全焦點** Podman 非常重視安全性。它支援使用者命名空間映射等功能,將容器使用者ID映射到主機上的非root使用者ID,從而增強容器隔離。 Podman 還整合了 SELinux 和 seccomp 設定檔等安全增強技術,以提供額外的保護層。 Podman 旨在為 Docker 用戶提供無縫過渡,同時強調安全性和輕量級容器管理。 它提供相容性、靈活性和用戶友好的 CLI,對於尋求替代容器執行時的人來說是一個引人注目的選擇。 ![什麼是 Podman](https://miro.medium.com/v2/resize:fit:609/1*bFTJH7TCRebunX4CXhr7Uw.png) --- Docker、Kubernetes 和 Podman 之間有什麼區別? ----------------------------------- 以下是 Docker、Kubernetes 和 Podman 之間的主要區別,我對它們的不同點進行了比較,主要是這些工具提供的功能和功能,例如容器化和容器管理等。 **1. 容器引擎** Docker 主要是用於建置、執行和分發容器的容器執行時和引擎。另一方面,Kubernetes 是一個編排平台,旨在管理跨機器叢集的容器化應用程式。 Podman 是一個容器執行時間和管理工具,提供與 Docker 相容的 CLI 和容器執行時間。 **2. 容器格式** Docker 使用自己的容器格式,稱為 Docker 容器。 [Kubernetes](https://medium.com/javarevisited/7-free-online-courses-to-learn-kubernetes-in-2020-3b8a68ec7abc)可以使用多種容器格式,但 Docker 容器是最常見的選擇。 另一方面,Podman 使用相容於開放容器計劃 (OCI) 的容器格式,並且可以執行符合 OCI 的容器。 **3. 編排** Docker 擁有內建的編排工具 Docker Swarm,它允許管理一組用於執行容器的 Docker 節點。 另一方面,Kubernetes 提供了用於管理容器化應用程式的高級編排功能,包括擴充功能、負載平衡、自動化部署和自我修復。 Podman 沒有像 Docker Swarm 或 Kubernetes 這樣的內建編排功能,但它可以與 Kubernetes 或其他編排平台一起工作。 **4. 集群管理** Docker 本身不支援管理容器叢集。另一方面,Kubernetes 是專門為管理容器叢集而設計的,並提供擴展、升級、監控和管理容器化應用程式的功能。 Podman 本身不支援管理容器集群,但可以與 Kubernetes 或其他容器編排框架等外部工具一起使用。 **5. 安全** 對於安全性比較,Docker 提供了基本的隔離和安全功能,但其主要重點是執行單一容器。 Kubernetes 提供進階安全功能,例如網路策略、秘密管理和 RBAC。 另一方面, **Podman**專注於安全性,並提供使用者命名空間映射、seccomp 設定檔和 SELinux 整合等功能,以增強容器安全性。 **6. 使用者介面** 相較於 UI, [Docker](https://medium.com/javarevisited/10-free-courses-to-learn-docker-and-devops-for-frontend-developers-691ac7652cee)提供了使用者友善的 CLI 和基於 Web 的圖形介面(Docker Desktop)來管理容器。 Kubernetes 有一個名為`"kubectl"`的 CLI 工具和一個基於 Web 的儀表板(Kubernetes Dashboard),用於管理容器和叢集。 同時,Podman 提供了類似 Docker CLI 的 CLI,可以與`Cockpit`等第三方工具一起使用,進行基於 Web 的管理。 而且,如果您喜歡表格,這裡有一個很好的表格,我以表格格式列出了*Docker、Kubernetes 和 Podman 之間的所有差異*: ![docker、kubernetes 和 podman 之間的區別](https://miro.medium.com/v2/resize:fit:609/1*Q4wN6VE6C_0LoWc1PqgTzg.png) 這些是*Docker、Kubernetes 和 Podman 之間的根本區別*,它們在容器化生態系統中服務於不同的目的。 --- ### 系統設計訪談資源: 而且,這裡列出了最佳系統設計書籍、線上課程和練習網站,您可以查看這些內容,以便更好地為系統設計面試做好準備。這些課程中的大多數也回答了我在這裡分享的問題。 1. [**DesignGuru 的 Grokking 系統設計課程**](https://bit.ly/3pMiO8g):一個互動式學習平台,提供實作練習和真實場景,以增強您的系統設計技能。 2. [**《系統設計面試》作者:Alex Xu**](https://amzn.to/3nU2Mbp) :這本書深入探討了系統設計概念、策略和麵試準備技巧。 3. Martin Kleppmann 的[**「設計資料密集型應用程式」**](https://amzn.to/3nXKaas) :綜合指南,涵蓋了設計可擴展且可靠的系統的原則和實踐。 4. [LeetCode 系統設計 標籤](https://leetcode.com/explore/learn/card/system-design):LeetCode 是一個受歡迎的技術面試準備平台。 LeetCode 上的系統設計標籤包含各種練習問題。 5. GitHub 上的[**「系統設計入門」**](https://bit.ly/3bSaBfC) :精選的資源列表,包括文章、書籍和影片,可幫助您準備系統設計面試。 6. [**Educative 的系統設計課程**](https://bit.ly/3Mnh6UR):一個互動式學習平台,提供實作練習和真實場景,以增強您的系統設計技能。 7. **高可擴展性部落格**:該部落格包含有關高流量網站和可擴展系統架構的文章和案例研究。 8. **[YouTube 頻道](https://medium.com/javarevisited/top-8-youtube-channels-for-system-design-interview-preparation-970d103ea18d)**:請參閱「Gaurav Sen」和「Tech Dummies」等頻道,以取得有關係統設計概念和麵試準備的富有洞察力的影片。 9. [**ByteByteGo**](https://bit.ly/3P3eqMN) :Alex Xu 的一本現場書籍和課程,用於系統設計面試準備。它包含《系統設計訪談》第一捲和第二卷的所有內容,並將隨即將推出的第三卷進行更新。 10. [**Exponent**](https://bit.ly/3cNF0vw) :一個專為面試準備的網站,特別是針對亞馬遜和谷歌等 FAANG 公司,他們還有很棒的系統設計課程和許多其他材料,可以幫助您破解 FAAN 面試。 [![如何為系統設計做準備](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%2Fkqv3p46jmw5qc0newuiu.jpg)](https://bit.ly/3P3eqMN) image\_credit - [ByteByteGo](https://bit.ly/3P3eqMN) 這就是**Docker、Kubernetes 和 Podman 之間的差異。**總之,Docker 是一個用於建立和管理容器的流行容器化平台,Kubernetes 是一個用於大規模管理容器化應用程式的容器編排平台,而`Podman`是一個具有不同架構的容器化工具,可以用作Docker的直接替代品在很多情況下。 這些工具都有不同的用途,它們都可以一起使用,為開發人員提供全面的容器化解決方案,但更重要的是每個開發人員和 DevOps 都應該了解這些工具。 ### 獎金 正如承諾的,這是給你的獎金,一本免費的書。我剛剛找到一本新的免費書籍來學習分散式系統設計,您也可以在 Microsoft 上閱讀它 --- [https://info.microsoft.com/rs/157-GQE-382/images/EN-CNTNT -eBook-設計分散式系統.pdf](https://info.microsoft.com/rs/157-GQE-382/images/EN-CNTNT-eBook-DesigningDistributedSystems.pdf) [![學習分散式系統的免費書籍](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%2Fhrc1jn751mzs4ru91zt3.png)](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrc1jn751mzs4ru91zt3.png) 謝謝 --- 原文出處:https://dev.to/somadevtoo/difference-between-docker-kubernetes-and-podman-for-system-design-interview-3an6

了解 API 和端點之間的區別

### 了解 API 和端點之間的區別 在軟體開發領域,特別是在 Web 服務和後端開發領域,經常出現兩個術語:API(應用程式介面)和端點。雖然它們具有內在聯繫,但它們代表不同的概念。本文旨在闡明 API 和端點之間的差異,闡明它們各自的角色以及它們如何相互關聯。 #### 什麼是 API? 應用程式介面 (API) 是一組用於建立軟體應用程式的協定、例程和工具。它定義了應用程式可以用來相互溝通的方法和資料格式。本質上,API 充當中介,允許不同的軟體系統無縫互動。 ##### API 的主要特徵: - **定義**:API 是一套全面的規則和定義,可促進軟體應用程式之間的通訊。 - **範圍**:它包含多個端點、函數或方法,提供廣泛的功能。 - **目的**:API 支援不同系統之間的集成,透過提供用於存取各種功能和資料的一致介面來確保它們可以協同工作。 - **範例**:常見範例包括 RESTful API、SOAP API 和 GraphQL API。 #### 什麼是端點? 另一方面,端點是 API 中代表離散資源或功能的特定 URL 或 URI。它是客戶端(例如 Web 瀏覽器、行動應用程式或其他伺服器)可以存取 API 的特定互動點。 ##### 端點的主要特徵: - **定義**:端點是 API 中的精確位置,通常對應於單一功能或服務。 - **範圍**:它是 API 的一部分,通常指特定功能,例如檢索資料、更新資源或執行操作。 - **用途**:端點是 API 請求所導向的特定 URL。它們定義存取特定資源或功能所需的路徑和參數。 - **範例**:典型範例包括: - `GET /api/users` – 檢索使用者列表 - `POST /api/users` – 建立一個新用戶 - `GET /api/users/{id}` – 透過 ID 檢索特定用戶 - `PUT /api/users/{id}` – 按 ID 更新特定用戶 - `DELETE /api/users/{id}` – 按 ID 刪除特定用戶 #### API和端點之間的關係 打個比方,可以將 API 視為一個函式庫,將端點視為該函式庫中的特定書籍。 API 提供了庫如何運作的結構和規則,而端點是您可以尋找和存取特定資訊的精確位置。 - **API 作為圖書館**:就像圖書館包含書籍集合一樣,API 包含端點集合,每個端點都有特定的用途。 - **端點作為書籍**:API 中的每個端點都類似於圖書館中的一本書,提供可以直接存取的特定資訊或功能。 #### 實際影響 了解 API 和端點之間的差異對於開發人員來說至關重要。在設計 API 或與 API 互動時,重要的是要了解: - **API**提供了互動的整體框架和規則。 - **端點**是存取資料和功能的特定交互點。 這種差異有助於設計更有效率、更有組織的系統。它還有助於故障排除,因為開發人員可以找出問題是在更廣泛的 API 結構中還是在特定端點中。 #### 結論 總之,雖然 API 和端點是相關概念,但它們在軟體開發生態系統中扮演著不同的角色。 API 是一套全面的協定和定義,使軟體系統能夠進行通信,而端點是 API 中發生這些交互的特定 URL。了解這些差異對於有效的軟體設計、開發和整合至關重要。 --- 原文出處:https://dev.to/msnmongare/understanding-the-difference-between-apis-and-endpoints-402a

我發現的很酷的 VSCode 擴展

最近,我重新審視了去年放棄的 React 副專案。在此過程中,我發現了一些重要的 VSCode 擴展,這些擴展顯著提高了我作為 React 開發人員的工作效率。此清單的唯一規則是所有這些擴充都是**React 特定的**。雖然它們可能對其他目的有用,但它們的主要焦點是 React。 那麼,讓我們深入了解一下。 ![我們走吧](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/opxot6h4u0sxgm9zp3yq.gif) --- 這些擴充功能將透過為您提供片段來提供幫助。***程式碼片段***是預先定義的程式碼片段,只需一次按鍵(*大多數情況下按 Tab 鍵*)即可擴充為完整的程式碼區塊。這些片段的範圍可以從單行到整個文件。透過使用片段,您可以將整個檔案壓縮為簡短的縮寫,使您的編碼體驗更加順暢。 ### **1.ES7 React/Redux/GraphQL/React-Native 片段** ![ES7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqxpf64yy8a7zpfcpgcg.png) 此擴充功能提供了 React、Redux、GraphQL 和 React Native 的全面片段集合。這些片段可讓您快速產生常用的程式碼結構,從而顯著加快您的開發流程。例如: - `rcc`建立一個 React 類別元件骨架。 - `rfc`產生一個 React 功能元件。 - `rnfce`片段可協助您快速設定具有預設匯出的 React Native 元件。 - *這個清單是無窮無盡的*。[在這裡](https://github.com/r5n-dev/vscode-react-javascript-snippets/blob/HEAD/docs/Snippets.md)探索 這些片段是高度可自訂的,涵蓋廣泛的用例,使您的開發更加高效。 ### **2.React Hooks 片段** ![鉤子](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ulwbak9qamtc3846llm.png) React Hooks 程式碼片段擴充功能透過提供特定的縮寫來簡化在 React 中加入鉤子: - `ush` for `useState`初始化一個狀態變數。 - `ueh` for `useEffect`設定副作用。 - `uch` for `useContext`存取上下文。 這個擴充特別有用,因為它專注於 React 的 hooks API,這是功能元件的核心功能。它可以幫助您快速實現鉤子,而不必每次都記住確切的語法。 ### **3.VSCode React 重構** ![重構](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tucj03fncc4btoltsxm4.png) VSCode React Refactor 可讓您透過將部分程式碼提取到單獨的元件中來重構程式碼。當您的元件變得太大並且您希望將其分解為更小、更易於管理的部分時,這尤其有用。例如: - 選擇一段 JSX 程式碼。 - 右鍵單擊並選擇“重構”。 - 將其提取到新元件中。 此擴充功能支援 TypeScript 並確保正確導入和使用提取的元件,從而簡化您的重構過程。 ### **4. 將 JSON 貼為程式碼** ![json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cflc9kcid3tvfitmlzg8.png) 將 JSON 貼上為程式碼可讓您將 JSON 物件轉換為程式碼。這在處理傳回 JSON 回應的 API 時特別有用。例如: - 複製 JSON 物件。 - 使用命令選項板選擇“將 JSON 貼上為程式碼”。 - 將 JSON 轉換為具有類型定義的 JavaScript 或 TypeScript 程式碼。 此擴充功能有助於快速將 JSON 資料轉換為可用的程式碼結構,從而節省時間並減少錯誤。 ### **5.SVG圖庫** ![svg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ioelbe4mk13mk7y2ld0.png) SVG Gallery 是用於管理專案中的 SVG 檔案的絕佳工具。它允許您直接在 VSCode 中預覽 SVG 文件,這在處理多個 SVG 資源時特別方便。特點包括: - 在編輯器中預覽 SVG。 - 將 SVG 內容複製為 React 元件。 - 有效地組織和管理您的 SVG 資源。 此擴充簡化了使用 SVG 檔案的流程,讓您更輕鬆地在 React 專案中整合和管理向量圖形。 --- 雖然上述建議來自我的主觀觀點和個人對這些擴充功能的體驗,但我強烈建議您親自安裝和體驗它們。每個開發人員都有獨特的需求和工作流程,這些擴充功能可能會以不同的方式適合您的專案。 我鼓勵您分享一些可以提高您的工作效率的很酷的擴充功能。請記住,這些並不是唯一的擴展,我一直在尋找新工具來改善我的工作流程。 *這給我們帶來了一個發人深省的問題:**我們是否透過嚴重依賴這些擴充功能而創造了懶惰的程式設計師,或者我們是否真正提高了生產力和效率?**分享您的想法和經驗。讓我們討論一下這些工具是更好發展的拐杖還是催化劑。* 直到下次! ![乾杯](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ruau6ij81iaqqoyjlzm1.jpeg) --- 原文出處:https://dev.to/mitchiemt11/cool-vscode-extensions-that-that-ive-discovered-12mg

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

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

JavaScript 去抖動綜合指南:提高程式碼效率

透過實際範例和技巧了解如何在 JavaScript 中實現去抖動。掌握去抖功能並提升您的網路效能。 在這份綜合指南中,我們將探索 JavaScript 中的去抖動,了解其重要性,並學習如何有效地實現它。無論您是初學者還是經驗豐富的開發人員,掌握去抖動都可以顯著提高您的網路效能。 去抖動是一種程式設計實踐,用於確保耗時的任務不會頻繁觸發,從而提高效能和使用者體驗。它在視窗大小調整、按鈕單擊或表單輸入事件等需要控制多個快速事件的場景中特別有用。 請訂閱我的 [YouTube 頻道](https://www.youtube.com/@DevDivewithDipak?sub\_confirmation=1)來支援我的頻道並獲取更多 Web 開發教學。 ### 什麼是去抖動? 去抖是一種限制函數執行速率的技術。當多個事件快速連續觸發時,去抖動功能將確保只有係列中的最後一個事件在指定的延遲後觸發函數執行。 ### 為什麼要使用去抖動? - **效能最佳化**:透過減少呼叫函數的次數來防止效能問題。 - **增強的使用者體驗**:避免重複操作的混亂,提供更流暢的體驗。 - **網路效率**:與即時搜尋輸入欄位等事件處理程序一起使用時,減少不必要的網路請求。 ### 去抖動如何運作 想像一下,使用者在搜尋框中輸入內容,每次按鍵都會觸發 API 呼叫。如果沒有去抖,每次擊鍵都會導致新的 API 呼叫,從而使網路充滿請求。透過去抖動,只有使用者停止輸入指定持續時間後的最終輸入才會觸發 API 呼叫。 ### 在 JavaScript 中實作去抖動 這是去抖函數的簡單實作: ``` function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } ``` ### 使用範例 讓我們看看如何在現實場景中使用`debounce`函數: ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Debouncing Example</title> </head> <body> <input type="text" id="searchBox" placeholder="Type to search..."> <script> const searchBox = document.getElementById('searchBox'); function fetchSuggestions(query) { console.log('Fetching suggestions for:', query); // Simulate an API call } const debouncedFetchSuggestions = debounce(fetchSuggestions, 300); searchBox.addEventListener('input', (event) => { debouncedFetchSuggestions(event.target.value); }); function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } </script> </body> </html> ``` 在這個例子中: - 輸入欄位捕獲使用者的輸入。 - `fetchSuggestions`函數的去抖延遲為 300 毫秒。 - 當使用者鍵入時,將呼叫`debouncedFetchSuggestions`函數,確保僅在使用者停止鍵入 300 毫秒後才執行`fetchSuggestions` 。 ### 結論 去抖動是一種簡單但強大的技術,可優化 Web 應用程式的效能。透過控制函數執行的速率,它有助於減少不必要的計算並改善整體用戶體驗。無論您是處理搜尋輸入、調整視窗大小還是處理其他快速事件,去抖動都是 JavaScript 武器庫中的一個有價值的工具。 *追蹤我,以獲得更多有關 Web 開發的教學課程和技巧。歡迎在下面留下評論或問題!* ### 關注並訂閱: - **網址**:\[Dipak Ahirav\] (https://www.dipakahirav.com) - **電子郵件**:[email protected] - **Instagram** : [devdivewithdipak](https://www.instagram.com/devdivewithdipak) - **YouTube** :\[devDive 與 Dipak\](https://www.youtube.com/@DevDivewithDipak?sub\_confirmation=1) - **領英**:[迪帕克·阿希拉夫](https://www.linkedin.com/in/dipak-ahirav-606bba128) --- 原文出處:https://dev.to/dipakahirav/understanding-debouncing-in-javascript-5g30

僅使用 HTML 和 CSS 建立側邊欄選單

如果您是 Web 開發新手,您可能在不同網站上看過[側邊欄](https://www.codingnepalweb.com/category/sidebar-menu/)。您是否想知道它們是如何僅使用 HTML 和 CSS 建立的?僅使用 HTML 和 CSS 製作側邊欄是學習網頁設計基礎知識和獲得實務經驗的好方法。 在這篇文章中,我將指導您僅使用[HTML](https://www.codingnepalweb.com/?s=html)和[CSS](https://www.codingnepalweb.com/category/html-and-css/)建立響應式側邊欄。最初,側邊欄將被隱藏,僅顯示每個連結的圖示。但是,將滑鼠懸停在側邊欄上將平滑展開以顯示與每個圖示關聯的連結。 為了建立這個側邊欄,我們將使用基本的 HTML 語意元素,例如`<aside>` 、 `<ul>` 、 `<li>`和`<a>`以及常見的 CSS 屬性來設定其樣式。這是一個簡單的專案,因此您應該毫無困難地遵循這些步驟或理解程式碼。 HTML 和 CSS 中的響應式側邊欄選單影片教學 ------------------------- https://www.youtube.com/watch?v=VU74s-XAn7M 如果您喜歡從影片教學中學習,上面的 YouTube 影片是一個很好的資源。在本影片中,我解釋了每一行程式碼並提供了資訊豐富的註釋,以使建立 HTML 側邊欄的過程易於遵循,尤其是對於初學者而言。 但是,如果您喜歡閱讀部落格文章或需要此專案的逐步指南,您可以繼續閱讀這篇文章。 在 HTML 和 CSS 中建立響應式側邊欄的步驟 ------------------------- 若要僅使用 HTML 和 CSS 建立響應式側邊欄,請按照以下簡單的逐步說明進行操作: - 首先,建立一個具有任何您喜歡的名稱的資料夾。然後,在其中建立必要的文件。 - 建立一個名為`index.html`的檔案作為主檔案。 - 為 CSS 程式碼建立一個名為`style.css`檔案。 - 最後,下載[Images](https://www.codingnepalweb.com/custom-projects/simple-sidebar-menu-html-css-only-images.zip)資料夾並將其放置在您的專案目錄中。該資料夾包含該側邊欄專案所需的所有圖像。 首先,將以下 HTML 程式碼新增至您的`index.html`檔案: 此程式碼包含具有不同語意標籤(如`<aside>` 、 `<ul>` 、 `<li>`和`<a>`的基本HTML 標記,用於建立我們的側邊欄佈局。 ``` <!DOCTYPE html> <!-- Coding By CodingNepal - www.codingnepalweb.com --> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Sidebar Menu HTML and CSS | CodingNepal</title> <!-- Linking Google Font Link For Icons --> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" /> <link rel="stylesheet" href="style.css" /> </head> <body> <aside class="sidebar"> <div class="sidebar-header"> <img src="images/logo.png" alt="logo" /> <h2>CodingLab</h2> </div> <ul class="sidebar-links"> <h4> <span>Main Menu</span> <div class="menu-separator"></div> </h4> <li> <a href="#"> <span class="material-symbols-outlined"> dashboard </span >Dashboard</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> overview </span >Overview</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> monitoring </span >Analytic</a > </li> <h4> <span>General</span> <div class="menu-separator"></div> </h4> <li> <a href="#" ><span class="material-symbols-outlined"> folder </span>Projects</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> groups </span>Groups</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> move_up </span>Transfer</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> flag </span>All Reports</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> notifications_active </span >Notifications</a > </li> <h4> <span>Account</span> <div class="menu-separator"></div> </h4> <li> <a href="#" ><span class="material-symbols-outlined"> account_circle </span >Profile</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> settings </span >Settings</a > </li> <li> <a href="#" ><span class="material-symbols-outlined"> logout </span>Logout</a > </li> </ul> <div class="user-account"> <div class="user-profile"> <img src="images/profile-img.jpg" alt="Profile Image" /> <div class="user-detail"> <h3>Eva Murphy</h3> <span>Web Developer</span> </div> </div> </div> </aside> </body> </html> ``` 接下來,將以下 CSS 程式碼新增至您的`style.css`檔案中,以使您的側邊欄實用且具有視覺吸引力。請隨意嘗試不同的 CSS 屬性,例如顏色、字體、背景等,以使您的側邊欄更具吸引力。 ``` /* Importing Google font - Poppins */ @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"); * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } body { min-height: 100vh; background: #F0F4FF; } .sidebar { position: fixed; top: 0; left: 0; height: 100%; width: 85px; display: flex; overflow-x: hidden; flex-direction: column; background: #161a2d; padding: 25px 20px; transition: all 0.4s ease; } .sidebar:hover { width: 260px; } .sidebar .sidebar-header { display: flex; align-items: center; } .sidebar .sidebar-header img { width: 42px; border-radius: 50%; } .sidebar .sidebar-header h2 { color: #fff; font-size: 1.25rem; font-weight: 600; white-space: nowrap; margin-left: 23px; } .sidebar-links h4 { color: #fff; font-weight: 500; white-space: nowrap; margin: 10px 0; position: relative; } .sidebar-links h4 span { opacity: 0; } .sidebar:hover .sidebar-links h4 span { opacity: 1; } .sidebar-links .menu-separator { position: absolute; left: 0; top: 50%; width: 100%; height: 1px; transform: scaleX(1); transform: translateY(-50%); background: #4f52ba; transform-origin: right; transition-delay: 0.2s; } .sidebar:hover .sidebar-links .menu-separator { transition-delay: 0s; transform: scaleX(0); } .sidebar-links { list-style: none; margin-top: 20px; height: 80%; overflow-y: auto; scrollbar-width: none; } .sidebar-links::-webkit-scrollbar { display: none; } .sidebar-links li a { display: flex; align-items: center; gap: 0 20px; color: #fff; font-weight: 500; white-space: nowrap; padding: 15px 10px; text-decoration: none; transition: 0.2s ease; } .sidebar-links li a:hover { color: #161a2d; background: #fff; border-radius: 4px; } .user-account { margin-top: auto; padding: 12px 10px; margin-left: -10px; } .user-profile { display: flex; align-items: center; color: #161a2d; } .user-profile img { width: 42px; border-radius: 50%; border: 2px solid #fff; } .user-profile h3 { font-size: 1rem; font-weight: 600; } .user-profile span { font-size: 0.775rem; font-weight: 600; } .user-detail { margin-left: 23px; white-space: nowrap; } .sidebar:hover .user-account { background: #fff; border-radius: 4px; } ``` 結論和最後的話 ------- 對於 Web 開發初學者來說,使用 HTML 和 CSS 建立響應式側邊欄是一項可以完成的任務。透過遵循本文中提供的步驟和程式碼,您應該能夠成功建立自己的響應式和功能性側邊欄。 為了進一步提高您的網頁開發技能,我建議您嘗試重新建立本網站上提供的其他[漂亮的側邊欄](https://www.codingnepalweb.com/category/sidebar-menu/)。其中一些側邊欄使用 JavaScript 來增強其功能,例如加入[深色模式](https://www.codingnepalweb.com/sidebar-menu-in-html-css-javascript-dark-light-mode/)、[下拉式選單](https://www.codingnepalweb.com/dropdown-sidebar-menu-html-css/)等。 如果您在建立側邊欄時遇到任何問題,可以透過點擊「下載」按鈕免費下載專案的原始碼檔案。您也可以透過點擊“查看即時”按鈕來查看它的即時演示。 [查看現場演示](https://www.codingnepalweb.com/demos/create-sidebar-menu-html-css-only/) [下載程式碼文件](https://www.codingnepalweb.com/create-sidebar-menu-html-css-only/) --- 原文出處:https://dev.to/codingnepal/create-a-sidebar-menu-using-html-and-css-only-2e79

  近期留言