如何在Codespaces中執行一個前端研討會/教學會

如何在Codespaces中執行一個前端研討會/教學會

自2018年以來,我為15-25人的班級教授網路開發入門課程。這對我來說是一個有益的經驗。有趣的是:我的父母都是教師,實際上是在我的小學教書,這讓我發誓永遠不會成為一名教師。具有諷刺意味的是,我的職業是以教人們學習技術為中心。

我的經驗告訴我,當你沒有正確的技術時,教師和學習者的挫折感就會積累起來。例如,當我教大家HTML、CSS和JavaScript時,我們總是在每節課的前15分鐘確保所有與會者都能接觸到啟動程式碼,能夠在本地執行程式碼,並且能夠跟隨。

更加複雜的是,這些學習者都是遠端的,從來沒有寫過程式碼,所以很難說每個人是否正確地克隆了資源庫,使用了正確的檔案。

有時,我會告訴他們只是複製和貼上啟動程式碼中每個檔案的內容,但這也會出現問題。學員們會把它們放在錯誤的檔案裡,或者沒有使用正確的副檔名。這是一個爛攤子,但可以理解!當我第一次學習程式碼時,我也有類似的經歷。我參加研討會,花了整整一天的時間試圖建立我的環境。與此同時,我周圍的人卻在創造傑作。

我終於找到了解決研討會和培訓初級開發人員編碼的混亂局面的辦法–GitHub Codespaces

為什麼Codespaces是一個最佳解決方案

在Codespaces中執行一個研討會,為所有參與者創造了更好的體驗。與其期望初級開發人員瞭解如何克隆倉庫以使用模板,他們可以開啟一個Codespace,在我建立的開發環境中工作。現在,我可以放心了,每個人都有和我一樣的環境,可以輕鬆地跟上。這減少了大量的時間、壓力和混亂。作為一個研討會的參與者,在研討會上掙扎著跟上,有時會讓我的自尊心破裂,或者讓我失去興趣。有了Codespaces,參與者可以自信地跟上,並富有成效地學習。

每個講習班參與者的經驗

我為每個參與者建立的體驗類似於以下內容:

  • 學員開啟一個Codespace,它立即載入了我要求的擴充套件:
    • ESLint – 這有助於學習者快速識別並減少他們程式碼中的任何問題
    • Prettier – 這可以幫助學習者將他們的程式碼格式化,使之易於閱讀和遵循。
    • Live Share – 學習者可以用它來相互協作和配對程式設計。
    • Deploy to GitHub Pages – 這是我開發的一個擴充套件,幫助人們快速地將他們的靜態網站部署到GitHub頁面。這個擴充套件減少了我需要指導學員配置GitHub頁面的額外步驟。取而代之的是,只需點選幾個按鈕,他們就可以留在自己的IDE裡。閱讀這篇博文,瞭解如何使用該擴充套件,並檢視這篇博文,瞭解我是如何建立該擴充套件的。
    • Panda Theme – 雖然這是不必要的,但初級開發者往往注重準確性。他們想記住每一個方法,而當他們所跟隨的會話有不同顏色的語法高亮時,他們有時會感到不確定。多次,學習者表示擔心他們可能打錯了什麼,因為我的變數是粉紅色的,而他們的變數是藍色的。為了解決這個問題,我設定大家在研討會上使用與我相同的主題。
    • CodeSwing – 我在GitHub欣賞的傑出軟體工程師Jonathan Carter創造了這個擴充套件。這將一個類似於Codepen的檢視帶入你的IDE。這對學習者有好處,因為他們可以實時看到他們所做的視覺變化,而且他們更容易區分HTML、CSS和JavaScript程式碼。
    • Code Tour – Jonathan Carter也開發了這個擴充套件,在程式碼庫中提供指導性的走訪。我使用這個擴充套件來保持學習者的進度,並使遠端指導更容易。
    • Code Spell Checker – 這可以幫助學習者在他們的程式碼中抓出錯別字!
  • 在擴充套件程式載入後,學習者會立即看到他們網站的實時預覽,並通過CodeSwing看到HTML、CSS和JavaScript的三個桶。
  • 接下來,學習者會收到來自CodeTour的提示,要求他們更新程式碼行並與程式碼庫互動。
  • 在確保他們的程式碼庫和網站符合要求後,他們可以使用部署到GitHub Pages擴充套件來發布他們的網站。

這就是了!通過利用Codespaces,我創造了一個順利的研討會經驗,向人們介紹HTML、CSS和JavaScript,並將網站部署到GitHub Pages。

如何為前端研討會配置一個Codespace

建立Codespace

下面的圖片舉例說明了如何在你的倉庫中建立一個新的codespace。如果你有更多關於建立和配置程式碼空間的問題,請查閱GitHub官方文件

建立Codespace

新增你的前端啟動程式碼

在這個例子中,我使用了HTML、CSS和JavaScript。請注意,每個檔案都包含一些小錯誤,我在挑戰研討會參與者的解決能力。如果你想跟著這篇博文學習如何設定Codespace,你可以建立以下檔案:

index.html

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>What Time is It?</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="clock">
<h1 id="twelve">12</h1>
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
<!-- update the question mark to the number 6 -->
<h1 id="six">?</h1>
</div>
<script src="script.js"></script>
</body>
</html>
<DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>What Time is It?</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="clock"> <h1 id="twelve">12</h1> <div class="clock-face"> <div class="hand hour-hand"></div> <div class="hand min-hand"></div> <div class="hand second-hand"></div> </div> <!-- update the question mark to the number 6 --> <h1 id="six">?</h1> </div> <script src="script.js"></script> </body> </html>
<DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>What Time is It?</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="clock">
<h1 id="twelve">12</h1>
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
<!-- update the question mark to the number 6 -->
<h1 id="six">?</h1>
</div>
<script src="script.js"></script>
</body>
</html>

style.css

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
html {
background-size:cover;
font-family:'helvetica neue';
text-align: center;
font-size: 10px;
}
h1{
color: #FFC312;
text-shadow: 2px 2px 4px #000000;
}
body {
/*change the background color to a gradient of your choice*/
background: linear-gradient(to bottom right, #47D457, #0F1CCD);
margin: 0;
font-size: 2rem;
display:flex;
flex:1;
min-height: 100vh;
align-items: center;
}
.clock {
width: 50rem;
height: 50rem;
border:20px solid white;
border-radius:50%;
margin:50px auto;
position: relative;
padding:2rem;
box-shadow:
0 0 0 4px rgba(0,0,0,0.1),
inset 0 0 0 3px #EFEFEF,
inset 0 0 10px black,
0 0 10px rgba(0,0,0,0.2);
}
.clock-face {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-3px); /* account for the height of the clock hands */
}
.hand {
width:50%;
height:6px;
background:lightgrey;
position: absolute;
top:30%;
transform-origin: 100%;
transform: rotate(90deg);
transition: all 0.05s;
transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
box-shadow:
0 0 0 4px rgba(0,0,0,0.1),
inset 0 0 0 3px #EFEFEF,
inset 0 0 10px black,
0 0 10px rgba(0,0,0,0.2);
}
#six{
margin-top:-150px;
}
html { background-size:cover; font-family:'helvetica neue'; text-align: center; font-size: 10px; } h1{ color: #FFC312; text-shadow: 2px 2px 4px #000000; } body { /*change the background color to a gradient of your choice*/ background: linear-gradient(to bottom right, #47D457, #0F1CCD); margin: 0; font-size: 2rem; display:flex; flex:1; min-height: 100vh; align-items: center; } .clock { width: 50rem; height: 50rem; border:20px solid white; border-radius:50%; margin:50px auto; position: relative; padding:2rem; box-shadow: 0 0 0 4px rgba(0,0,0,0.1), inset 0 0 0 3px #EFEFEF, inset 0 0 10px black, 0 0 10px rgba(0,0,0,0.2); } .clock-face { position: relative; width: 100%; height: 100%; transform: translateY(-3px); /* account for the height of the clock hands */ } .hand { width:50%; height:6px; background:lightgrey; position: absolute; top:30%; transform-origin: 100%; transform: rotate(90deg); transition: all 0.05s; transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1); box-shadow: 0 0 0 4px rgba(0,0,0,0.1), inset 0 0 0 3px #EFEFEF, inset 0 0 10px black, 0 0 10px rgba(0,0,0,0.2); } #six{ margin-top:-150px; }
html {
background-size:cover;
font-family:'helvetica neue';
text-align: center;
font-size: 10px;
}
h1{
color: #FFC312;
text-shadow: 2px 2px 4px #000000;
}
body {
/*change the background color to a gradient of your choice*/
background: linear-gradient(to bottom right, #47D457, #0F1CCD);
margin: 0;
font-size: 2rem;
display:flex;
flex:1;
min-height: 100vh;
align-items: center;
}
.clock {
width: 50rem;
height: 50rem;
border:20px solid white;
border-radius:50%;
margin:50px auto;
position: relative;
padding:2rem;
box-shadow:
0 0 0 4px rgba(0,0,0,0.1),
inset 0 0 0 3px #EFEFEF,
inset 0 0 10px black,
0 0 10px rgba(0,0,0,0.2);
}
.clock-face {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-3px); /* account for the height of the clock hands */
}
.hand {
width:50%;
height:6px;
background:lightgrey;
position: absolute;
top:30%;
transform-origin: 100%;
transform: rotate(90deg);
transition: all 0.05s;
transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
box-shadow:
0 0 0 4px rgba(0,0,0,0.1),
inset 0 0 0 3px #EFEFEF,
inset 0 0 10px black,
0 0 10px rgba(0,0,0,0.2);
}
#six{
margin-top:-150px;
}

script.js

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const secondHand = document.querySelector('.second-hand');
const minsHand = document.querySelector('.min-hand');
const hourHand = document.querySelector('.hour-hand');
function setDate() {
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = ((seconds / 60) * 360) + 90;
secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
const mins = now.getMinutes();
const minsDegrees = ((mins / 60) * 360) + ((seconds/60)*6) + 90;
minsHand.style.transform = `rotate(${minsDegrees}deg)`;
const hour = now.getHours();
// change seconds to hours on the line below
const hourDegrees = ((seconds / 12) * 360) + ((mins/60)*30) + 90;
hourHand.style.transform = `rotate(${hourDegrees}deg)`;
}
setInterval(setDate, 1000);
setDate();
const secondHand = document.querySelector('.second-hand'); const minsHand = document.querySelector('.min-hand'); const hourHand = document.querySelector('.hour-hand'); function setDate() { const now = new Date(); const seconds = now.getSeconds(); const secondsDegrees = ((seconds / 60) * 360) + 90; secondHand.style.transform = `rotate(${secondsDegrees}deg)`; const mins = now.getMinutes(); const minsDegrees = ((mins / 60) * 360) + ((seconds/60)*6) + 90; minsHand.style.transform = `rotate(${minsDegrees}deg)`; const hour = now.getHours(); // change seconds to hours on the line below const hourDegrees = ((seconds / 12) * 360) + ((mins/60)*30) + 90; hourHand.style.transform = `rotate(${hourDegrees}deg)`; } setInterval(setDate, 1000); setDate();
const secondHand = document.querySelector('.second-hand');
const minsHand = document.querySelector('.min-hand');
const hourHand = document.querySelector('.hour-hand');
function setDate() {
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = ((seconds / 60) * 360) + 90;
secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
const mins = now.getMinutes();
const minsDegrees = ((mins / 60) * 360) + ((seconds/60)*6) + 90;
minsHand.style.transform = `rotate(${minsDegrees}deg)`;
const hour = now.getHours();
// change seconds to hours on the line below
const hourDegrees = ((seconds / 12) * 360) + ((mins/60)*30) + 90;
hourHand.style.transform = `rotate(${hourDegrees}deg)`;
}
setInterval(setDate, 1000);
setDate();

自動載入擴充套件

在你的專案的根部,建立一個 .devcontainer 資料夾,並在該資料夾記憶體儲一個 devcontainer.json 檔案。你可以通過建立 devcontainer.json 預先定義特定的擴充套件,以便在有人開啟 Codespace 的時候載入。在 devcontainer.json 裡面,你可以提供VS Code擴充套件ID的值。下面是我的 devcontainer.json 的一個例子:

devcontainer.json

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-vsliveshare.vsliveshare",
"blackgirlbytes.deploy-to-github-pages",
"tinkertrain.theme-panda",
"codespaces-contrib.codeswing",
"vsls-contrib.codetour",
"streetsidesoftware.code-spell-checker"
]
}
{ "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "ms-vsliveshare.vsliveshare", "blackgirlbytes.deploy-to-github-pages", "tinkertrain.theme-panda", "codespaces-contrib.codeswing", "vsls-contrib.codetour", "streetsidesoftware.code-spell-checker" ] }
{
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-vsliveshare.vsliveshare",
"blackgirlbytes.deploy-to-github-pages",
"tinkertrain.theme-panda",
"codespaces-contrib.codeswing",
"vsls-contrib.codetour",
"streetsidesoftware.code-spell-checker"
]
}

新增擴充套件到 devcontainer.json 的另一種方法

你可以點選 add to devcontainer.json 將它們新增到你的 devcontainer.json 中,而不是搜尋每個VS Code擴充套件的ID,如下圖:

新增擴充套件到 devcontainer.json

設定CodeSwing

由於CodeSwing已經安裝在你的IDE中,你可以通過建立一個CodeSwing清單來定製CodeSwing體驗。我使用清單來定製我的佈局。我喜歡HTML、CSS和JavaScript的大塊內容堆積在編輯器的右側,所以我在專案的根部建立了一個 codeswing.json,內容如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"scripts": [],
"styles": [],
"layout": "splitRight"
}
{ "scripts": [], "styles": [], "layout": "splitRight" }
{
"scripts": [],
"styles": [],
"layout": "splitRight"
}

沒有看到任何改變?

如果你在你的Codespace中沒有看到任何變化,你可能需要重建你的容器,或者關閉你當前的Codespace,並啟動一個新的Codespace來重新載入你的環境。

要重建你的環境,訪問你的命令面板並選擇 Codespaces: Rebuild Container。如果你不確定如何訪問它,請檢視指南

命令面板

建立Code Tour

通過CodeTour擴充套件的一點額外幫助,引導你的研討會與會者完成研討會。在我的案例中,我在我的程式碼中留下了兩個錯誤,我希望研討會的與會者能夠解決:

  • 我在時鐘上應該是數字6的地方放了一個問號
  • 背景顏色很好,但我提示學生使用他們自己選擇的調色盤
  • 我讓時針和分針走得一樣快

為了提示學生修正錯誤,我用CodeTour在每個檔案的特定行上新增了指導性資訊。在我專案的根部,我建立了一個名為 main.tour 的檔案。在我的 main.tour 檔案中,我新增了以下指導資訊:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"$schema": "https://aka.ms/codetour-schema",
"title": "Fix The Broken Clock",
"steps": [
{
"file": "index.html",
"line": 2,
"description": "Hey! 👋 Welcome to the Fix The Broken Clock workshop. Something is very wrong with this clock, and we need your help to fix it. Use this tour to guide you through the app, and learn how to interact with its live coding environment. Try changing their text content and watch it take effect immediately!\n\nClick the `Next` link below to keep learning 👇"
},
{
"file": "index.html",
"line": 22,
"description": "Our clock has a question mark instead of the number 6. Update the `&lt;h1 id='six'>?&lt;/h1>` to render the number 6!"
},
{
"file": "style.css",
"line": 13,
"description": "Great job at fixing the numbers over the clock. Check out background colors for the clock. Hover over the `&lt;hex>` color to choose the background color of your choice."
},
{
"file": "script.js",
"line": 14,
"description": "The hour hand is moving just as fast as the second hand. Let’s fix this by changing the word `seconds` on line 14 to `hours`."
},
{
"file": "script.js",
"line": 18,
"description": "Mission complete! Thank you for completing this workshop."
}
]
}
{ "$schema": "https://aka.ms/codetour-schema", "title": "Fix The Broken Clock", "steps": [ { "file": "index.html", "line": 2, "description": "Hey! 👋 Welcome to the Fix The Broken Clock workshop. Something is very wrong with this clock, and we need your help to fix it. Use this tour to guide you through the app, and learn how to interact with its live coding environment. Try changing their text content and watch it take effect immediately!\n\nClick the `Next` link below to keep learning 👇" }, { "file": "index.html", "line": 22, "description": "Our clock has a question mark instead of the number 6. Update the `&lt;h1 id='six'>?&lt;/h1>` to render the number 6!" }, { "file": "style.css", "line": 13, "description": "Great job at fixing the numbers over the clock. Check out background colors for the clock. Hover over the `&lt;hex>` color to choose the background color of your choice." }, { "file": "script.js", "line": 14, "description": "The hour hand is moving just as fast as the second hand. Let’s fix this by changing the word `seconds` on line 14 to `hours`." }, { "file": "script.js", "line": 18, "description": "Mission complete! Thank you for completing this workshop." } ] }
{
"$schema": "https://aka.ms/codetour-schema",
"title": "Fix The Broken Clock",
"steps": [
{
"file": "index.html",
"line": 2,
"description": "Hey! 👋 Welcome to the Fix The Broken Clock workshop. Something is very wrong with this clock, and we need your help to fix it. Use this tour to guide you through the app, and learn how to interact with its live coding environment. Try changing their text content and watch it take effect immediately!\n\nClick the `Next` link below to keep learning 👇"
},
{
"file": "index.html",
"line": 22,
"description": "Our clock has a question mark instead of the number 6. Update the `&lt;h1 id='six'>?&lt;/h1>` to render the number 6!"
},
{
"file": "style.css",
"line": 13,
"description": "Great job at fixing the numbers over the clock. Check out background colors for the clock. Hover over the `&lt;hex>` color to choose the background color of your choice."
},
{
"file": "script.js",
"line": 14,
"description": "The hour hand is moving just as fast as the second hand. Let’s fix this by changing the word `seconds` on line 14 to `hours`."
},
{
"file": "script.js",
"line": 18,
"description": "Mission complete! Thank you for completing this workshop."
}
]
}

這個code tour看起來應該類似於下面的截圖:

code tour截圖-01

code tour截圖-02

code tour截圖-03

code tour截圖-04

code tour截圖-05

提交和推送更改

即使是最有經驗的工程師也會為版本控制而掙扎,所以我並不期望初級開發者在研討會上寫git命令。幸運的是,Codespaces和VS Code有一個原始碼控制的使用者介面。我使用這個使用者介面來幫助與會者階段性地提交和推送他們的修改。

提交和推送更改

上線!

有兩件事我認識到新的開發者喜歡:

  1. 當他們修改一個本地託管的網站時,他們會立即得到滿足感
  2. 向朋友和家人展示自己的第一個網站

我鼓勵研討會的參與者在GitHub Pages上部署他們的網站,這樣他們就可以向朋友和家人炫耀他們的第一個網站。對於初級開發者來說,部署到GitHub Pages上可能會感覺比較困難,因為這需要對GitHub Actions和GitHub UI進行修補。相反,我讓他們使用一個叫做Deploy to GitHub Pages的擴充套件,它允許參與者不離開他們的IDE就能部署網站。這篇簡短的博文概述瞭如何使用這個擴充套件。這個演示的真實網站在這裡

Deploy to GitHub Pages擴充套件

讓研討會在VS Code中可用

如果有人喜歡使用VS Code而不是Codespaces來關注你的工作,你仍然可以定義為該專案安裝的推薦擴充套件。在你的專案根部建立一個 .vscode文 件夾,裡面有一個 extensions.json 檔案。你可以使用我的 extensions.json 檔案的內容作為參考。

extensions.json

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-vsliveshare.vsliveshare",
"blackgirlbytes.deploy-to-github-pages",
"tinkertrain.theme-panda",
"codespaces-contrib.codeswing",
"vsls-contrib.codetour",
"streetsidesoftware.code-spell-checker"
],
}
{ "recommendations": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "ms-vsliveshare.vsliveshare", "blackgirlbytes.deploy-to-github-pages", "tinkertrain.theme-panda", "codespaces-contrib.codeswing", "vsls-contrib.codetour", "streetsidesoftware.code-spell-checker" ], }
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-vsliveshare.vsliveshare",
"blackgirlbytes.deploy-to-github-pages",
"tinkertrain.theme-panda",
"codespaces-contrib.codeswing",
"vsls-contrib.codetour",
"streetsidesoftware.code-spell-checker"
],
}

這個方法適用於任何前端框架!

雖然我在例子中使用了HTML、CSS和JavaScript,但你可以對任何前端框架使用這種方法。我計劃在以後的博文中解釋如何使用Codespaces來執行其他技術的研討會,但現在,我希望這是一個很好的起點!

這是什麼?

這是一個用於向人們介紹HTML、CSS和JavaScript的研討會。該程式特意有以下錯誤:

  • 在數字6應該呈現的地方,時鐘上有一個問號
  • 時針走得太快了!

在這個工作坊中,參與者要挑戰的是如何解決和修復這些問題。下面的擴充套件程式為與會者創造了一個自我指導的體驗:

  • CodeSwing
  • CodeTour

這是為展示在Codespaces中執行研討會的價值而製作的。

使用說明

任何人都可以在協議下使用它或對它進行調整。

資源和連結

演示:https://blackgirlbytes.github.io/clock-codespace-workshop/

原始碼:View on GitHub

附註

不要把Codespaces和GitHub.dev混為一談,後者是一個輕量級的瀏覽器編輯器,如果你在任何倉庫中按下“.”鍵就會顯示出來。許多人告訴我他們喜歡Codespaces,並給我看GitHub.dev。雖然我喜歡GitHub.dev,因為它使我更容易快速編輯和格式化檔案,但它與Codespaces不同。Codespaces是GitHub.dev的類固醇。

關於Codespaces,你還想了解什麼?請在下面評論,這樣我就可以建立更多的內容來教育你如何針對你的使用情況優化Codespace!(via Rizèl Scarlett

評論留言