惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
博客园_首页
博客园 - 聂微东
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
The Cloudflare Blog
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
D
Docker
人人都是产品经理
人人都是产品经理
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
Microsoft Azure Blog
Microsoft Azure Blog
Recent Announcements
Recent Announcements
Apple Machine Learning Research
Apple Machine Learning Research
阮一峰的网络日志
阮一峰的网络日志
B
Blog RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
Jina AI
Jina AI
博客园 - Franky
D
DataBreaches.Net

kkocdko's blog

Tasker 永久试用修改思路 - kkocdko's blog 极限压缩文档扫描件 - kkocdko's blog Bypass the Blank Chars Detection crknob - Chrome portable patch 我如何将博客首页体积降至 3 KB - kkocdko's blog 如何极限优化压缩文件体积 - kkocdko's blog EmEditor 精简版 - kkocdko's blog Backup Data from VSCode Web 优雅地游玩 Minecraft - kkocdko's blog 让程序以管理员权限运行的 PE 清单 - kkocdko's blog 注销 ZEIT 账号之后遇到的坑 - kkocdko's blog 本博客的协议已更改为 CC0 - kkocdko's blog mobp - 使 MSOffice 后台常驻 在安装 VS 生成工具时规避 .NET 安装错误 各种格式的占位空文件 - kkocdko's blog 优雅地游玩 Flash 游戏 - kkocdko's blog WPS 2016 极限精简版 - kkocdko's blog Convert Const to Let by Terser 规避 Visual Studio 许可证过期的 Bug 方便地使用 iPod - kkocdko's blog 用 UserJS 注入 UserCSS - kkocdko's blog 注册表修改文件关联(默认程序) - kkocdko's blog 周期精准的太阳系模型 - kkocdko's blog 关闭屏幕的 WinAPI - kkocdko's blog 重置 Windows 图标缓存 - kkocdko's blog AIDA64 极限精简单文件版 - kkocdko's blog 几何画板单文件精简版 - kkocdko's blog 世界之窗浏览器单文件版 - kkocdko's blog 在 MBR + Legacy 下用 Bootmgr 引导 Ubuntu 简洁的 Markdown 预览工具 - kkocdko's blog
Using VSCode Web Server Variant
2026-04-11 · via kkocdko's blog

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

Pros

  • As a tab on browser, more convenient. Haven't redundant services and GPU processs, less overhead.

  • Bypass Electron's IME issues on Linux Wayland (Electron 33 alpha fixed this).

  • Official extension market, not coder/code-server's market.

Cons

  • Not officially supported. See this issue.

  • Key shortcut conflicts, like Ctrl + W will close the browser tab (PWA mode fixes this).

Guide

Download and extract https://update.code.visualstudio.com/latest/server-linux-x64-web/stable (or server-win32-x64-web and others).

Then use bin/code-server(.bat) or write a custom run.sh:

#!/bin/sh
cd $(dirname $0)
UV_USE_IO_URING=0 exec node out/server-main.js --accept-server-license-terms --host 127.0.0.1 --port 8109 --connection-token=hello

And here's a patch.js to workaround some issues like offline webview, see comments for details:

import fs from "node:fs";
if (!fs.existsSync("out/server-cli.js")) throw new Error("working dir wrong");
const patch = (filePath, replaceList) => {
  const bakPath = filePath + `.bak`;
  if (!fs.existsSync(bakPath)) fs.renameSync(filePath, bakPath);
  let content = fs.readFileSync(bakPath).toString();
  for (const [from, to] of replaceList) {
    const testFn = from instanceof RegExp ? "match" : "includes";
    const replaceFn = from instanceof RegExp ? "replace" : "replaceAll";
    if (!content[testFn](from))
      console.error("patch entry not found", { from, to });
    content = content[replaceFn](from, to);
  }
  fs.writeFileSync(filePath, content);
};
patch("out/vs/code/browser/workbench/workbench.js", [
  // > src/vs/workbench/services/environment/browser/environmentService.ts
  [`"https://{{uuid}}.vscode-cdn.net/{{quality}}/{{commit}}`, `baseUrl+"`], // Replace entry url with local server to allow offline work (for webview)
  // > src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts
  [/(?<="extensions.autoUpdate":\{.+?,default:).+?,/, "false,"], // Set "extensions.autoUpdate" default = false. Because the "User Settings" is store in browser (indexedDB), so if you open a page in a fresh incognito window, the update progress will start unexpectedly
]);
patch("out/vs/workbench/contrib/webview/browser/pre/index.html", [
  // > src/vs/workbench/contrib/webview/browser/pre/index.html
  [/\'sha256.+?\'/, "'unsafe-inline'"], // Modify CSP (for webview)
  [/\.padStart\(52.+?\)/, "&&location.hostname"], // Bypass hostname vertify (for webview)
]);
const spdlogDir = "node_modules/@vscode/spdlog";
fs.rmSync(spdlogDir + "/build", { recursive: true, force: true });
fs.writeFileSync(spdlogDir + "/package.json", '{"version":"99.0.0"}\n'); // the overwrite here can deal with the type:"module" in future
const spdlogIndexJs = () => {
  const fs = require("node:fs");
  const path = require("node:path");
  function Logger(name, filepath) {
    fs.mkdirSync(path.dirname(filepath), { recursive: true });
    const fd = fs.openSync(filepath, "a");
    const write = (v) =>
      fs.write(fd, "[" + Date.now() + "] " + v.trimEnd() + "\n", () => {});
    this.debug = this.info = this.warn = write;
    this.error = this.critical = this.trace = write;
    this.getLevel = () => 2;
    this.setLevel = this.setPattern = this.clearFormatters = () => {};
    this.flush = () => fs.fsync(fd, () => {});
    this.drop = () => fs.close(fd);
  }
  const create = (name, filepath, maxSize, maxFiles) =>
    new Promise((resolve) => resolve(new Logger(name, filepath)));
  exports.createAsyncRotatingLogger = exports.createRotatingLogger = create;
  exports.setLevel = exports.setFlushOn = () => {};
  exports.version = 11100;
};
fs.writeFileSync(spdlogDir + "/index.js", `(${spdlogIndexJs.toString()})()`);
// node patch.js; rm -rf extensions/markdown-language-features extensions/mermaid-chat-features node_modules/@xterm/addon-ligatures node_modules/@vscode/vsce-sign node_modules/vsda node_modules/vscode-regexp-languagedetection node_modules/@vscode/vscode-languagedetection ~/.vscode-server/data/Cached* ~/.vscode-server/extensions/redhat.java-*/jre/ ~/.vscode-server/extensions/ms-python.python-*/pythonFiles/lib/python/debugpy/_vendored/pydevd/pydevd_attach_to_process/ ~/.vscode-server/extensions/ms-python.python-*/out/client/extension.js.map*

// todo:
// ./node_modules/0_vscode-oniguruma
// ./node_modules/0_vscode-textmate
// ./node_modules/@vscode/tree-sitter-wasm
// ./out/vs/workbench/workbench.web.main.internal.js