🔍 搜尋結果:專案

🔍 搜尋結果:專案

簡單介紹幾個基本 Git 指令

## 介紹 在軟體開發的世界裡,Git 已經成為版本控制必不可少的工具。它允許開發人員有效地協作、跟踪更改和有效地管理程式碼存儲庫。無論您是初學者還是經驗豐富的開發人員,理解和掌握 Git 命令對於最大限度地提高工作效率至關重要。在這篇博文中,我們將探索每個開發人員都應該知道的最重要的 Git 命令。 原文出處:https://dev.to/syedsadiqali/mastering-git-top-commands-every-developer-should-know-5hkn ### git init: 使用 Git 的第一步是初始化存儲庫。通過在您的專案目錄中執行 git init,您可以建立一個空的 Git 存儲庫,從而為您的專案啟用版本控制。此命令為 Git 設置必要的基礎結構以開始跟踪更改。 ``` $ git init ``` ### git clone: 要開始處理現有專案,您通常需要製作存儲庫的本地副本。 git clone 允許您將整個存儲庫及其歷史下載到本地計算機。它在您的本地副本和遠程存儲庫之間建立連接,使您能夠獲取更新並為專案做出貢獻。 ``` $ git clone https://github.com/example/repository.git ``` ### git add: 在將更改提交到存儲庫之前,您需要暫存要包含在下一次提交中的文件。 git add 允許您有選擇地將文件或整個目錄加入到暫存區。它為即將到來的提交做好準備,表明您希望將這些更改包含在存儲庫中。 ``` $ git add file.txt $ git add folder/ $ git add . ``` ### git commit: 暫存更改後,您可以使用 git commit 建立新的提交。提交充當專案在特定時間點的快照,保留您所做的更改。每個提交都有一個唯一的標識符、提交訊息,並引用以前的提交,從而形成專案的時間順序歷史記錄。 ``` $ git commit -m "Initial commit" ``` ### git pull: 協作專案通常涉及在同一個存儲庫上工作的多個開發人員。 git pull 允許您從遠程存儲庫獲取最新更改並將其合併到本地分支。它確保您的本地副本是最新的,在您開始工作之前包含其他人所做的任何新提交。 ``` $ git pull origin master ``` ### git push: 一旦您對本地分支進行了更改並想與其他人共享它們,您可以使用 git push 將您的提交上傳到遠程存儲庫。它將您的本地更改與中央存儲庫同步,使它們可供從事該專案的其他人使用。 ``` $ git push origin master ``` ### git branch: 分支是 Git 中的一項強大功能,可實現並行開發和實驗。 git branch 允許你建立新分支或列出現有分支。您可以通過使用 git checkout 在分支之間切換來獨立處理不同的功能或錯誤修復。 ``` $ git branch $ git branch new-feature ``` ### git merge: 當你完成一個特性分支的工作或者想要將一個分支的更改合併到另一個分支時,你可以使用 git merge。它將源分支中的更改合併到目標分支中,建立一個包含兩組更改的新提交。 ``` $ git merge new-feature ``` ### git stash: 有時,您可能需要在處理未完成的更改時切換到不同的分支。 git stash 允許您將修改臨時保存在類似堆棧的結構中,使您能夠在不提交或丟棄更改的情況下切換分支。稍後,您可以將隱藏的更改應用到適當的分支。 ``` $ git stash save "Work in progress" $ git stash apply ``` ### git log: 要檢查存儲庫的提交歷史,git log 是一個方便的命令。它顯示按時間順序排列的提交列表,包括作者、時間戳和提交訊息。您可以使用此命令的各種選項來根據您的要求過濾和格式化輸出。 ``` $ git log $ git log --author="John Doe" ``` ## 結論: Git 是一個強大的版本控制系統,它使開發人員能夠有效協作並跟踪專案中的更改。通過掌握這些頂級 Git 命令,您將能夠輕鬆導航存儲庫、管理分支和跟踪更改。無論您是從事個人專案還是參與大型軟體開發,理解和使用這些命令

Github 範本專案推薦:學習 React 技術的幾個 Repo

開源對很多事情都非常有用。其中之一是學習新技能。在本文中,我們將介紹 GitHub 上一些最好的開源 React 專案,您可以使用它們來快速提升您的 React 技能。 原文出處:https://dev.to/livecycle/top-github-repositories-to-learn-modern-react-development-5d3h ## 你可以學習的開源 React 專案 ![提升](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/app52pnsi0e6rey24kp1.gif) ## Cal.com ![Cal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jnra9gxpgh0y04ereq7.png) [https://github.com/calcom/cal.com](https://github.com/calcom/cal.com) Cal.com 將自己標榜為“絕對適合所有人的日程安排基礎設施”。他們是 Calendly 等預約安排服務的競爭對手。他們同時提供託管和自託管產品。它是一個全棧 Next.js 應用程式,它依賴 tRPC 進行類型安全的客戶端到伺服器通信。該存儲庫具有相當廣泛的 Monorepo 設置(使用 Turborepo),可將應用程式拆分為多個包。在樣式方面,Cal.com 使用 TailwindCSS 和無頭 Radix 元件。存儲庫非常活躍,他們積極鼓勵貢獻者。許多問題被標記為“良好的第一期”和“需要幫助”。 ## Taxonomy ![分類法](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfjhtw3tccnosgf5n0rn.png) [https://github.com/shadcn/taxonomy](https://github.com/shadcn/taxonomy) 這個有點不同。它由單個開發人員建置,作為探索新的 Next.js 13 App Router 功能的演示。但是不要讓那個愚弄你。它可以說是使用新 App Router 的最全面的開源應用程式之一。因此,即使對於想要學習如何在生產中使用 App Router 的經驗豐富的 React 開發人員來說,這也是一個很好的資源。 除了用於前端和後端的 Next.js 之外,Taxonomy 使用 NextAuth 進行身份驗證,使用 Prisma 作為 ORM,使用帶有 Radix 的 TailwindCSS 進行樣式設置。特別有趣的是 Stripe 訂閱集成。因此,如果您想了解如何將訂閱集成到您的應用程式中,這就是適合您的存儲庫。 ## Highstorm ![高塔](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/40cy6gokdozqqihlqgxr.png) [https://github.com/chronark/highstorm](https://github.com/chronark/highstorm) Highstorm 是這個街區的新玩家。它是一種監視應用程式中發生的事件的服務。您通過他們的 API 提交事件,然後將其輸入 Highstorm 儀表板。再次重申,這是一個基於 Next.js 的專案。它使用 Tinybird 作為分析資料的資料庫,並使用 Clerk 進行身份驗證。如果您想學習如何處理大量分析資料並將它們顯示在精美的圖表中,那麼這個專案很棒。 ## Dub.sh ![配音](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g90d1imz9110lv1uxb5l.png) [https://github.com/steven-tey/dub](https://github.com/steven-tey/dub) Dub.sh 大約在一年前作為開源連結縮短器推出。它是 Bitly 等服務的替代品。它也是基於 Next.js 並結合使用舊頁面和新 App 路由器。它通常是最早採用 Next.js 新功能(例如元資料 API)的專案之一。 該存儲庫是了解多租戶 Next 應用程式的好地方。這些是為不同域下的不同用戶提供服務的應用程式。在 Dub.sh 的情況下,用戶可以加入自己的域以在其下建立縮短的連結。該應用程式的設計也很精美,整個網站上都有許多令人愉悅的動畫。 Framer Motion 庫用於幫助解決此問題。 ## Bulletproof React ![防彈](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1cndmw6tii88v9puz154.png) [https://github.com/alan2207/bulletproof-react](https://github.com/alan2207/bulletproof-react) Bulletproof React 與我們目前介紹的其他專案不同。該存儲庫確實包含一個功能齊全的演示 React 應用程式。但最大的價值來自閱讀此應用程式附帶的綜合文件。本文件列出了設計大型 React 應用程式各個方面的最佳實踐。這是一個很好的資源,可以定期參考以刷新您對最佳實踐的記憶。 ## 總結和開始 正如我們所見,上述每個存儲庫都提供了一個獨特的視角來了解大型 React 應用程式是如何建置的。每個人都可以從研究存儲庫的程式碼中獲益,無論您有多有經驗。 開始從存儲庫中學習的一個很好的實用技巧是提出一個特定的問題。例如,您可能會問“Taxonomy 如何處理 Stripe 訂閱?”之類的問題。然後挖掘程式碼層以找到問題的答案。 最後一點——探索開源存儲庫是提升 React 技能的好方法,但這不是您唯一應該做的事情。將您新獲得的知識應用到您自己的專案中也很重要。這就是您鞏固新技能和保留訊息的方式。 最主要的是享受這個過程,並認識到開源是培養新技能的友好場所,無論您目前的經驗水平如何。

分享職場小菜雞所遇到的狀況

感謝站長關懷~ 是的,這禮拜確實有遇到一些之前有稍微碰過卻不太熟悉的東西,也有之前沒有碰過的東西,是有些小崩潰...,但還是可以稍微跟大家分享與請教一下: 這裡有一些前期提要:公司目前的前端開發並不使用現在的主流前端框架,也沒有使用打包整合工具...(像是Webpack、Parcel這類的),JS使用JQuery,並且將JS檔案一個一個的引入網頁中。 ## 遇到的問題1 :CSS樣式問題 過去在自學的時候其開發方法是:在本機開發,然後在處理樣式與RWD時就是開啟Chrome 的 Dev Tools來做調整,但也有遇過在Chrome的Dev Tools中看起來將樣式都調整好了之後,部署到網路上之後換手機來查看頁面時卻發生了一些差異,這些差異可能包含滿版、間距等等,這部分我自己理解的差異可能會是有些手機會有瀏海的緣故以及Chrome與Safari之間的小差異.到新公司後發現在更多的裝置上,例如安卓手機,則存在的差異更多,包含顏色、日期時間選取器等等的樣式,因為型號真的太多了. ###到這裡可以跟大家分享的以及向各位請教的: 這裡我自己有想到幾個解決的方式,第一個是最懶的方法我最想用但是我有些不知道該如何整合給其他人使用的方法,例如透過Vue cli直接在npm下載PostCSS以及Autoprefixer這樣的工具來使用,一次解決主流瀏覽器的差異,但目前我不太曉得如何在公司的開發方法下,不透過整合工具來完成這個流程. 另一個我想到的方法是加入CSS Normalize來減少各個瀏覽器在不同樣式的預設值差異,過去我們可能都有寫過非常簡易CSS reset 例如: ```css= *{ padding: 0; margin:0; box-sizing:border-box; } ``` 但這樣如果把每一個樣式的預設值全部強制歸零,可能會導致有些樣式到後來要重新寫,或許Normalize可以只是單純地減少差異(也是因為網路上有人已經整理好了XD). ## 遇到的問題2 :API串接 過去我自己練習串接API的方式實在是相當簡易,我拿的是中央氣象局開放資料平台的API,所以之前很簡單的一行fetch就拿到資料了,毫無難度哈哈哈,但第一天公司需要我去切幾個版面並且串接運輸資料TDX的資料,恩...我一開始不知道要如何在JS中塞入登入資料並且拿回Token的方式.以及我要查詢的數值該如何發出. ###到這裡可以跟大家分享的以及向各位請教的: 這中間我摸索了fetch的一些選項設定,這應該也適用其他的非同步請求方法,例如ajax、axios(這兩個我還沒用過,後續應該會來摸索一下axios),包含請求方法(method),header與body中的內容設定等等. 至於API該如何塞入a頁面填入查詢參數並且跳轉到b頁面顯示查詢解果,在沒有前端框架全域狀態管理的支援下,這邊則是摸索了encodeURIComponent以及decodeURIComponent這樣的函式,將要查詢的參數在a頁面進行編碼並丟入到URL中,跳轉到b頁面後再進行解碼.並fetch我要的資料.最後是有成功的,只是覺得自己像薪水小偷哈哈哈,效率並不高. 這個方法感覺並不建議應用在需要輸入有個人資料的內容中,因為編碼的方式是雙向的,資料可以編碼也可以解碼,所以....像個資這類的內容就應該不建議塞在URL中用這種方式傳輸.至於要用什麼方法,這也是我想知道的. ## 遇到的問題3:不同裝置的問題 這個並非第一個樣式的問題,而是我目前覺得還沒有解的問題,就是我在網頁中需要獲取使用者的位置,因此用了navigator.geolocation 這個API,但神奇的是,在本機中都可以抓得到資料,打開Dev Tools檢查回傳的狀態碼與經緯度也都是沒有問題,但是在手機中雖然會顯示是否能夠取得使用者位置的提示,但按了同意後卻一直無法獲取資料,而且尷尬的是,我無法在手機中打開Dev Tools,所以我也不知道問題發生在哪....,過去有使用過navigator.geolocation 好像也沒有碰過這樣的問題 想跟各位請教的是,有什麼方式可以查看手機上的問題嗎? ## 遇到的問題4:不同的開發方式 這個是我自己很好奇的,雖然說我知道Vue是漸進式框架,但我卻不知道該如何漸進.我理解的漸進式是,有些頁面或元件可以自行選擇要不要使用Vue開發,還是這個漸進式的意思是可以自行選擇要使用多少Vue的套件工具呢(像是要不要使用Vue Router or Vuex). 會這樣問是因爲,假如現在有一份專案一共是十個頁面,我被分到了其中五頁,另外的同事則是負責另外五頁,誠如開頭所說,假如公司既定的開發方式並不使用框架與其他整合工具,我有可能使用框架進行開發並與之合作嗎?還是我這是一個很奇怪的問題,本來就應該要統一一個開發方式? --- 感謝看到這邊的各位,以上有些觀念上是我這位小菜雞自己摸索的,是可能不是正確的(例如有些函式、工具的用途或使用情境),因此歡迎大家指教與討論,這是我這禮拜可以跟大家分享的啦. 謝謝~~ --- PS:我自學八個月的時間有摸了原生JS、CSS、Vue.js、Tailwind、SCSS這樣的工具,本來我是很想要在第一份工作多了解與強化上述工具以及多人開發GitHub的部分,我了解這些終究只是工具且我自己也沒有到非常熟,只要可以完成專案目的即可,我的實力在哪裡我也知道,但以目前公司的開發模式來說,我需要考量沒有踏上趨勢的這個問題嗎?還是我多慮呢了?

同事寫 css 大量使用 !important 導致很難維護,怎麼辦?

# !important 的正確使用時機 !important 會強制打斷正常的 css 修改邏輯權重 在我十年的工作經驗中,只有兩種情況會這樣用 第一個是寫 utility css class 的時候 例如 `.text-center` `.text-right` 這種輔助功能性的 css class 比方說參考 bootstrap 的相關文件 https://getbootstrap.com/docs/5.3/utilities/api/ 這些 css class 看命名就知道有一種「這元素就是要這樣式」的感覺 所以加上去會蓋過其他所有 css class,但是這沒問題,不會造成維護的困擾 別人一看就知道是 utility class 在作用 --- 第二個情況是,當你確認自己在對某元素進行「最終維護」的時候 也就是幾乎結束的專案,最後一次幫客戶修改,你很確定有些元素之後不會再擴充、再修改了 這時有些樣式會偷懶 !important 亂加一通 改完就不想管了 # 當同事濫用導致 code 難以維護 實務上來說,除了上述兩種情況之外,使用 !important 都是「完全不可接受的」! 當專案內出現大量 !important 時,會讓 css 難以維護,甚至是無法維護! 就我個人經驗來說,這情況非常慘,是一種「重大技術債」 也就是代價很高,會開始不斷支付利息,然後很沒效率 # 現階段的務實處理 這個情況的出現,代表圖隊內有人「經驗不足」或者是「缺乏責任感」 需要適當反應、溝通,避免未來再出現這情況 第一種辦法是 相關樣式通通重寫!這個成本很高,但專案若還需要長期維護很久,可能必須這樣 第二種辦法是,讓相關 PM 與資深工程師知道這個情況的存在 他們會可以理解:相關 code 修改起來的時間,難以預期、難以估計!分配安排上,要考量到這點,甚至避免相關樣式的改動 總而言之,這情況,算是相當「雷」了 工作上,千萬別當濫用 !important 的人 # 最後補充 在程式設計領域,各種套件、協定、API 在設計的時候,有些功能會提供給大家用,但希望大家盡量少用 這種時候,通常會讓函式名稱、變數名稱、或者是相關命名「長得很奇怪」 比方說突然有一個「全英文大寫的命名」、「很冗長的函式命名」、「用奇怪的底線前後包住的命名」、「使用奇怪的特殊符號的命名」 這些就是「知道你可能必要時刻會需要用,但是非常不鼓勵使用」的 API,所以故意讓你打字累一點、而且會察覺到自己在幹嘛 !important 就是屬於這類東西,打起來很怪很累,所以當然不應該濫用 --- 以上,簡單分享

增加開發者生產力:19 個簡單好用的 VScode 外掛

[VS Code](https://code.visualstudio.com/) 是一款免費、跨平台、開源的程式碼編輯器,近年來成為開發者最熱門的選擇。 在本文中,我整理了一些最有用的外掛,您可以使用它們來提高工作效率。 原文出處:https://dev.to/madza/19-vs-code-extensions-to-boost-your-productivity-4npo --- ### 1\. [Swimm](https://go.swimm.io/ide-plugin?utm_source=Hashnode&utm_medium=paid_influencer&utm_campaign=launch_may&utm_content=madza_dev) 使用 Swimm 的富文本編輯器建立文件。記錄跨越多個文件和存儲庫的複雜流程,其中包含與程式碼交互並在您進行更改時自動更新的豐富內容。 在本地驗證和更新文件,並將其作為 CI 工作流的一部分,自動修復簡單的錯誤,並且僅在發生重大更改時提醒您。 在正確的時間找到正確的文件——就在相關程式碼旁邊。當您看到一個 wave 時,這意味著存在與該特定程式碼部分相關的文件。 ![使用 Swimm 建立內部文件](https://storage.googleapis.com/swimmio-ide/assets/doc%20creation.png) ### 2\. [GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) 借助 GitLens,開發人員可以通過提供有關 Git 存儲庫的高級可視化和訊息,更好地了解其程式碼庫的歷史、作者身份和更改。 GitLens 還提供了一組豐富的自定義選項,以及內聯責備註釋、提交和差異詳細訊息,甚至無需離開編輯器即可查看和編輯提交訊息的能力。 ![提交圖](https://raw.githubusercontent.com/gitkraken/vscode-gitlens/main/images/docs/commit-graph-illustrated.png) ### 3\. [Thunder Client](https://marketplace.visualstudio.com/items?itemName=rangav.vscode-thunder-client) Thunder Client 是用於 Visual Studio Code 的輕量級 Rest API 客戶端擴展,具有簡單易用的 UI。 支持集合和環境變數和 GraphQL 查詢,以及使用基於 GUI 的界面進行無腳本測試。 所有請求的資料都本地保存在您的設備上。 ![迅雷客戶端](https://github.com/rangav/thunder-client-support/blob/master/images/thunder-client-v2.png?raw=true) ### 4\. [Tabnine](https://marketplace.visualstudio.com/items?itemName=TabNine.tabnine-vscode) Tabnine 是一個 AI 程式碼助手,可以通過在所有最流行的編碼語言和 IDE 中實時完成程式碼來提高您的開發速度。 Tabnine 由多種語言專用的機器學習模型提供支持,這些模型是在程式碼上從頭開始進行預訓練的。 ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683725176305/71c6f916-5dd6-475a-ac87-066bc301d3e3.gif) ### 5\. [Remote-SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) Remote - SSH 擴展允許您使用任何帶有 SSH 伺服器的遠程機器作為您的開發環境。 無需在本地計算機上安裝源程式碼即可獲得這些好處,因為該擴展程序直接在遠程計算機上執行命令和其他擴展程序。 您可以打開遠程計算機上的任何文件夾並使用它,就像文件夾在您的計算機上一樣。 ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/psfddazji4zk1nfgcbrg.png) ### 6\. [Docker](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker) Docker 擴展使從 Visual Studio Code 建置、管理和部署容器化應用程式變得容易。 它還提供了對容器內 Node.js、Python 和 .NET 的一鍵式除錯。 ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kifgjwnunn9ynmr2odcf.png) ### 7\. [Git History](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory) 使用此擴展,用戶可以輕鬆瀏覽提交歷史記錄、檢查文件更改並比較程式碼的不同版本。 該擴展提供了一個 GUI,可以在時間軸中顯示提交歷史記錄。每個提交都與其提交訊息、作者、日期和時間一起顯示。 用戶還可以查看與每個提交關聯的分支和標籤名稱。 ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y7us7mebno5di3f7lp1l.png) ### 8\. [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) 對於在 VS Code 中使用大量 Markdown 的任何人來說,這是一個有用的工具。它使建立和編輯 Markdown 文件變得更加容易和快速,幫助您提高生產力和效率。 這些功能包括語法突出顯示、程式碼塊格式化、目錄、預覽模式、表情符號支持、鍵盤快捷鍵等等。 ![圖片說明](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8f1ygmrmzd1ifz2q2pfq.png) ### 9\. [Regex Previewer](https://marketplace.visualstudio.com/items?itemName=chrmarti.regex) 該擴展在並排文件中顯示當前正則表達式的匹配項。這可以使用 Ctrl+Alt+M 打開/關閉。 可以通過狀態欄條目加入全局選項和多行選項,以便使用並排文件進行評估。當並排文件有多個匹配示例時,這會很有用。 ![執行中的正則表達式預覽器](https://github.com/chrmarti/vscode-regex/raw/main/images/in_action.gif) ### 10\. [Better Comments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments) 使用此擴展,您將能夠將註釋分類為提醒、查詢、TODO、突出顯示等。 註釋掉的程式碼也可以設置樣式以明確程式碼不應該存在。您可以在設置中指定您想要的任何其他評論樣式。 ![無法為 Python 使用 vs 程式碼“更好的評論擴展”- 堆棧溢出](https://i.stack.imgur.com/MFQJN.png) ### 11\. [Bookmarks](https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks) 書籤擴展可幫助您導航程式碼,輕鬆快速地在重要位置之間移動。 不再需要搜尋程式碼。它還支持一組選擇命令,允許您選擇書籤行和書籤行之間的區域。它對日誌文件分析非常有用。 ![切換](https://github.com/alefragnani/vscode-bookmarks/raw/HEAD/images/printscreen-toggle.png) ### 12\. [Project Manager](https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager) 專案管理器可幫助您輕鬆存取您的專案,無論它們位於何處。不要再錯過那些重要的專案了。 您可以定義您的專案(也稱為收藏夾),或選擇自動檢測 Git、Mercurial 或 SVN 存儲庫、VS 程式碼文件夾或任何其他文件夾。 此外,您還可以使用標籤來組織您的專案。 ![側欄](https://github.com/alefragnani/vscode-project-manager/raw/HEAD/images/vscode-project-manager-side-bar-tags.gif) ### 13\. [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) 一個基本的拼寫檢查器,適用於程式碼和文件。 這個拼寫檢查器的目標是幫助捕獲常見的拼寫錯誤,同時保持較低的誤報率。 ![示例](https://raw.githubusercontent.com/streetsidesoftware/vscode-spell-checker/main/images/example.gif) ### 14\. [Image Optimizer](https://marketplace.visualstudio.com/items?itemName=MadsKristensen.ImageOptimizer) 向解決方案資源管理器中的任何文件夾和圖像加入右鍵單擊菜單,使您可以自動優化該文件夾中的所有 PNG、GIF 和 JPEG 文件。 只需右鍵單擊任何包含圖像的文件或文件夾,然後單擊其中一個圖像優化按鈕。 ![輸出窗口](https://github.com/madskristensen/ImageOptimizer/raw/master/art/output-window.png) ### 15\. [CSS Peek](https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek) 該擴展支持符號定義跟踪的所有正常功能,但它適用於 CSS 選擇器(類、ID 和 HTML 標記)。 您可以內聯加載 CSS 文件並在此處進行快速編輯,直接跳轉到 CSS 文件或在新編輯器中打開它或在懸停時顯示定義。 ![工作](https://github.com/pranaygp/vscode-css-peek/raw/master/readme/working.gif) ### 16\. [Placeholder Images](https://marketplace.visualstudio.com/items?itemName=JakeWilson.vscode-placeholder-images) 使用各種第 3 方服務(如 Unsplash、LoremFlickr 等)在 Visual Studio Code 中生成佔位符圖像並將其插入到 HTML 中。 您可以選擇圖像寬度、高度、文本和顏色,將生成的 IMG 標籤插入到您的 HTML 中或將其複製到剪貼板,或者將圖像 URL 插入到您的 HTML 中,複製到剪貼板,或在您的瀏覽器中打開它。 ![使用 placehold.it 生成佔位符圖像](https://github.com/Jakobud/vscode-placeholder-images/raw/master/images/example.gif) ### 17\. [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) 具有實時瀏覽器重新加載功能的快速開發實時伺服器。從狀態欄單擊即可啟動或停止伺服器。 允許用戶建立可自定義的端口號,設置伺服器根目錄,並在設置中提供默認的瀏覽器配置選項。 ![實時伺服器演示 VSCode](https://github.com/ritwickdey/vscode-live-server/raw/HEAD/images/Screenshot/vscode-live-server-animated-demo.gif) ### 18\. [Peacock](https://marketplace.visualstudio.com/items?itemName=johnpapa.vscode-peacock) 使用 Peacock,您可以巧妙地更改 VS Code 工作區的顏色。 當你有多個 VS Code 實例、使用 VS Live Share 或使用 VS Code 的遠程功能,並且你想快速辨識你的編輯器時,這是理想選擇。 ![孔雀窗](https://raw.githubusercontent.com/johnpapa/vscode-peacock/main/resources/hero.png) ### 19\. [Polacode](https://marketplace.visualstudio.com/items?itemName=pnp.polacode) Polacode 是 VS Code 的擴展,它可以對你的程式碼進行截圖。 該擴展生成一個與源具有相同風格和主題的螢幕截圖。 ![用法](https://github.com/octref/polacode/raw/master/demo/usage.gif) --- 以上簡單分享,希望對您有幫助~

給軟體工程師:50 個好用的 ChatGPT 咒語指令

下列 ChatGPT-4 咒語,對開發者很有幫助。附上原文與中文指令,供您參考。 原文出處:https://dev.to/hackertab_org/50-chat-gpt-prompts-every-software-developer-should-know-tested-9al ### **程式碼生成** - Generate a boilerplate `[language]` code for a `[class/module/component]` named [name] with the following functionality: `[functionality description].` - 為名為 [name] 的 `[class/module/component]` 生成樣板 `[language]` 程式碼,具有以下功能:`[functionality description]。 - Create a [language] function to perform `[operation]` on `[data structure]` with the following inputs: [input variables] and expected output: `[output description]`. - 建立一個 [語言] 函數以使用以下輸入對 `[資料結構]` 執行 `[操作]`:[輸入變數] 和預期輸出:`[輸出描述]`。 - Generate a `[language]` class for a `[domain]` application that includes methods for `[methods list]` and properties `[properties list]`. - 為包含“[方法列表]”的方法和屬性“[屬性列表]”的“[域]”應用程式生成一個“[語言]”類。 - Based on the [design pattern], create a code snippet in [language] that demonstrates its implementation for a [use case]. - 基於[設計模式],用[語言]建立一個程式碼片段,演示其對[用例]的實現。 **例子:** ``` Generate a boilerplate Python code for a shopping cart module named "ShoppingCart" with the following functionality: - A constructor that initializes an empty list to store cart items. - A method called "add_item" that takes in an item object and adds it to the cart. - A method called "remove_item" that takes in an item object and removes it from the cart if it exists. - A method called "get_items" that returns the list of items in the cart. - A method called "get_total" that calculates and returns the total price of all items in the cart. ``` ### **程式碼完成** - In `[language]`, complete the following code snippet that initializes a [data structure] with `[values]`: `[code snippet]`. - 在“[語言]”中,完成以下使用“[值]”初始化[資料結構]的程式碼片段:“[程式碼片段]”。 - Finish the `[language]` function that calculates [desired output] given the following input parameters: `[function signature]`. - 在給定以下輸入參數的情況下完成計算[期望輸出]的[語言]函數:[函數簽名]。 - Complete the `[language]` code to make an API call to `[API endpoint]` with [parameters] and process the response: `[code snippet]`. - 完成“[語言]”程式碼以使用[參數]對“[API 端點]”進行 API 呼叫並處理響應:“[程式碼片段]”。 **Example** : Finish the Python function that calculates the average of a list of numbers given the following input parameters: **示例**:完成計算給定以下輸入參數的數字列表的平均值的 Python 函數: ``` def calculate_average(num_list) ``` ### **錯誤檢測** - Identify any potential bugs in the following [language] code snippet: `[code snippet]`. - 確定以下 [語言] 程式碼片段中的任何潛在錯誤:`[程式碼片段]`。 - Analyze the given [language] code and suggest improvements to prevent [error type]: `[code snippet]`. - 分析給定的[語言]程式碼並提出改進建議以防止[錯誤類型]:`[程式碼片段]`。 - Find any memory leaks in the following [language] code and suggest fixes: `[code snippet]`. - 在以下 [語言] 程式碼中查找任何內存洩漏並提出修復建議:`[程式碼片段]`。 **Example** : Identify any potential bugs in the following Python code snippet: **示例**:辨識以下 Python 程式碼片段中的任何潛在錯誤: ``` def calculate_sum(num_list): sum = 0 for i in range(len(num_list)): sum += num_list[i] return sum ``` ### **程式碼審查** - Review the following `[language]` code for best practices and suggest improvements: `[code snippet]`. - 查看以下“[語言]”程式碼以獲得最佳實踐並提出改進建議:“[程式碼片段]”。 - Analyze the given `[language]` code for adherence to `[coding style guidelines]`: `[code snippet]`. - 分析給定的“[語言]”程式碼是否符合“[編碼風格指南]”:“[程式碼片段]”。 - Check the following [language] code for proper error handling and suggest enhancements: `[code snippet]`. - 檢查以下 [語言] 程式碼以正確處理錯誤並提出改進建議:`[程式碼片段]`。 - Evaluate the modularity and maintainability of the given `[language]` code: `[code snippet]`. - 評估給定“[語言]”程式碼的模塊化和可維護性:“[程式碼片段]”。 **Example** : Review the following Python code for best practices and suggest improvements: **示例**:查看以下 Python 程式碼以獲得最佳實踐並提出改進建議: ``` def multiply_list(lst): result = 1 for num in lst: result *= num return result ``` ### **API 文件生成** - Generate API documentation for the following `[language]` code: `[code snippet]`. - 為以下“[語言]”程式碼生成 API 文件:“[程式碼片段]”。 - Create a concise API reference for the given `[language]` class: `[code snippet]`. - 為給定的“[語言]”類建立簡明的 API 參考:“[程式碼片段]”。 - Generate usage examples for the following `[language]` API: `[code snippet]`. - 為以下“[語言]”API 生成用法示例:“[程式碼片段]”。 **Example** : Generate API documentation for the following JavaScript code: **示例**:為以下 JavaScript 程式碼生成 API 文件: ``` /** * Returns the sum of two numbers. * @param {number} a - The first number to add. * @param {number} b - The second number to add. * @returns {number} The sum of a and b. */ function sum(a, b) { return a + b; } ``` ### **查詢優化** - Optimize the following SQL query for better performance: `[SQL query]`. - 優化以下 SQL 查詢以獲得更好的性能:`[SQL 查詢]`。 - Analyze the given SQL query for any potential bottlenecks: `[SQL query]`. - 分析給定的 SQL 查詢是否存在任何潛在瓶頸:`[SQL 查詢]`。 - Suggest indexing strategies for the following SQL query: `[SQL query]`. - 為以下 SQL 查詢建議索引策略:`[SQL 查詢]`。 - Optimize the following NoSQL query for better performance and resource usage: `[NoSQL query]`. - 優化以下 NoSQL 查詢以獲得更好的性能和資源使用:`[NoSQL 查詢]`。 **Example** : Optimize the following SQL query for better performance: **示例**:優化以下 SQL 查詢以獲得更好的性能: ``` SELECT * FROM orders WHERE order_date BETWEEN '2022-01-01' AND '2022-12-31' ORDER BY order_date DESC LIMIT 100; ``` ### **用戶界面設計** - Generate a UI mockup for a `[web/mobile]` application that focuses on [`user goal or task]`. - 為專注於 [`用戶目標或任務]` 的`[web/mobile]` 應用程式生成 UI 模型。 - Suggest improvements to the existing user interface of `[app or website]` to enhance `[usability, accessibility, or aesthetics]`. - 建議改進“[應用程式或網站]”的現有用戶界面,以增強“[可用性、可存取性或美學]”。 - Design a responsive user interface for a `[web/mobile]` app that adapts to different screen sizes and orientations. - 為適應不同螢幕尺寸和方向的“[web/mobile]”應用程式設計響應式用戶界面。 **Example** : Generate a UI mockup for a mobile application that focuses on managing personal finances. **示例**:為專注於管理個人財務的移動應用程式生成 UI 模型。 ### **自動化測試** - Generate test cases for the following [language] function based on the input parameters and expected output: `[function signature]`. - 根據輸入參數和預期輸出為以下 [語言] 函數生成測試用例:`[函數簽名]`。 - Create a test script for the given [language] code that covers [unit/integration/system] testing: `[code snippet]`. - 為涵蓋[單元/集成/系統]測試的給定[語言]程式碼建立測試腳本:`[程式碼片段]`。 - Generate test data for the following [language] function that tests various edge cases: `[function signature]`. - 為以下測試各種邊緣情況的[語言]函數生成測試資料:`[函數簽名]`。 - Design a testing strategy for a [web/mobile] app that includes [unit, integration, system, and/or performance] testing. - 為 [網絡/移動] 應用程式設計測試策略,包括 [單元、集成、系統和/或性能] 測試。 **Example:** Generate test cases for the following Python function based on the input parameters and expected output: **示例:** 根據輸入參數和預期輸出為以下 Python 函數生成測試用例: ``` def divide(a: float, b: float) -> float: if b == 0: raise ZeroDivisionError('division by zero') return a / b ``` ### **程式碼重構** - Suggest refactoring improvements for the following [language] code to enhance readability and maintainability: `[code snippet]`. - 建議對以下 [語言] 程式碼進行重構改進,以增強可讀性和可維護性:`[程式碼片段]`。 - Identify opportunities to apply [design pattern] in the given [language] code: `[code snippet]`. - 確定在給定的[語言]程式碼中應用[設計模式]的機會:`[程式碼片段]`。 - Optimize the following [language] code for better performance: `[code snippet]`. - 優化以下 [語言] 程式碼以獲得更好的性能:`[程式碼片段]`。 **Example** : Optimize the following Python code for better performance: **示例**:優化以下 Python 程式碼以獲得更好的性能: ``` def find_max(numbers): max_num = numbers[0] for num in numbers: if num > max_num: max_num = num return max_num ``` ### **設計模式建議** - Based on the given [language] code, recommend a suitable design pattern to improve its structure: `[code snippet]`. - 根據給定的[語言]程式碼,推薦合適的設計模式來改進其結構:`[程式碼片段]`。 - Identify opportunities to apply the [design pattern] in the following [language] codebase: `[repository URL or codebase description]`. - 確定在以下 [語言] 程式碼庫中應用 [設計模式] 的機會:`[存儲庫 URL 或程式碼庫描述]`。 - Suggest an alternative design pattern for the given [language] code that may provide additional benefits: `[code snippet]`. - 為可能提供額外好處的給定 [語言] 程式碼建議替代設計模式:`[程式碼片段]`。 **Example:** Based on the given Python code, recommend a suitable design pattern to improve its structure: **例子:** 根據給定的Python程式碼,推薦合適的設計模式來改進其結構: ``` class TotalPriceCalculator: def calculate_total(self, items): pass class NormalTotalPriceCalculator(TotalPriceCalculator): def calculate_total(self, items): total = 0 for item in items: total += item.price * item.quantity return total class DiscountedTotalPriceCalculator(TotalPriceCalculator): def calculate_total(self, items): total = 0 for item in items: total += item.price * item.quantity * 0.9 # apply 10% discount return total class Order: def __init__ (self, items, total_price_calculator): self.items = items self.total_price_calculator = total_price_calculator def calculate_total(self): return self.total_price_calculator.calculate_total(self.items) class Item: def __init__ (self, name, price, quantity): self.name = name self.price = price self.quantity = quantity ``` ### **算法開發** - Suggest an optimal algorithm to solve the following problem: `[problem description]`. - 建議解決以下問題的最佳算法:`[問題描述]`。 - Improve the efficiency of the given algorithm for `[specific use case]`: `[algorithm or pseudocode]`. - 為“[特定用例]”提高給定算法的效率:“[算法或偽程式碼]”。 - Design an algorithm that can handle `[large-scale data or high-throughput]` for `[specific task or operation]`. - 為“[特定任務或操作]”設計一種可以處理“[大規模資料或高吞吐量]”的算法。 - Propose a parallel or distributed version of the following algorithm to improve performance: `[algorithm or pseudocode]`. - 提出以下算法的並行或分佈式版本以提高性能:`[算法或偽程式碼]`。 ### **程式碼翻譯** - Translate the following `[source language]` code to `[target language]`: `[code snippet]`. - 將以下“[源語言]”程式碼翻譯成“[目標語言]”:“[程式碼片段]”。 - Convert the given `[source language]` class or module to `[target language]` while preserving its functionality and structure: `[code snippet]`. - 將給定的“[源語言]”類或模塊轉換為“[目標語言]”,同時保留其功能和結構:“[程式碼片段]”。 - Migrate the following `[source language]` code that uses `[library or framework]` to [target language] with a similar library or framework: `[code snippet]`. - 將以下使用“[庫或框架]”的“[源語言]”程式碼遷移到具有類似庫或框架的“目標語言”:“[程式碼片段]”。 **Example:** Translate the following Python code to JavaScript: **示例:**將以下 Python 程式碼轉換為 JavaScript: ``` def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) ``` ### **個性化學習** - Curate a list of resources to learn `[programming language or technology]` based on my current skill level: `[beginner/intermediate/advanced]`. - 根據我目前的技能水平,策劃學習`[編程語言或技術]`的資源列表:`[初學者/中級/高級]`。 - Recommend a learning path to become proficient in `[specific programming domain or technology]` considering my background in `[existing skills or experience]`. - 考慮到我在“[現有技能或經驗]”方面的背景,推薦精通“[特定編程領域或技術]”的學習路徑。 - Suggest project ideas or coding exercises to practice and improve my skills in `[programming language or technology]`. - 建議專案想法或編碼練習,以練習和提高我在“[編程語言或技術]”方面的技能。 ### **程式碼可視化** - Generate a UML diagram for the following `[language]` code: `[code snippet]`. - 為以下“[語言]”程式碼生成一個 UML 圖:“[程式碼片段]”。 - Create a flowchart or visual representation of the given `[language]` algorithm: `[algorithm or pseudocode]`. - 建立給定“[語言]”算法的流程圖或可視化表示:“[算法或偽程式碼]”。 - Visualize the call graph or dependencies of the following `[language]` code: `[code snippet]`. - 可視化以下“[語言]”程式碼的呼叫圖或依賴關係:“[程式碼片段]”。 **Example** : Generate a UML diagram for the following Java code: **示例**:為以下 Java 程式碼生成 UML 圖: ``` public abstract class Vehicle { private String model; public Vehicle(String model) { this.model = model; } public String getModel() { return model; } public abstract void start(); public abstract void stop(); } public class Car extends Vehicle { public Car(String model) { super(model); } @Override public void start() { System.out.println("Starting car engine"); } @Override public void stop() { System.out.println("Stopping car engine"); } } public class Motorcycle extends Vehicle { public Motorcycle(String model) { super(model); } @Override public void start() { System.out.println("Starting motorcycle engine"); } @Override public void stop() { System.out.println("Stopping motorcycle engine"); } } ``` ### **資料可視化** - Generate a bar chart that represents the following data: `[data or dataset description]`. - 生成代表以下資料的條形圖:`[資料或資料集描述]`。 - Create a line chart that visualizes the trend in the following time series data: `[data or dataset description]`. - 建立一個折線圖,將以下時間序列資料的趨勢可視化:`[資料或資料集描述]`。 - Design a heatmap that represents the correlation between the following variables: `[variable list]`. - 設計一個表示以下變數之間相關性的熱圖:`[變數列表]`。 --- 以上,簡單分享,希望對您有幫助!

Composer 進階原理:PHP命名空間與PSR-0

上次的說明了PHP套件管理的歷史與社群提出的解決之道,本篇文章接著談類別管理的進階議題。 # 當類別名稱一樣... 當專案大了起來,有時候會有類別名稱重複的問題。 假設今天要撰寫一個論壇模組,提供討論區與留言板功能。 你一定很想將討論區的文章與留言板的文章都命名類別為Article: ``` // BoardArticle.php <?php class Article{ //... } ?> // ForumArticle.php <?php class Article{ //... } ?> ``` 當然了,這麼做會得到一個結果: ``` Fatal error: Cannot redeclare class Article ``` 這種問題有一個簡單的解決辦法,就是加上前綴字。 類別分別命名為ForumArticle與BoardArticle就可以了。 *Q1: 等一下!這個解法好陽春!我看到至少4個問題:* 1. 類別名稱容易變得冗長。 2. 有些類別一開始你以為不會跟人重複,結果之後真的重複了。難道永遠替類別加前綴字? 3. 類別名稱寫Article俐落多了!文章就是概念上的文章,不要逼我告訴你是討論區還是留言板!如果專案用到兩種留言板模組,分別由以前的兩個前輩寫好,難道還要逼我把作者名稱寫進去? ``` class TonyBoardArticle{ //... } class JackBoardArticle{ //... } ``` 4. 如果我在打造框架(framework)呢?幾乎會把所有常見名詞用過一次(像是Request、Loader、Response、Controller、Model等類別)!難道前面全部前綴? 看看 Codeigniter 的原始碼,全部用CI_當作前綴。超醜的。 # 命名空間(namespace)登場 於是PHP從5.3版之後支援了命名空間(namespace)。 所以可以用Article替類別定義了: ``` // BoardArticle.php <?php namespace Board; class Article{ //... } ?> // ForumArticle.php <?php namespace Forum; class Article{ //... } ?> ``` 使用類別時只要加上命名空間即可: ``` //index.php <?php include 'BoardArticle.php'; include 'ForumArticle.php'; $article = new Forum\Article(); $post = new Board\Article(); ``` 如果當前的php檔只用到其中一個Article類別,可以指定當前的php檔只用哪個命名空間+類別的組合: ``` <?php include 'BoardArticle.php'; include 'ForumArticle.php'; use Forum\Article; $article = new Article(); $fArticle = new Forum\Article(); $bArticle = new Board\Article(); ``` 如此一來,當php找不到Article類別時,便會去使用use關鍵字宣告的組合。 當然了,就算用use指定過,原本的宣告方式還是可以用的。(如最下方兩行所示) # 當東西多了起來... OK,可以繼續完成我們的論壇模組了! 討論區跟留言板有各自的文章,再來還需要「推文」: ``` <?php namespace Board; class Comment{ // ... } ?> <?php namespace Forum; class Comment{ // ... } ?> ``` 使用剛剛學到的命名空間去載入他們: ``` <?php // index.php include 'BoardArticle.php'; include 'ForumArticle.php'; include 'BoardComment.php'; include 'ForumComment.php'; $article = new Forum\Article(); $comment = new Forum\Comment(); // ... ``` 果然是漂亮的各種命名阿! *Q2: include有好多行!上次提到了Composer可以解決這種問題,當引入命名空間之後,Composer也能發揮作用嗎?* **是的。** # Composer登場 跟上次初學Composer一樣,建立一個composer.json檔: ``` { "autoload": { "files": [ "ForumArticle.php", "ForumComment.php", "BoardArticle.php", "BoardComment.php" ] } } ``` 注意,上次我們用"classmap"指定資料夾、把資料夾內檔案全掃一次,這次我們用"files"分別設定各個檔案。 再來,在terminal輸入 ``` composer install ``` 執行完畢之後,跟上次一樣,只要載入一個檔案: ``` <?php require 'vendor/autoload.php'; $article = new Forum\Article(); $comment = new Forum\Comment(); ``` 就可以使用各個類別囉! *Q3: 等一下!看起來跟沒有命名空間的時候差不多啊!一樣是把php檔自動require進去而已?* 對啊,你最上面的原始寫法,也只是手動載入好幾個檔案,在載入的時候本來就沒有特別之處: ``` <?php // index.php include 'BoardArticle.php'; include 'ForumArticle.php'; include 'BoardComment.php'; include 'ForumComment.php'; $article = new Forum\Article(); $comment = new Forum\Comment(); // ... ``` 載入php檔就只是載入,跟命名空間是兩回事。 *Q4: 還是不太對啊!上次我用classmap一次把好幾個資料夾內容掃過,這次我用files分別指定每個檔案幹嘛?Composer不是厲害在能指定資料夾去自動掃過?* ......你說的沒錯。 開個my_lib資料夾,把4個php檔都丟進去吧。composer.json這樣寫就好了: ``` { "autoload": { "classmap": [ "my_lib" ] } } ``` 再來,在terminal輸入 ``` composer install ``` 這樣就搞定了! 其實我只是想示範,除了用classmap設定資料夾之外,也可以用files直接指定檔案。 *Q5: OK,原諒你。不過,我必須說,我今天什麼都沒學到。最後還是在composer.json寫classmap而已,跟上次一模一樣。* 是的...我剛說了,載入php檔就只是載入,跟命名空間是兩回事。 我今天介紹的namespace功能是PHP本身提供的。而Composer只是協助你載入的工具、當然不可能改變程式語言本身。 Composer只是幫助你少打那一串require而已。 *Q6: ㄟ等等...有個地方我覺得很醜。我們現在的my_lib資料夾裏面有4個檔案,檔名很醜:* ``` "ForumArticle.php" "ForumComment.php" "BoardArticle.php" "BoardComment.php" ``` 類別名稱本身都是俐落的Article跟Comment了,檔案名稱還是有前綴字。但也不可能有兩個Article.php、兩個Comment.php。你有沒有辦法解決這個美感問題? 這個問題簡單,把那個my_lib資料夾刪掉,開一個Forum資料夾、一個Board資料夾。本來的ForumArticle.php改成Article.php丟進Forum資料夾、本來的BoardArticle.php改成Article.php丟進Board資料夾。composer.json改寫成這樣: ``` { "autoload": { "classmap": [ "Board", "Forum" ] } } ``` 再來,在terminal輸入 ``` composer install ``` 這招不錯吧!檔案名稱就是類別名稱,乾淨俐落! 而且資料夾的名字本身就是namespace的名稱! 以後都這樣做啦!一用到命名空間就開個同名資料夾把檔案丟進去! *Q7: 這招我覺得還好耶...。本來檔案都放在my_lib,我在composer.json只要填my_lib一行就好,現在變成要填兩行。要是我這個論壇模組有一大堆類別、用了一大堆命名空間呢?那我classmap底下不就要填入好幾行?那我寧可全部丟進my_lib,只填my_lib一行!* 唔,這樣說也是有道理。那重新建立my_lib資料夾,把Board跟Forum資料夾丟進my_lib資料夾。 composer.json改回這樣寫: ``` { "autoload": { "classmap": [ "my_lib" ] } } ``` 再來,在terminal輸入 ``` composer install ``` classmap不只是告訴Composer去載入哪幾個資料夾內的檔案,還會把資料夾內的資料夾也全部掃過一次。 怎麼樣,Composer夠神吧。 *Q8: 原來classmap底下會遞迴掃描下去...。我決定了,我的Forum跟Board都是在提供線上討論功能,我決定替我這個模組命名為Discussion。我要在my_lib底下開Discussion資料夾,然後把原本的Forum跟Board資料夾都丟進去。你覺得這個想法如何?* 還不錯。一個Discussion資料夾就是你的整個Discussion模組。 提供了討論區、留言板功能的Discussion模組,我喜歡。 *Q9: 好像忘了什麼...。啊,剛剛說命名空間跟檔案結構符合會最漂亮。那我要把那4個檔案的namespace改成這樣:* ``` <?php namespace Dicussion/Forum; class Article{ //... } ``` 剛剛說了,載入檔案就只是載入檔案,跟命名空間無關。 現在檔案結構沒變,所以我應該不用重新輸入composer install。 讓我試試...。 靠!怎麼噴error了!你騙我? ``` Fatal error: Class 'Discussion\Forum\Comment' not found ``` 呃...,我前面的說法確實有點誤導。 PHP自動載入的基本函式長這樣: ``` void __autoload ( string $class ) ``` 如你所見,PHP至少需要Composer提供資訊指出$class該去哪個檔案找。 namespace改變之後,PHP會找不到對應的$class在哪。 所以還是輸入一下composer install吧!Composer會把需要的資訊整理好的。 *Q10: OKOK,我知道了,我駕馭這一切了。我覺得這個Dicsussion模組真的超屌的,不但命名空間漂亮,連檔案結構都漂亮。我要把這個Discussion資料夾整個丟給我朋友,他們公司最近需要論壇模組。* 讓我打電話給他...。 「什麼?你們已經做好半個論壇模組了?你只需要我模組的其中幾個功能?你們的模組也是放在Discussion資料夾?」 糟糕,資料夾名稱重複了!所以我的模組拿給別人還是有不相容的可能,怎麼辦? 沒有錯..還記得你Q1提到的第3個狀況嗎?確實有把作者名稱加進去的必要! 別怕,我教你。你開一個Tony資料夾,把整個Discussion資料夾丟進去。 接著所有檔案namespace改成像這樣: ``` <?php namespace Tony/Dicussion/Forum; class Article{ //... } ``` 要用的時候就這樣喔: ``` <?php require 'vendor/autoload.php'; $article = new Tony\Discussion\Forum\Article(); $comment = new Tony\Discussion\Forum\Comment(); ``` 是變得有點長啦。 但這下搞定了吧!作者名稱再撞到的話,就改個獨特的名稱就是了! # 終於。讓我們談談PSR-0 你一定常聽到PSR-0對吧! PSR-0是PHP跨框架相容性統一標準組織訂出來的自動載入慣例。 來談談PSR-0幾個最重要的要求吧! * 命名空間加上類別名稱一定要長這樣: ``` {vendor name}\{namespace}\{class name} ``` * 前面一定要是作者名稱 * 中間可以有任意層次的命名空間、最後是類別名稱。 * 中間任意層次的命名空間直接對應到檔案結構。 發現了嗎?在剛剛Q1~Q10的過程中,其實你已經把PSR-0學完了,連設計原理都一起搞懂了。 懂這些之後,你也可以做好自己的模組、發佈到 Packagist 給全世界透過composer下載、使用了! 最後,如果遵守psr-0的話,composer.json可以這樣寫: ``` { "autoload": { "psr-0": { "Tony\\Discussion\\": "my_lib/" } } } ``` 注意,雙引號、兩次反斜線並沒有特別意思,只是 json 規定的格式。 跟classmap一樣都可以完成任務。兩者其實是有差別的...,我們下次再談。 # 結語 Composer工具以及PHP-FIG組織的出現,讓一直以來散落各地的PHP社群開始有集中的趨勢。 換句話說,各社群終於能共享彼此的library了。 然而,如你所見,psr-0不但導致檔案結構容易變得深層,還要求檔案結構必須配合程式碼,這也招致了不少批評。 https://r.je/php-psr-0-pretty-shortsighted-really.html 除此之外,composer autoload內的classmap跟psr-0到底如何分工?效能差異又為何?這些問題也都還在爭論與驗證當中。 http://stackoverflow.com/questions/22803419/why-use-a-psr-0-or-psr-4-autoload-in-composer-if-classmap-is-actually-faster 不過,PSR-0在各框架已被廣泛支援,因此建議你還是需要有所瞭解。 # 最後... 現在已經出現psr-0的替代方案,稱為psr-4。 PSR-0從2014-10-21開始被註明為不建議使用。 至於PSR-4..我們下次再談。

後端 JS 訓練一:第4課 ── 把 node 非同步設計改寫為同步設計

## 課程目標 - 把 node 非同步設計改寫為同步設計 ## 課程內容 前面我說過,node 有些地方的寫法設計,看起來很怪、很醜 在瀏覽器 js 環境,我們的確不知道用戶何時會點擊按鈕、不知道 AJAX 回應何時會拿到 不能讓網頁整個停下來卡住、等待上述事件發生,所以必須用「非同步程式設計」處理 可是檔案系統模組,絕大多數情況下,你就是要現在就讀取好檔案、讀取完才讓程式接著繼續跑,才有意義 實在沒必要用「非同步程式設計」處理! 取得用戶輸入就更不用說了,程式就是該停在這裡、等用戶輸入完再接著繼續執行,才有意義 何必用「非同步程式設計」處理! 其他程式語言,大多都是「同步程式設計」,例如用 Python 寫同樣程式時 就是一行一行寫下來即可,不用像這邊這樣把函式當參數傳進去 簡單講,javascript 的非同步設計,在網頁畫面上運作時,有其優勢與必要 但是在用來寫腳本時,顯得多餘而不必要 --- 來學習怎麼改寫吧,打開 `read-my-name.js`,改寫成以下內容 ``` var fs = require('fs'); var data = fs.readFileSync('my-name.txt'); console.log("您好," + data); process.exit(0); ``` 執行看看! ``` node read-my-name.js ``` 跑起來一模一樣,但是不是好讀多了? 注意 `fs.readFileSync` 後面的 sync,那就是同步的意思 --- 接著來改寫第二個程式吧,打開 `write-my-name.js`,改寫成以下內容 ``` var fs = require('fs'); const readlineSync = require('readline-sync'); var answer = readlineSync.question('請問您的大名?\n'); fs.writeFileSync('my-name.txt', answer); console.log('儲存成功。'); process.exit(0); ``` 是不是好讀多了? 新函式名稱,就是後面加上 sync 而已,node 官方知道大家的抱怨,所以有提供這些同步函式 但是,這段 code 不能直接執行,因為 `readline-sync` 不是官方內建模組,是社群開發的,需要透過 npm 安裝 怎麼辦? --- NPM 全稱為 Node Package Manager,也就是 Node 套件管理工具 關於 npm 的安裝,網路上有非常多教學,請根據你的作業系統,自己找一套安裝方法 安裝好之後,你就可以使用「終端機」運行 npm 指令 --- 請在終端機輸入 `npm install readline-sync` 即可安裝 `readline-sync` 套件 會多出兩個檔案 `package-lock.json` `package.json` 用來記錄目前專案用到的 npm 套件,你可以打開這兩個檔案看一看 還會多出一個資料夾 `node_modules`,套件本身會下載到這個地方,你可以打開資料夾逛一逛 接著執行看看! ``` node write-my-name.js ``` 跑起來一模一樣,但是好讀多了! ## 課後作業 接續前一課的作業,現在來嘗試「同步」的語法 請把「非同步」的語法改寫,通通改用「同步」的語法 改完之後,程式碼中,應該就不會出現 callback function 了 也就是不會出現「把一段函式定義當作參數傳進另一個函式」這種情況 完成以上任務,你就完成這次的課程目標了!

後端 JS 訓練一:第2課 ── 用 node 讀取檔案內容

## 課程目標 - 用 node 讀取檔案內容 ## 課程內容 來學習一下用 node 讀取檔案的方法 學會這方法,可以用 node 寫出簡易的檔案內容分析程式 --- 建立一個 `my-name.txt` 文字檔,在裡面輸入你的名字 然後建立 `read-my-name.js` 程式,裡面輸入 ``` var fs = require('fs'); fs.readFile('my-name.txt', function(err, data) { console.log("您好," + data); process.exit(0); }); ``` 然後去終端機輸入 ``` node read-my-name.js ``` 你會看到一段打招呼的訊息! --- 讓我們逐行說明一下 ``` var fs = require('fs'); ``` 這是載入「檔案系統模組」的意思,`fs` 是 `file system` 的縮寫 `readFile` 函式,第一個參數是檔案名稱,第二個參數是「一個函式定義」 看起來有點怪,其實是「非同步程式設計」的關係 之前在學網頁元素的事件處理時,就是用「非同步」程式設計處理 也就是我不確定「點擊」事件何時會發生,但我先「綁定」好事件發生時要做的任務 還有在網頁呼叫 AJAX 時也是,我不確定「主機回應」何時會拿到,但我先「綁定」好拿到之後要做的任務 這邊 `fs` 的意思就是:我不確定何時會「檔案讀取完畢」,但我先「綁定」好讀取完畢之後,要做的任務 看起來很怪、很醜,這種設計的意義不明,對嗎?我也覺得!後面會教你如何改寫成「同步程式設計」,先照做就好 -- `console.log` 是印出訊息到終端機(語法就跟在瀏覽器環境一樣!) `process.exit(0);` 是結束程式的意思。那個 `process` 是代表當前 node 程式的全域變數 --- 在瀏覽器裡面,無法去操作「檔案系統模組」,否則也太可怕,每個人上網時,都能用 js 亂改電腦上的檔案,資安大問題! 在瀏覽器裡面,也沒有 `process` 這個全域變數 用 node 跑完這段程式,你應該會發現,這段程式拿到網頁環境,是無法執行的! 在瀏覽器、node 跑 js 程式,有很多相似,也有很多相異之處,希望你慢慢抓到兩者的感覺! ## 課後作業 讓我們嘗試開發一個 CLI 版本的待辦管理工具 請建立一個檔案 `todos.json` 並放入以下內容 ``` [ { "title": "去操場跑步" }, { "title": "去市場採購" }, { "title": "找朋友吃飯" } ] ``` 然後建立一個 `read.js` 檔案 使用者輸入 `node read.js` 之後,終端機會去讀取 `todos.json` 並且顯示 ``` 您的待辦事項: #0 去操場跑步 #1 去市場採購 #2 找朋友吃飯 ``` 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: **方法一** 直接截圖視窗內容,上傳到留言區 **方法二** 開一個新資料夾,用 git 初始化這個資料夾 接下來的作業,都放在這個資料夾,然後上傳 github 然後把 github 專案連結,貼到留言區即可

Git 入門上手教材:第7課 ── 學會處理 git 衝突

## 課程目標 - 學會處理 git 衝突 ## 課程內容 這課來學一下 commit 彼此有衝突,而 git 沒辦法自動合併的情況吧 先挑一個資料夾,把 `my-work-1.html` 裡面隨意加上幾行內容 ``` <p>我的第一個網頁檔案</p> <p>new content a</p> <p>new content b</p> <p>new content c</p> ``` 接著 ``` git add my-work-1.html git commit -m 'new content abc' git push ``` 順利送出! 然後去另一個資料夾,把 `my-work-1.html` 裡面隨意加上幾行內容 ``` <p>我的第一個網頁檔案</p> <p>new content x</p> <p>new content y</p> <p>new content z</p> ``` 接著 ``` git add my-work-1.html git commit -m 'new content xyz' git push ``` 結果失敗了!一如預期,被 git 喊停了 ``` To github.com:howtomakeaturn/my-first-testing-repo.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'github.com:howtomakeaturn/my-first-testing-repo.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. ``` 預期之中,這時應該 pull 對吧? ``` git pull ``` ``` remote: Enumerating objects: 14, done. remote: Counting objects: 100% (12/12), done. remote: Compressing objects: 100% (4/4), done. remote: Total 8 (delta 3), reused 8 (delta 3), pack-reused 0 Unpacking objects: 100% (8/8), 792 bytes | 79.00 KiB/s, done. From github.com:howtomakeaturn/my-first-testing-repo d999c25..2cf01f4 main -> origin/main hint: Pulling without specifying how to reconcile divergent branches is hint: discouraged. You can squelch this message by running one of the following hint: commands sometime before your next pull: hint: hint: git config pull.rebase false # merge (the default strategy) hint: git config pull.rebase true # rebase hint: git config pull.ff only # fast-forward only hint: hint: You can replace "git config" with "git config --global" to set a default hint: preference for all repositories. You can also pass --rebase, --no-rebase, hint: or --ff-only on the command line to override the configured default per hint: invocation. Auto-merging my-work-1.html CONFLICT (content): Merge conflict in my-work-1.html Automatic merge failed; fix conflicts and then commit the result. ``` 在前一課,我們 pull 之後,會被 git 自動把雲端版本、跟本機你剛改過的版本,合併在一起,然後在終端機編輯器內,請你打一段小訊息,備註這次合併 這次,卻沒有進入終端機編輯器內,而是跳出一串訊息! 注意看最後幾行! ``` Auto-merging my-work-1.html CONFLICT (content): Merge conflict in my-work-1.html Automatic merge failed; fix conflicts and then commit the result. ``` 這就是 commit 衝突的情況:兩個 commit 都有改到同樣檔案,雖然先後時間不同,但是 git 不敢直接用新的蓋掉舊的! git status 看一下 ``` Unmerged paths: (use "git add <file>..." to mark resolution) both modified: my-work-1.html ``` 清楚寫出了:both modified,兩邊都修改過! 打開 `my-work-1.html` 看一下 ``` <p>我的第一個網頁檔案</p> <<<<<<< HEAD <p>new content x</p> <p>new content y</p> <p>new content z</p> ======= <p>new content a</p> <p>new content b</p> <p>new content c</p> >>>>>>> 2cf01f4f63f5ea9040610495688f08032761a170 ``` 看起來很嚇人,其實,只是 git 怕你看不清楚,用一種誇飾法,列出衝突的地方而已! HEAD 段落,是你剛提交的 commit 部份 `2cf01f4f63f5ea9040610495688f08032761a170` 的部份呢?則是剛剛從 github 抓下來的 commit 代號! 要如何處理衝突呢?其實,你就決定一下,衝突這幾行,到底要怎麼合併就可以了,然後把 git 誇飾法的地方刪掉 比方說,我決定讓行數交錯呈現吧 ``` <p>我的第一個網頁檔案</p> <p>new content a</p> <p>new content x</p> <p>new content b</p> <p>new content y</p> <p>new content c</p> <p>new content z</p> ``` 改完之後 ``` git add my-work-1.html ``` ``` git commit -m 'handle conflict' ``` 手動合併的 commit,我個人通常習慣訊息就寫 handle conflict ``` git push ``` 大功告成!這就是所謂的 git 衝突處理 ## 課後作業 接續前一課的作業 在上一次的作業,我們嘗試了兩個資料夾,同時 push 送出 commit,導致 git 比對 github 上的雲端版本時,發現有衝突,請你先 pull 再 push 的情況 上次的情況比較單純,因為雖然有衝突,但是 git 一看就知道影響不大,所以 pull 時自動處理了衝突,把事情都安排好了 這次的作業,我們要模擬「遇到衝突,而且 git 無法自動處理衝突」的情況 --- 請按照以下步驟,送出 commit **第一步** 到 `at-home` 資料夾,打開檔案 `about.html` 的內容,原本是 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發</p> ``` 請改成 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發,目標是成為厲害的前端工程師</p> ``` 然後送出 commit,接著 `git push` 出去 你會看到 github 上面就被更新了 **第二步** 到 `at-laptop` 資料夾,假設你今天出門工作,忘記先 pull 了,也忘記檔案其實你已經改好了 打開檔案 `about.html` 的內容,依然是 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發</p> ``` 請改成 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發,目標是成為厲害的軟體工程師</p> ``` 然後送出 commit,接著 `git push` 出去 這時 git 會請你先更新,於是你輸入 `git pull` 你會發現 git 表示遇到衝突,無法自動合併,請你處理! 原來有一邊是寫「前端工程師」,另一邊是寫「軟體工程師」 git 無法自動判斷你到底是想要以哪個為準!(其實用哪個都可以吧!) 請處理這個 conflict 衝突,處理完之後 push 到 github 上面 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把 github 專案連結,貼到留言區

Git 入門上手教材:第6課 ── 學會 git pull

## 課程目標 - 學會 git pull ## 課程內容 學會把專案上傳 github 了,這次來試試把專案從 github 載下來吧 假設你現在使用另一台新電腦,專案還不在你的電腦上 打開專案頁面 https://github.com/howtomakeaturn/my-first-testing-repo 頁面上有一個 `Code` 的按鈕,點下去有 clone(複製)的指示 在電腦上先移動到別的資料夾底下,使用 clone 指令把專案抓下來 ``` git clone [email protected]:howtomakeaturn/my-first-testing-repo.git ``` 完成之後,會看到在新資料夾底下,有一份一模一樣的專案! --- 在新資料夾底下,把 `my-work-3.html` 裡面隨意加上幾個字,接著 ``` git add my-work-3.html git commit -m 'commit from new folder' git push ``` 打開 github,會在上面看到有被更新! --- 回到之前的「舊資料夾」底下,把 `my-work-4.html` 裡面隨意加上幾個字,接著 ``` git add my-work-4.html git commit -m 'commit from old folder' git push ``` 會發現上傳失敗! ``` To github.com:howtomakeaturn/my-first-testing-repo.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'github.com:howtomakeaturn/my-first-testing-repo.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. ``` 原因是,git 發現,你從兩個不同的地方,分別更新過不同檔案,git 怕你會搞混編輯歷史紀錄 (github 上現在有4筆 commit,目前資料夾上也是4筆 commit,git 無法分辨哪個第4筆是最新的) 所以 git 希望你能先把最新版本抓下來,再送出你的版本,比較不會有爭議! 把新版本抓下來的指令是 ``` git pull ``` 抓完之後,因為 git 自動把雲端版本、跟本機你剛改過的版本,合併在一起了 會請你打一段小訊息,備註這次合併 通常你就使用 `ctrl + x` 或者 `:q` 離開終端機編輯器就可以了 完成之後,使用 `git log` 會看到,現在有6筆 commit 紀錄,最後一筆是剛剛自動合併的 commit ``` Merge branch 'main' of github.com:howtomakeaturn/my-first-testing-repo ``` 使用 `git status` 也會看到 ``` On branch main Your branch is ahead of 'origin/main' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean ``` git 提示你目前比雲端版本還多了 2 筆 commit(一筆是你剛加的,一筆是關於自動合併的) 使用 `git push` 通通推上去 github 吧! --- 看到這邊你可能會想,剛剛那筆自動合併的 commit 好像有點多餘? 就把 `commit from new folder` 以及 `commit from old folder` 按照時間順序排列,不就好了嗎? 其實,那是因為這兩筆 commit 內容沒有重疊,所以看起來很單純 實務上很多時候,兩筆 commit 會更新到「相同的檔案」之中的「同樣幾行程式碼」 這時 git 如果按照時間順序排列,就會讓「較晚送出 commit 的人」把「較早送出 commit 的人」的工作內容覆蓋掉! 這樣一來,根本沒辦法團隊工作:晚提交的人,會一直破壞掉早提交的內容! 所以 git 一律會多一筆「合併 commit」。平常就自動合併沒問題,有衝突時,就可以在這筆 commit 處理 有點不懂沒關係,我們下一課會練習 ## 課後作業 接續前一課的作業,專案已經傳到 github 了 假設你原本是用家裡的電腦開發,現在你打算帶著筆電,出門到咖啡廳繼續開發 請拿出你的筆電,把 github 上那個專案 `git clone` 到筆電上面 如果你沒有筆電,沒關係,在電腦上另外找個資料夾,用 `git clone` 從 github 抓專案下來 這樣兩個資料夾對應同一個專案,也可以,模擬跨裝置同步專案 --- 現在分別有兩個資料夾,內容一模一樣,我這邊分別用 `at-home` 以及 `at-laptop` 稱呼兩個資料夾 請按照以下步驟,送出 commit **第一步** 到 `at-home` 資料夾,建立一個檔案 `create-this-file-at-home.html` 內容放 ``` <p>我在家裡新增這個檔案</p> ``` 然後送出 commit,接著 `git push` 出去 你會看到 github 上面就被更新了 **第二步** 到 `at-laptop` 資料夾,建立一個檔案 `create-this-file-at-laptop.html` 內容放 ``` <p>我在咖啡廳新增這個檔案</p> ``` 然後送出 commit,接著 `git push` 出去 你會看到錯誤訊息! git 會跟你說,有衝突,請先將資料夾內容下載同步,再更新 **第三步** 所以請輸入 `git pull` 先把資料夾更新到最新版本 接著用 `git log` 看一下,會看到有關 `create-this-file-at-home.html` 那個檔案的 commit **第四步** 這時再 `git push` 出去 你會看到 github 上面就被更新了 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把 github 專案連結,貼到留言區

Git 入門上手教材:第5課 ── 學會連線 github

## 課程目標 - 學會連線 github ## 課程內容 git 工具,光是一個人離線使用,就已經很好用了 再加上雲端功能,變成雲端專案,那就會更強大 上傳專案可分為兩種類型 第一種是公開專案 public repository 也就是所謂的開源專案 open source 在實務上,軟體工程師,會大量使用彼此開源分享出來的專案 學習跟開源社群互動,是工程師一個極度重要的技能 當然不可能所有程式碼都免費熱心給人用,所以會有第二種,稱為私人專案 private repository 也就是自己、或者團隊的私人專案 --- 業界最常用的 git 雲端服務有三家 github、gitlab、bitbucket 當然公司要自己架一套自己的 git server 也可以 不過以 open source 來說,主要會在 github 上面 --- 請自行註冊 github 帳號,之後建立一個 github 專案 Create a new repository -> 幫專案簡單命名 `my-first-testing-repo` -> 類型選 Public -> 初始化時別加任何檔案(通通選 None) 舉例來說,我剛建立的專案,網址在這: https://github.com/howtomakeaturn/my-first-testing-repo 回到本機的專案底下,依序輸入下列指令 ``` git remote add origin [email protected]:howtomakeaturn/my-first-testing-repo.git ``` 設定雲端 git 對應網址 ``` git branch -M main ``` 建立一個命名為 main 的分支 (本機上的分支命名是預設的 master,近年因為這有奴隸時代主人/奴僕的影子,在轉型正義之下,很多廠商把預設分支名稱改為 main) ``` git push -u origin main ``` 把本機的程式碼,推到 github 上去 --- 在網路上找文章的時候,有時候會看到主分支叫 master,有時會看到叫 main 這是因為轉型正義、政治正確的關係,新舊慣例有點衝突,自己習慣、轉換一下即可 --- 另外,在設定雲端 git 位置的時候,有文章會寫 `https://` 開頭,有文章會寫 `git@` 開頭 ``` git remote add origin https://github.com/howtomakeaturn/my-first-testing-repo.git ``` ``` git remote add origin [email protected]:howtomakeaturn/my-first-testing-repo.git ``` 其實功能一樣,前者是每次跟雲端 git 互動,都要驗證輸入帳密 後者是比較方便,每次都自動檢查電腦上的 ssh key 驗證,但一開始設定 key 會花些時間 通常來說,任意挑一種方式,都可以。但是 github 在 2021 年開始,不再允許 git push 時使用帳密驗證 所以,就去學一下 ssh key 的設定方式吧!需要在本機建立 ssh key,然後到 github 更新 key 資訊 請根據你的作業系統,自己上網找一下建立 ssh key 的方式,然後再找一下 github 設定 ssh key 的地方 --- 完成之後,這個開源專案,不但可以線上看到程式碼 https://github.com/howtomakeaturn/my-first-testing-repo 還可以線上看到 commit 提交紀錄 https://github.com/howtomakeaturn/my-first-testing-repo/commits/main ## 課後作業 接續前一課的作業,現在你打算把專案上傳到 github,當做雲端備份,也方便跟別人分享原始碼 請註冊一個 github 帳號,建立一個新的 repository,並且把之前做的個人品牌網站,上傳到 github 上傳之後,你應該會在 github 專案的頁面,看到專案的程式碼,也能看到多筆 commit 歷史紀錄 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把 github 專案連結,貼到留言區

Git 入門上手教材:第3課 ── 學會 git 版本切換

## 課程目標 - 學會 git 版本切換 ## 課程內容 上次的內容順利提交之後 這次讓我們試試看切換版本功能! 在 git log 內,每個 commit 紀錄後面,會看到一串提交代號,類似這樣 `0e78f9d62d1342f29b1a2a3af8b751f1a4d653ef` git 強大的版本歷史功能,就跟這個相關 請找到前一筆提交的代號,然後輸入切換版本指令 ``` git checkout 148106fcb1a496ab034ad5f6253c1dd8fe21eb22 ``` 看一下資料夾內容,會發現就跟「搭時光機」一樣,整個專案的狀態「回溯」到上一次提交了! 再看一下這時 `git log` 會顯示什麼,會發現歷史紀錄也只剩兩筆了! 你可以再找出更前一筆提交代號 ``` git checkout 0e78f9d62d1342f29b1a2a3af8b751f1a4d653ef ``` 會發現回溯到第一筆提交狀態了!神奇吧! --- 時光機搭完了,要如何回到最新狀態呢? ``` git checkout master ``` 這樣就行了! master 其實是主要的 branch 名稱 先不用管 branch 是什麼意思,之後會提到 在學習 git 過程中,很多東西先「享受用起來的好處」就夠了 背後機制與觀念,有點一知半解沒關係,真的卡關再去鑽研就可以了 反正目的就是管理檔案的歷史版本而已嘛! ## 課後作業 接續前一課的作業,你的專案目前有三個 html 檔案 你突然又有點反悔,覺得原本全部資訊寫在 `index.html` 那樣比較好? 開發專案時,像這樣反反覆覆其實很正常,就切回去看一下,感覺看看有沒有比較好,再決定即可 請使用 `git checkout {版本}` 指令,切回前一個 commit 的版本 你可以看一下資料夾內容,應該會發現變回之前的樣子了! --- 請輸入 `git log`,應該會發現,歷史紀錄也倒退了一個版本! 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把整段 `git log` 顯示的文字內容複製,貼到留言區 也可以直接截圖視窗內 `git log` 的內容,上傳到留言區

Git 入門上手教材:第2課 ── 學會 git 基本指令

## 課程目標 - 學會 git 基本指令 ## 課程內容 來建立第一個檔案吧,請建立 `my-work-1.html` 並放入以下內容 ``` <p>我的第一個網頁檔案</p> ``` 接著用 `git status` 看看狀況 會看到檔案名稱顯示為「紅色」,並放在「Untracked」訊息下方 這代表 git 已經發現它的存在了 --- 接著來開始追蹤檔案 ``` git add my-work-1.html ``` 然後輸入 `git status` 看看狀況 會看到檔案名稱顯示為「綠色」,並放在「to be committed」訊息下方 這代表 git 已經把它放入暫存區,準備好正式納入歷史紀錄了 --- 來建立第二個檔案試試吧,請建立 `my-work-2.html` 並放入以下內容 ``` <p>我的第二個網頁檔案</p> ``` 接著用 `git status` 看看狀況 會看到新的檔案又顯示為紅色,暫存區的檔案一樣是綠色沒變 接著再繼續追蹤 ``` git add my-work-2.html ``` 然後輸入 `git status` 看看狀況 會看到兩個檔案都顯示為綠色,代表都放入暫存區了 --- 之所以會分成那麼多步驟,是因為開發者寫程式,很像是作家寫小說/漫畫家畫漫畫,交給出版社那樣 首先,你手上會有很多隨手草稿,這些看不順眼可以隨時丟掉,也就是 git 顯示為紅字的部份 接著,你覺得比較滿意的幾張紙會挑出來,放在旁邊,但你不會直接交給出版社,而是先整理在旁邊,也就是 git 顯示為綠字的部份 然後,哪些是滿意的?哪些是草稿?這兩部份你會一直改變心意,也就是有的會從紅色移進綠色,有的會從綠色移進紅色,一直來回修改,到你滿意為止 最後,你才會把這次要交給出版社的那些滿意部份,通通放進牛皮紙袋,一口氣交給出版社,而 git 版本管理就是在模擬這個過程 --- 來正式提交我們的第一次版本紀錄吧! 需要打一段提示訊息,方便日後翻閱,大致知道每個提交的內容 ``` git commit -m 'this is my first commit, i am so happy!' ``` 完成之後,請再輸入 `git status` 看看,會看到又變得乾乾淨淨了,因為目前沒有正在「工作」的稿件 然後輸入 `git log` 看看,應該會看到剛剛那筆提交紀錄囉! --- 讓我們多提交幾次檔案,試試看多次提交的感覺! 先建立新檔案,請建立 `my-work-3.html` 並放入以下內容 ``` <p>我的第三個網頁檔案</p> ``` ``` git add my-work-3.html ``` ``` git commit -m 'add another work' ``` --- 然後再建立新檔案一次,請建立 `my-work-4.html` 並放入以下內容 ``` <p>我的第四個網頁檔案</p> ``` ``` git add my-work-4.html ``` ``` git commit -m 'add one more work' ``` --- 然後輸入 `git log` 看看,應該會看到總共三筆提交紀錄! --- 在 git 專有名詞中,檔案的狀態分為 untracked/unmodified/modified/staged/commited 提交則稱為 commit 不同文章,有時會用不同的稱呼,一開始有點混亂沒關係,久了會慢慢習慣 記得我說的作家與出版社的比喻即可,我會用 `草稿/紅色 vs 滿意區/綠色` 來描述檔案狀態 反正就是「新增檔案 -> 編寫草稿 -> 放進滿意區 -> 最後一口氣把滿意區的所有檔案提交出去」 然後身為作家,就是每個截稿日之前,都重複一次上面這個流程,就這樣而已 學習的過程,養成習慣,經常 `git status` `git log` 看一下,就會更清楚了! ## 課後作業 假設你正要做一個網站,來做自我介紹、經營個人品牌 請繼續用前一課作業的資料夾,用來放整個網站的檔案 然後要模擬實際開發的時候,先寫筆記規劃,接著一直增減檔案的過程 請按照以下順序送出 commit **第一個 commit:** 新增一個 `README.md` 檔案,裡面放入以下內容(實務上,每個專案通常都會放這個檔案,內容是給自己看的專案筆記,不會出現在網站上): ``` # 簡介 這專案用來放我的個人品牌網站內容 # 規格 預計包含簡介、學經歷,等等頁面 ``` **第二個 commit:** 新增一個 `index.html` 檔案,裡面放入以下內容 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發</p> <h1>我的學歷</h1> <p>高中:積極高中</p> <p>大學:品質大學</p> ``` **第三個 commit:** 你改變心意,覺得拆成多個頁面比較好看,也比較容易分別追蹤瀏覽次數 請把 `index.html` 檔案的內容清空,改放以下內容 ``` 我是XXX,請參考其它頁面,瞭解更多我的介紹與背景。 ``` 新增 `about.html` 以及 `background.html` 兩個檔案 並且把 `我是誰` 的內容放進 `about.html`,把 `我的學歷` 的內容放進 `background.html` --- 最後,請輸入 `git log`,應該會看到以上三個 commit 的訊息! 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把整段 `git log` 顯示的文字內容複製,貼到留言區 也可以直接截圖視窗內 `git log` 的內容,上傳到留言區

10 個可以改善開發體驗的 VSCode 外掛

- 原文出處:https://dev.to/j471n/vs-code-extensions-to-take-your-coding-to-the-next-level-50od ## Documatic 此外掛將 [Documatic](https://www.documatic.com/) 引入 VSCode:使用簡單查詢快速搜尋大型程式碼庫。 Documatic 使用 AI 連結您的查詢和程式碼片段之間的關係,因此您不必知道要查找的確切關鍵字! **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=Tyriar.sort-lines) ![](https://i.imgur.com/KYutr9T.gif) ## Sort lines 此外掛允許您按字母或數字快速對程式碼進行排序,從而在處理大文件時節省時間。當您有要排序的資料時,這會非常方便。 **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=Tyriar.sort-lines) ![使用動畫](https://github.com/Tyriar/vscode-sort-lines/raw/HEAD/images/usage-animation.gif) ## TabNine 此外掛使用 AI 提供程式碼自動完成建議,可以幫助您節省時間並提高程式碼品質。它支援很多語言和框架。但是要小心使用它,因為它會佔用你系統的很多資源。 **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=TabNine.tabnine-vscode) ![Tabnine 主要完成](https://raw.githubusercontent.com/codota/tabnine-vscode/master/assets/completions-main.gif) ## **Template String Converter** 可以在程式碼編輯器中鍵入“${”時將普通字串轉換為模板字串。 **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=meganrogge.template-string-converter) ![鍵入一個美元符號然後在字串中打開大括號將引號轉換為反引號](https://raw.githubusercontent.com/meganrogge/template-string-converter/master/images/demo.gif) ## **Error Lens** ErrorLens 增強了語言診斷功能,突出顯示語言生成診斷的整行,並連結相關訊息。 **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) ![演示圖片](https://raw.githubusercontent.com/usernamehw/vscode-error-lens/master/img/demo.png) ## **WakaTime** [WakaTime](https://wakatime.com/vs-code) 是一個開源 VS Code 外掛,用於從您的寫程式工時中,自動生成指標、分析和時間追蹤。 **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=WakaTime.vscode-wakatime) ![專案概覽](https://wakatime.com/static/img/ScreenShots/Screen-Shot-2016-03-21.png) ## **Chat** 通過使用此外掛,您可以在 VS Code 中與您的 Slack 和 Discord 團隊聊天。 * **安靜的通知**:聊天應用程式可能會讓人分心。此外掛使聊天變得有用、上下文相關且不會分散注意力。 * **豐富的格式**:分享 Markdown 程式碼片段,並在您的聊天訊息中加入表情符號。 * **本地外觀**:在您喜歡的主題和網格編輯器佈局中使用聊天。 **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=karigari.chat) ![截圖](https://raw.githubusercontent.com/karigari/vscode-chat/master/readme/Live%20Share%20Chat.gif) ## **SVG Preview** 允許您直接在 VS 程式碼中查看 SVG 文件。如果您在 vs 程式碼中打開 SVG 文件,那麼預設情況下它會顯示 SVG 程式碼。使用它後,您可以看到 SVG 的預覽。 **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=SimonSiefke.svg-preview) ![演示](https://github.com/SimonSiefke/vscode-svg-preview/raw/master/demo_images/demo.gif) ## **Headwind** Headwind 是用於 Visual Studio Code 的 Tailwind CSS 類排序器。它通過解析您的程式碼並重新打印類別標籤來強制執行一致的類別排序。 **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=heybourn.headwind) ![解釋器](https://github.com/heybourn/headwind/blob/master/img/explainer.gif?raw=true) ## **Material Design Palette Generator** [Material Design Palette Generator](https://marketplace.visualstudio.com/items?itemName=piyush-bhatt.vscode-mat-palette) 是一個 VSCode 外掛,用於生成 [material 調色板](https://material.io/design/color/the-color-system.html#tools-for-picking-colors)。 **⬇️** [**下載**](https://marketplace.visualstudio.com/items?itemName=piyush-bhatt.vscode-mat-palette) ![獲取從給定的十六進制顏色生成的完整調色板](https://raw.githubusercontent.com/piyush-bhatt/vscode-mat-palette/master/assets/readme/Primary.gif) --- 以上,簡單分享,希望對您有幫助!