Using VSCode Web Server Variant

Last tested version is 1.75.1, may become invalid in a future version.

Why & Why Not?

Advantages

Disadvantages

Guide

First, the download link is:

https://update.code.visualstudio.com/latest/{target}/stable

{target} = server-win32-x64-web, server-linux-x64-web or others.

Extract the package, then execute ./bin/code-server(.bat).

To change data directory, use custom token and port, ./run.sh:

export VSCODE_AGENT_FOLDER=./data
./bin/code-server --accept-server-license-terms --port=8109 --connection-token=mytoken

But a lot of inconvenience here, such as build tasks always fail when offline. So there is a patch ./misc/patch.js:

"use strict"; // Last Tested Version: 1.76.0
const patch = (path, replaceList) => {
  const fs = require("fs");
  const filePath = require("path").join(__dirname, path);
  const bakPath = filePath + `.bak`;
  if (!fs.existsSync(bakPath)) fs.renameSync(filePath, bakPath);
  let content = fs.readFileSync(bakPath).toString();
  for (const [search, value] of replaceList) {
    const fn = search instanceof RegExp ? "replace" : "replaceAll";
    content = content[fn](search, value);
  }
  fs.writeFileSync(filePath, content);
  console.log("patched: " + path);
};
patch("./out/vs/workbench/workbench.web.main.js", [
  // Replace entry url with local server to allow offline work (for webview)
  // Source: src/vs/workbench/services/environment/browser/environmentService.ts
  [`"https://{{uuid}}.vscode-cdn.net/{{quality}}/{{commit}}`, `baseUrl+"`],
]);
patch("./out/vs/workbench/contrib/webview/browser/pre/index.html", [
  // Modify CSP (for webview)
  // Source: src/vs/workbench/contrib/webview/browser/pre/index.html
  [/\'sha256.+?\'/, "'unsafe-inline'"],
  // Bypass hostname vertify (for webview)
  // Source: src/vs/workbench/contrib/webview/browser/pre/index.html
  [/\.padStart\(52.+?\)/, "&&location.hostname"],
]);
// strip ./node_modules/@vscode/ripgrep/bin/rg
// strip ./node_modules/node-vsce-sign/bin/vsce-sign
// rm -rf ~/.vscode-server/extensions/redhat.java-*/jre/
// rm -rf ~/.vscode-server/extensions/ms-python.vscode-pylance-*/dist/native/onnxruntime/
// rm -rf ~/.vscode-server/extensions/ms-python.python-*/pythonFiles/lib/python/debugpy/_vendored/pydevd/pydevd_attach_to_process/

Because node-spdlog and node-pty were both use NAN, so cross NodeJS version is hard to do (especially when you want pointer compression enabled). You can use a faked spdlog and daniel-brenot's node-pty fork.

{
  "name": "spdlog",
  "version": "0.13.7",
  "description": "Faked Node bindings for spdlog",
  "main": "index.js",
  "license": "MIT"
}
const p = () => {}; // const p = console.log;
class Logger {
  constructor(loggerType, name, filename, filesize, filecount) {}
  trace = p;
  debug = p;
  info = p;
  warn = p;
  error = p;
  critical = p;
  getLevel = () => 2;
  setLevel(level) {}
  setPattern(pattern) {}
  clearFormatters() {}
  flush() {}
  drop() {}
}
const c = (...args) => new Promise((r) => r(new Logger(...args)));
exports.createRotatingLogger = (...args) => c("rotating", ...args);
exports.createAsyncRotatingLogger = (...args) => c("rotating_async", ...args);
exports.setLevel = (level) => {};
exports.setFlushOn = (level) => {};
exports.version = 11100;