visit
I created a tool for people that teach code, called code-workshop-kit. It makes remote workshops interactive and allows for experiences similar to those in a classroom, and better.
In this blog I will explain the problems of remote code workshops, why I created and how you can use it.
Instead of standing in front of a classroom in a real physical location, we often find ourselves educating in front of a digital Teams or Zoom room.This transition has been happening for many years, gradually. Then, COVID-19 hit us, meaning that more and more people are now permanently working from home and classrooms with a bunch of people in a small room are a no-go in most places.Even though I am optimistic about the future of this pandemic, it still seems likely that it has sped up this transition of workshops and education. I foresee that even most conferences will embrace digital means of attending from now on, which would include their workshops being held remotely as well.
Next to my daily work as a web developer, I am also an educator, giving workshops and full-day training usually twice a month or so. My style is very interactive, hands-on, and exercise-driven. This requires input from my participants. If you happen to be like me in this regard, you will recognize the following problems when giving such training online.
The final contender is perhaps one you already thought of: , in my case the , or as I like to call it, the “Google Docs of coding”. This puts collaborative code sharing and writing, in what also happens to be my favorite code editor of all time. It is open-source, has an Extensibility API to write or extend upon VS Code extensions and a bunch of other features, most notably Shared Servers.
So with this, my first requirement was met, kudos to the Live Share team at Microsoft for creating such an incredible product! Shared servers inspired me for the second requirement.With shared servers, any participant that is connected to your session has an SSH tunnel to you over the port you share in shared servers. This means that they can use
localhost:<port>
on their machines and access a shared API or web server.However, there are remaining challenges:This server is essentially an abstraction on top of , making it easy to write plugins and middleware for serving files over HTTP, and it has a really good NodeJS API for extending and building on top of it to make your own opinionated dev server. This is exactly what I needed to overcome the remaining challenges.
What the code-workshop-kit server does on top of @web/dev-server, is ensure that when serving the main index.html, an app shell component is inserted which, among other things, has:mkdir cwk-test && cd cwk-test && npm init -y && npm i code-workshop-kit
Create a file called
cwk.config.js
:export default {
appTitle: 'Welcome to Joren\'s Frontend Workshop',
participants: ["Joren", "Bob", "Alice"],
};
Now let’s create some starter files for our participants. Create a folder
template
.In this folder, create
index.html
:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>Hello <%= participantName %></h1>
<script src="./index.js"></script>
</body>
</html>
Let’s also create a starter JavaScript file,
index.js
:console.log("Hello, <%= participantName %>");
Note the specialScaffold these starter files for all participants:tags in which we can place variables that will be filled in by the scaffolder. Read more about that in the<%= %>
npx cwk scaffold
npx cwk run
Now check out the browser on
localhost:8000
. Feel free to invite some others by creating a session in VS Code using the Live Share extension.If you select a name, you should then see the participant overview, and every participant’s
index.html
rendered through an iframe. You can click the view buttons to view only one specific participant's output.Very often, in the land of frontend, the main entrypoint is a Javascript file:
index.js
. We then export some sort of template which gets rendered to DOM. This is quite common for Single Page Applications. The benefit of this approach in code-workshop-kit
is that we can use a technique called Hot Module Replacement to reload this exported Javascript module whenever files have changed, without needing a page reset. Furthermore, the overview page can load the module and no iframes are needed, meaning dependencies can be shared easily.Let’s change our setup to use this method.In the
cwk.config.js
, edit it to:export default {
appTitle: 'Welcome to Joren\'s Frontend Workshop',
participants: ["Joren", "Bob", "Alice"],
targetOptions: {
mode: 'module'
}
};
This will assume an
index.js
file in the root folder of every participant, which must contain a default export which is either an HTML string value, a DOM Node/Element (document.createElement('div')
for example) or a lit-html TemplateResult
. I’m happy to accept feature requests or contributions for other templating methods, as long as they are not locked behind a compilation step. You can always pre-render with whatever tool or engine you like, and pass the DOM node.Delete your
index.html
inside the template
folder. Edit the index.js
:console.log("Hello, <%= participantName %>");
export default `<h1>Hello <%= participantName %></h1>`;
Delete your
participants
folder entirely, and just re-run:npx cwk scaffold
npx cwk run
You should see the same overview. But this time, things are rendered through modules instead inside iframes. Hot Module Replacement also works now. You can see this by going into for example Bob’s
index.js
, and change:export default `<h1>Hello Bob</h1>`;
export default `<h1>Hello Bob!!!!!</h1>`;
If you want more information, see
Change your
cwk.config.js
:export default {
appTitle: 'Welcome to Joren\'s Backend Workshop',
participants: ["Joren", "Bob", "Alice"],
target: 'terminal',
targetOptions: {
cmd: 'node index.js'
}
};
Change the
index.js
inside the template
folder to create a tiny terminal input/output program:const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question("Hello <%= participantName %>! Where do you live? ", (country) => {
console.log(`You are a citizen of ${country}`);
rl.close();
});
rl.on("close", () => {
process.exit(0);
});
npx cwk scaffold -f
npx cwk run
Try saving one of the files of the participant, or click one of the rerun buttons. This will make CWK run
node index.js
inside that participant's folder, and the output is aggregated to the participant's view. You will see a green circle pop up notifying you that a script is running for that participant, and you can now use the terminal input field to and press enter to send. This will send your text to the process' input.At this time of writing,
code-workshop-kit
is v1 (v1.0.4 to be precise). That means the API is stable. Me and two others have personally alpha tested with this a fair bit, both for frontend (usually web component related workshops) as well as Java backend workshops. The code is open-source, which I think is fair given that I build on top of existing open-source projects. I also want to reach as many teachers as possible and I want to carry my weight during these difficult COVID-19 times.This project is not finished. I will continue working on it for the foreseeable future, as it directly impacts my work as a trainer.
Microsoft’s VS Code Live Share extension team were kind enough to reach out to me and we had a very insightful meeting, so I have many ideas on how to further improve (thanks Jonathan Carter and Filisha Shah) .
Also published at