|
| 1 | +Title: Building A VS Code Extension Without Installing Node By Docker Magic |
| 2 | +Date: 2021-02-26 16:14 |
| 3 | +Modified: 2021-02-26 16:14 |
| 4 | +Category: Posts |
| 5 | +tags: vscode,nodejs,docker |
| 6 | +cover: static/imgs/default_page_imagev2.jpg |
| 7 | +summary: How to build a VS Code extension without installing Node.js locally. |
| 8 | + |
| 9 | +I recently wanted to work through the |
| 10 | +[tutorial for building a VS Code extension](https://code.visualstudio.com/api/get-started/your-first-extension), |
| 11 | + but the first step is to install [Node.js](https://nodejs.org/en/) |
| 12 | +locally, which, well, I don't want to do. Sorry to the Node peeps out there, |
| 13 | +but I don't want to touch the (large and rather complex) Node ecosystem just |
| 14 | +to try out building a VS Code extension. So I then thought, "Hey, you can |
| 15 | +install Node on a Linux box, so why can't I just do it inside a Docker container?" |
| 16 | + |
| 17 | +And of course, you can, and not only that, but with the magic that is the |
| 18 | +[VS Code Remote Containers extension](https://code.visualstudio.com/docs/remote/containers) |
| 19 | +you can even have VS Code work as if it's all on your local host machine. Let's |
| 20 | +give this a try. |
| 21 | + |
| 22 | +## Install The Pre-Requisites |
| 23 | + |
| 24 | +First step: install the |
| 25 | +[Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) |
| 26 | +extension pack from Microsoft. This will allow you to treat a running container, ssh connection |
| 27 | +to a remote machine, or Linux environment via WSL (assuming you are a Windows person) |
| 28 | +as though it's a local folder. If you've never played with this before, it really is |
| 29 | +worth checking out as it's amazing. |
| 30 | + |
| 31 | +I'm going to assume you also have [Docker](https://www.docker.com/) installed. If not, |
| 32 | +follow the instructions on their site, or any one of the 59 million or so |
| 33 | +[tutorials online](https://www.google.com/search?q=how+to+install+docker). |
| 34 | + |
| 35 | +## Create the Dockerfile |
| 36 | + |
| 37 | +Ok, now let's create a `Dockerfile` that has what we need. The VS Code tutorial mentions |
| 38 | +you need the following: |
| 39 | + |
| 40 | +* Node.js |
| 41 | +* Git |
| 42 | +* Yeoman |
| 43 | +* The VS Code Extension Generator |
| 44 | + |
| 45 | +Ok, all those things boil down to some basic terminal commands, but as a simple starting |
| 46 | +point, let's use the [official Node.js Docker image](https://hub.docker.com/_/node) to |
| 47 | +get Node.js. To do this, make `node:10-alpine` the base image, and then install those |
| 48 | +dependencies: |
| 49 | + |
| 50 | +```dockerfile |
| 51 | +FROM node:10-alpine |
| 52 | + |
| 53 | +RUN apk add --update git bash |
| 54 | +RUN npm install -g yo generator-code |
| 55 | + |
| 56 | +USER node |
| 57 | + |
| 58 | +ENTRYPOINT /bin/bash |
| 59 | + |
| 60 | +WORKDIR /home/node |
| 61 | +``` |
| 62 | + |
| 63 | +Breaking this down a bit: |
| 64 | + |
| 65 | +* the `FROM` line says the image to use as a base image is the `node:10-alpine` |
| 66 | + image from Dockerhub. This gives you npm & whatnot already installed. |
| 67 | +* the `apk add` line installs Git and Bash (alpine doesn't have Bash installed |
| 68 | + by default) |
| 69 | +* the `npm install -g` line installs Yeoman and the VS Code Extension Generator |
| 70 | +* the `USER` line creates a user called `node`, which you need as otherwise `yo` |
| 71 | + fails when you run it in the container due to permission issues (doesn't seem |
| 72 | + to like running as root) |
| 73 | +* the `ENTRYPOINT` says when a container is started from this image, start off |
| 74 | + by running `/bin/bash` |
| 75 | +* the `WORKDIR` says when a container is started from this image, start in the |
| 76 | + `/home/node` directory |
| 77 | + |
| 78 | +Save this file as `Dockerfile`. Note that I used `node:10-alpine` (so a 10.x |
| 79 | +version of Node), feel free to replace with a newer version if you want (I |
| 80 | +have no idea what version the VS Code Extension Generator wants). |
| 81 | + |
| 82 | +## Build The Docker Image |
| 83 | + |
| 84 | +Now you want to build the Docker image, run this command in the same directory as the `Dockerfile`: |
| 85 | + |
| 86 | +```shell |
| 87 | +docker build -t vscodeenv:latest . |
| 88 | +``` |
| 89 | + |
| 90 | +The `vscodeenv` name is totally arbitrary, feel free to name it whatever you |
| 91 | +want, but that's the name I'll use for this blog post. You'll see a bunch of |
| 92 | +output, and after it's done, you should be able to see the built image when you |
| 93 | +do a `docker images`: |
| 94 | + |
| 95 | +```shell |
| 96 | +$ docker images |
| 97 | +REPOSITORY TAG IMAGE ID CREATED SIZE |
| 98 | +vscodeenv latest 37d9e66fffbc 48 minutes ago 186MB |
| 99 | +``` |
| 100 | + |
| 101 | +## Run the Image |
| 102 | + |
| 103 | +Now we have a built Docker image with all the tooling you need for the tutorial. |
| 104 | +Next step is to spin up a container from this image. I'm sure if you get into |
| 105 | +the VS Code `devcontainer.json` stuff you could do this from within VS Code, but |
| 106 | +I just do it from the terminal: |
| 107 | + |
| 108 | +```shell |
| 109 | +$ docker run -it --name vscodeenv -v /Users/aparkin/dockerpath/:/home/node --rm vscodeenv:latest |
| 110 | +bash-5.0$ |
| 111 | +``` |
| 112 | + |
| 113 | +Replace `/Users/aparkin/dockerpath/` with the full path to a directory where you want to |
| 114 | +put your extensions code (it's perfectly fine to be the same directory where you put the |
| 115 | +`Dockerfile`). |
| 116 | + |
| 117 | +Note that this just drops you into a bash shell inside the running container. |
| 118 | +Leave this window open, so long as this is open your container will be running. |
| 119 | +Once you type "exit" here, the container will be terminated (which we don't |
| 120 | +want to do until we're done working on our little extension). |
| 121 | + |
| 122 | +To break the `docker run` command down a bit, the key bits: |
| 123 | + |
| 124 | +* `-it` means run in interactive mode (ie where you can type in commands) |
| 125 | +* `--name vscodeenv` gives the container the name `vscodeenv` (again, this is |
| 126 | + arbitrary) |
| 127 | +* `-v .....` tells it to mount the path you specified on your local host |
| 128 | + filesystem into `/home/node` in the running container (so any files in the |
| 129 | + path you specify will show up in the container inside `/home/node`) |
| 130 | +* `--rm` tells Docker to delete the container once you exit |
| 131 | + |
| 132 | +## Create The Skeleton Extension |
| 133 | + |
| 134 | +The VS Code tutorial indicates after installing everything, you should run the generator. |
| 135 | +Do this in the running docker container with the `yo code` command: |
| 136 | + |
| 137 | +```shell |
| 138 | +bash-5.0$ yo code |
| 139 | + |
| 140 | + _-----_ ╭──────────────────────────╮ |
| 141 | + | | │ Welcome to the Visual │ |
| 142 | + |--(o)--| │ Studio Code Extension │ |
| 143 | + `---------´ │ generator! │ |
| 144 | + ( _´U`_ ) ╰──────────────────────────╯ |
| 145 | + /___A___\ / |
| 146 | + | ~ | |
| 147 | + __'.___.'__ |
| 148 | + ´ ` |° ´ Y ` |
| 149 | +
|
| 150 | +? What type of extension do you want to create? (Use arrow keys) |
| 151 | +❯ New Extension (TypeScript) |
| 152 | + New Extension (JavaScript) |
| 153 | + New Color Theme |
| 154 | + New Language Support |
| 155 | + New Code Snippets |
| 156 | + New Keymap |
| 157 | + New Extension Pack |
| 158 | + New Language Pack (Localization) |
| 159 | +``` |
| 160 | +
|
| 161 | +This generator walks you through creating your first extension. Following VS Code's |
| 162 | +tutorial I picked: |
| 163 | +
|
| 164 | +* New Extension (TypeScript) |
| 165 | +* Name of my extension: "AdamsExtension" |
| 166 | +* Identifier of my extension: "adamsextension" (the default) |
| 167 | +* Description I entered random gibberish |
| 168 | +* Initialize a Git repo: yes |
| 169 | +* Bundle with Webpack: no |
| 170 | +* Package manager: npm |
| 171 | +
|
| 172 | +After that, it goes ahead and installs all the various npm dependencies -- *all within |
| 173 | +the docker container*. |
| 174 | +
|
| 175 | +## Attach To the Container |
| 176 | +
|
| 177 | +Now in VS Code open the command palette and search for |
| 178 | +`Remote-Containers: Attach to Running Container...`. Pick this, and then your running |
| 179 | +container called `vscodeenv` should appear in the list: |
| 180 | +
|
| 181 | + |
| 182 | +
|
| 183 | +Pick it, and VS Code will open a new Window "attached" to the running container. For |
| 184 | +more details, consult |
| 185 | +[the official docs](https://code.visualstudio.com/docs/remote/attach-container). |
| 186 | +
|
| 187 | +Now click on "Open Folder" and navigate to your `adamsextension` (or whatever you called |
| 188 | +your extension) folder and click OK. You then get a VS Code window "attached" to |
| 189 | +the running docker container, with your test extension open and ready to play with. |
| 190 | +Here's a screenshot to give an idea: |
| 191 | +
|
| 192 | + |
| 193 | +
|
| 194 | +Now you can hit `F5` and VS Code will open up a new Extension Development Host window with |
| 195 | +your test extension loaded. In that window you should be able to search for the |
| 196 | +"Hello World" command in the command palette and run the command. |
| 197 | +
|
| 198 | +## Profit |
| 199 | +
|
| 200 | +And that's it, no Node.js or any other tooling installed to your local machine other |
| 201 | +than VS Code & Docker. Once you're done playing around, exit out of the running Docker |
| 202 | +container (enter "exit" in the bash prompt) and the container will be terminated, and |
| 203 | +all the files you created will remain in the path you mounted into the container. |
| 204 | +
|
| 205 | +If you want to later pick up where you left off, just run the same `docker run` command |
| 206 | +as before, re-attach to the container, and re-open the folder. |
0 commit comments