教程的問題
2022 年 3 月 8 日,作者:Burke Holland,@burkeholland
撰寫一篇出色的教程並非易事。我深有體會——我寫過很多教程,但並非每一篇都取得了巨大的成功。
事實證明,製作一篇出色的教程的關鍵不在於你寫了什麼,而在於開發者是否能在不閱讀每個字的情況下取得成功。在本文中,我們將探討開發容器如何減少使用者可能遇到的錯誤,以及 Laravel PHP 專案 如何在其教程中優雅地實現這一點並取得了顯著效果。
沒人會閱讀
我們關於 如何在 Visual Studio Code 中使用開發容器 的教程一直以來完成率都很低——大約只有 4% 到 6%。

為了弄清楚人們在哪裡放棄了,我們進行了使用者研究,並觀察了人們嘗試完成我們教程的過程。那過程……令人痛苦。
人們無法完成教程的原因立即變得清晰起來:沒人會閱讀它。人們跳過了說明,直接進入操作步驟。不可避免地,他們會因為犯了一個錯誤而卡住,如果他們閱讀了說明,就不會犯這個錯誤。
賓夕法尼亞州立大學教授 John M. Carroll 在他的重要著作《紐倫堡漏斗——為實用計算機技能設計極簡主義教學法》(The Nurnberg Funnel - Designing Minimalist Instruction for Practical Computer Skill)中討論了這個問題。他寫道:“[學習者]太忙於學習,以至於無法充分利用指導。這是意義構建的悖論。”
我對此深有體會,你可能也是。當我瀏覽教程時,我的眼睛在尋找程式碼塊,因為我正試圖透過實踐來學習。我真的太忙於學習而無暇閱讀說明。
人們不會閱讀你的教程。或者至少不會像你希望的那樣多。你能做的最好的事情就是儘可能多地移除讀者在學習過程中可能犯錯的地方。其中一種方法是使用預配置的容器環境,完全移除任何環境設定步驟。
容器化開發環境
任何教程中很大一部分通常都致力於一長串的先決條件和環境設定。我清楚地記得嘗試學習 Ruby on Rails 時,大部分時間都在努力在 Windows 上正確安裝 Ruby,想知道“gem”到底是什麼,為什麼它們總是缺失。
容器化開發環境背後的理念是你在 Docker 容器內部進行開發。這使得擁有一個完全可移植、完全配置的開發環境成為可能,你可以隨意啟動或關閉它。然後,你可以將這個環境作為一組配置檔案提供給其他人。
但是如何在容器內部進行開發呢?容器又沒有一個你可以直接啟動 VS Code 的 UI。
VS Code 的 開發容器 擴充套件正是這樣做的。它既包含將 Docker 容器配置為開發環境的機制,又允許你從 VS Code 連線到該環境。它是透過在容器內部安裝一個小型的伺服器元件來實現的,你的本地 VS Code 與之通訊。然後你就像在本地一樣進行開發,但 VS Code 連線的是容器環境而不是你的本地環境。

為了建立容器化開發環境,你通常需要對 Docker 有所瞭解。很多人確實瞭解,但很多人不瞭解(你看不到我,但我的手正舉著),所以這個擴充套件試圖儘可能多地抽象容器設定過程。我設定了一個新的 Python 容器。一個嚮導會引導你選擇基礎映象和 Python 版本。然後它讓你有機會透過一個選擇列表向映象新增額外的軟體。在這種情況下,我添加了 Azure CLI、Dotnet CLI 和 PowerShell……

這個過程會向該專案新增一個 .devcontainer 資料夾,其中包含必要的 Dockerfile。它還會新增一個 devcontainer.json 檔案,這是定義開發容器各個方面的標準,例如應該安裝哪些擴充套件,在容器構建後應該執行哪些設定命令等等。由於你對環境及其設定擁有完全控制權,你可以自動化幾乎所有事情——包括依賴項安裝、庫版本等。
透過這種方式,你可以字面上地交給某人一個完整的、即用型的環境,無需額外的設定步驟,也不會因為 Ruby gems 而引發生存危機。
一些人已經在使用基於開發容器的方法,讓他們的使用者快速啟動和執行原本非常複雜的環境。Laravel PHP 框架就是一個很好的例子。
Laravel 的解決方案
Laravel 是一個用於 PHP 的開源 MVC 框架。它非常全面,包括物件關係對映器 (ORM)、直接資料庫訪問、打包系統等等。Laravel 功能強大。為了體驗它,你在入門時至少需要有一個數據庫。通常這需要使用者不僅安裝 PHP,還要安裝一個數據庫——通常是 MySQL。當用戶只是想試用你的框架時,這是一個很高的要求。
Laravel 透過容器化開發環境和名為 Sail 的工具解決了這個問題。要從零開始使用 Laravel、MySQL 伺服器和 Redis 快取,你只需執行一個命令……
curl -s "https://laravel.build/example-app?with=mysql,redis" | bash
這將建立一個帶有 docker-compose 檔案的新專案。此檔案設定了三個容器——一個應用程式容器、一個 MySQL 容器和一個 Redis 容器。你無需瞭解有關容器或這三個服務的任何資訊。Sail 為你抽象了所有這些。然後你執行 Sail 命令來啟動環境……
./vendor/bin/sail up
示例應用程式就會執行起來。無需安裝 PHP。無需安裝 Laravel。無需依賴項解析步驟。只有即時的成功。

我指定我們的專案有一個 MySQL 伺服器和一個 Redis 快取,所以當專案啟動時,我們實際上得到了三個容器。我們可以使用 VS Code 的 Docker 擴充套件 來檢視。

這些容器透過網路連線在一起,這樣我們就可以從應用程式容器呼叫 MySQL 或 Redis 快取容器。
如果你連線一個互動式終端到 sail-8.1/app container,你會在 /var/www/html 資料夾中看到你的專案。Docker 將你的機器上的專案“掛載”到容器中,因此你在開發時所做的任何更改都會在重新整理應用程式時反映出來。

新增開發容器
對 開發容器 擴充套件的支援也已新增。要將適當的開發容器配置新增到此專案,你可以搭建相同的專案並新增 &devcontainer 標誌。
curl -s "https://laravel.build/example-app?with=mysql,redis&devcontainer" | bash
請注意,如果你想向現有的 Sail/Laravel 專案新增開發容器,可以透過執行
php artisan sail:install --devcontainer來實現。
這將建立相同的專案配置,但會包含一個 .devcontainer 資料夾。VS Code 會自動檢測到該資料夾並提示你在容器中重新開啟專案,從而跳過必需的 sail up 步驟。

VS Code 連線到容器,因此你正在容器環境內部進行開發,而不是在本地環境中。你會知道這一點,因為 VS Code 左下角的遠端指示器會告訴你……

在容器中開發而不是在容器外部開發有一些明顯的優勢。
開發上下文與應用程式上下文一致
連線到容器時,你所處的開發上下文與應用程式執行的上下文相同。因此,你的終端變成了容器的終端……

開發容器擴充套件還為你提供了更完整的檢視,例如哪些埠被轉發了——以防你忘記應用程式在哪裡執行。

Laravel 應用程式自動啟動,應用程式日誌被管道到容器日誌。既然你可能想看看應用程式中發生了什麼,開發容器擴充套件在 VS Code 中提供了一個新檢視,你可以在其中看到所有正在執行的容器,並連線到流式傳輸容器日誌。

自動化開發環境設定
最佳的開發者體驗將包括對編輯器的定製。這包括編輯器本身的設定,以及需要新增到開箱即用體驗中的任何擴充套件或其他支援。
對於 VS Code 和 Laravel,擴充套件在 devcontainer.json 中建議,但被註釋掉,因此不會自動安裝。這允許使用者從一組已經確定的擴充套件中進行選擇,而不必去尋找配置編輯器的正確方法。
...
"extensions": [
// "mikestead.dotenv",
// "amiralizadeh9480.laravel-extra-intellisense",
// "ryannaddy.laravel-artisan",
// "onecentlin.laravel5-snippets",
// "onecentlin.laravel-blade"
],
少讀多做
人們不閱讀。這應該是可以接受的。Laravel 的教程不一定比其他教程短,但重要的是,如果你跳到程式碼並直接執行命令,它就能工作。開發容器使這成為可能。現在如果我們能弄清楚如何為我們自己的 使用 Docker 容器作為 Visual Studio Code 的開發環境 教程製作一個開發容器就好了……
編碼愉快!
Burke Holland (@burkeholland)