Skip to content

Commit faed813

Browse files
committed
Refactor static routing, template vars.
1 parent 0e8d25a commit faed813

27 files changed

+78
-126
lines changed

ci/build/build-release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ bundle_code_server() {
4040
mkdir -p "$RELEASE_PATH/src/browser"
4141
rsync src/browser/media/ "$RELEASE_PATH/src/browser/media"
4242
mkdir -p "$RELEASE_PATH/src/browser/pages"
43-
rsync src/browser/pages/*.handlebars "$RELEASE_PATH/src/browser/pages"
43+
rsync src/browser/views/*.handlebars "$RELEASE_PATH/src/browser/views"
4444
rsync src/browser/robots.txt "$RELEASE_PATH/src/browser"
4545

4646
# Adds the commit to package.json

ci/dev/watch.ts

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -173,21 +173,13 @@ class Watcher {
173173
}
174174

175175
private createBundler(out = "dist"): Bundler {
176-
return new Bundler(
177-
[
178-
path.join(this.rootPath, "src/browser/register.ts"),
179-
path.join(this.rootPath, "src/browser/serviceWorker.ts"),
180-
path.join(this.rootPath, "src/browser/pages/login.ts"),
181-
path.join(this.rootPath, "src/browser/pages/vscode.ts"),
182-
],
183-
{
184-
outDir: path.join(this.rootPath, out),
185-
cacheDir: path.join(this.rootPath, ".cache"),
186-
minify: !!process.env.MINIFY,
187-
logLevel: 1,
188-
publicUrl: ".",
189-
},
190-
)
176+
return new Bundler([path.join(this.rootPath, "src/browser/**/*.ts")], {
177+
outDir: path.join(this.rootPath, out),
178+
cacheDir: path.join(this.rootPath, ".cache"),
179+
minify: !!process.env.MINIFY,
180+
logLevel: 1,
181+
publicUrl: "/",
182+
})
191183
}
192184
}
193185

src/browser/pages/login.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/browser/register.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { getOptions, normalize } from "../common/util"
22

33
const options = getOptions()
44

5-
import "./pages/error.css"
6-
import "./pages/global.css"
7-
import "./pages/login.css"
5+
import "./static/assets/error.css"
6+
import "./static/assets/global.css"
7+
import "./static/assets/login.css"
88

99
if ("serviceWorker" in navigator) {
10-
const path = normalize(`${options.csStaticBase}/dist/serviceWorker.js`)
10+
const path = normalize(`${options.base}/serviceWorker.js`)
1111
navigator.serviceWorker
1212
.register(path, {
1313
scope: (options.base ?? "") + "/",

src/browser/serviceWorker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22

33
self.addEventListener("install", () => {
4-
console.log("[Service Worker] install")
4+
console.log("[Code Server Service Worker] install")
55
})
66

77
self.addEventListener("activate", (event: any) => {
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/browser/pages/error.handlebars renamed to src/browser/views/error.handlebars

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
content="style-src 'self'; manifest-src 'self'; img-src 'self' data:; font-src 'self' data:;"
1212
/>
1313
<title>{{ERROR_TITLE}} — Code Server</title>
14-
<link rel="icon" href="{{CS_STATIC_BASE}}/src/browser/media/favicon.ico" type="image/x-icon" />
15-
<link rel="manifest" href="/code-server.webmanifest" crossorigin="use-credentials" />
16-
<link rel="apple-touch-icon" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-384.png" />
17-
<link href="{{CS_STATIC_BASE}}/dist/register.css" rel="stylesheet" />
14+
<link rel="icon" href="{{assetPath csStaticBase '/media/favicon.ico'}}" type="image/x-icon" />
15+
<link rel="manifest" href="{{assetPath base '/code-server.webmanifest'}}" crossorigin="use-credentials" />
16+
<link rel="apple-touch-icon" href="{{assetPath csStaticBase '/media/pwa-icon-384.png'}}" />
17+
<link href="{{assetPath csStaticBase '/register.css'}}" rel="stylesheet" />
1818
<meta id="coder-options" data-settings="{{{json coderOptions}}}" />
1919
</head>
2020
<body>
@@ -23,10 +23,10 @@
2323
<h2 class="header">{{ERROR_HEADER}}</h2>
2424
<div class="body">{{ERROR_BODY}}</div>
2525
<div class="links">
26-
<a class="link" href="{{BASE}}{{TO}}">Go home</a>
26+
<a class="link" href="{{HOME_PATH}}">Go home</a>
2727
</div>
2828
</div>
2929
</div>
30-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/register.js"></script>
30+
<script data-cfasync="false" src="{{assetPath base '/register.js'}}"></script>
3131
</body>
3232
</html>

src/browser/pages/login.handlebars renamed to src/browser/views/login.handlebars

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
content="style-src 'self'; script-src 'self' 'unsafe-inline'; manifest-src 'self'; img-src 'self' data:; font-src 'self' data:;"
1212
/>
1313
<title>Login — Code Server</title>
14-
<link rel="icon" href="{{CS_STATIC_BASE}}/src/browser/media/favicon.ico" type="image/x-icon" />
15-
<link rel="manifest" href="/code-server.webmanifest" crossorigin="use-credentials" />
16-
<link rel="apple-touch-icon" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-384.png" />
17-
<link href="{{CS_STATIC_BASE}}/dist/register.css" rel="stylesheet" />
14+
15+
<link rel="icon" href="{{assetPath csStaticBase '/media/favicon.ico'}}" type="image/x-icon" />
16+
<link rel="manifest" href="{{assetPath base '/code-server.webmanifest'}}" crossorigin="use-credentials" />
17+
<link rel="apple-touch-icon" href="{{assetPath csStaticBase '/src/browser/media/pwa-icon-384.png'}}" />
18+
<link href="{{assetPath base '/register.css'}}" rel="stylesheet" />
1819
<meta id="coder-options" data-settings="{{{json coderOptions}}}" />
1920
</head>
2021
<body>
@@ -50,6 +51,5 @@
5051
</div>
5152
</div>
5253
</body>
53-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/register.js"></script>
54-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/pages/login.js"></script>
55-
</html>
54+
<script data-cfasync="false" src="{{assetPath base '/register.js'}}"></script>
55+
</html>

src/browser/pages/vscode.handlebars renamed to src/browser/views/vscode.handlebars

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@
2525
<meta id="vscode-remote-nls-configuration" data-settings="{{{json workbenchOptions.nlsConfiguration}}}" />
2626

2727
<!-- Workbench Icon/Manifest/CSS -->
28-
<link rel="icon" href="{{CS_STATIC_BASE}}/src/browser/media/favicon.ico" type="image/x-icon" />
29-
<link rel="manifest" href="/code-server.webmanifest" crossorigin="use-credentials" />
28+
<link rel="icon" href="{{assetPath csStaticBase '/src/browser/media/favicon.ico'}}" type="image/x-icon" />
29+
<link rel="manifest" href="./code-server.webmanifest" crossorigin="use-credentials" />
3030

3131
{{#if (prod)}}
32-
<link data-name="vs/workbench/workbench.web.api" rel="stylesheet" href="{{CS_STATIC_BASE}}/lib/vscode/out/vs/workbench/workbench.web.api.css">
32+
<link data-name="vs/workbench/workbench.web.api" rel="stylesheet" href="{{assetPath csStaticBase '/lib/vscode/out/vs/workbench/workbench.web.api.css'}}">
3333
{{/if}}
3434

35-
<link rel="apple-touch-icon" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-384.png" />
35+
<link rel="apple-touch-icon" href="{{assetPath csStaticBase '/src/browser/media/pwa-icon-384.png'}}" />
3636
<meta name="apple-mobile-web-app-capable" content="yes" />
3737

3838
<!-- Prefetch to avoid waterfall -->
3939
{{#if (prod)}}
40-
<link rel="prefetch" href="{{CS_STATIC_BASE}}/lib/vscode/node_modules/semver-umd/lib/semver-umd.js">
40+
<link rel="prefetch" href="{{assetPath csStaticBase '/lib/vscode/node_modules/semver-umd/lib/semver-umd.js'}}">
4141
{{/if}}
4242

4343
<meta id="coder-options" data-settings="{{{json coderOptions}}}" />
@@ -46,20 +46,21 @@
4646
<body aria-label=""></body>
4747

4848
<!-- Startup (do not modify order of script tags!) -->
49-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/pages/vscode.js"></script>
50-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/register.js"></script>
51-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/lib/vscode/out/vs/loader.js"></script>
49+
<script data-cfasync="false" src="{{assetPath base '/pages/vscode.js'}}"></script>
50+
<script data-cfasync="false" src="{{assetPath base '/register.js'}}"></script>
51+
<script data-cfasync="false" src="{{assetPath base '/lib/vscode/out/vs/loader.js'}}"></script>
5252

5353
<script>
5454
globalThis.MonacoPerformanceMarks.push("willLoadWorkbenchMain", Date.now());
5555
</script>
5656

5757
{{#if (prod)}}
58-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/lib/vscode/out/vs/workbench/workbench.web.api.nls.js"></script>
59-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/lib/vscode/out/vs/workbench/workbench.web.api.js"></script>
58+
<script data-cfasync="false" src="{{assetPath base '/lib/vscode/out/vs/workbench/workbench.web.api.nls.js'}}"></script>
59+
<script data-cfasync="false" src="{{assetPath base '/lib/vscode/out/vs/workbench/workbench.web.api.js'}}"></script>
6060
{{/if}}
6161

6262
<script>
63+
require.config({baseUrl: `${window.location.origin}/{{base}}/lib/vscode/out`});
6364
require(["vs/code/browser/workbench/workbench"], function () {});
6465
</script>
6566
</html>

src/common/util.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export const generateUuid = (length = 24): string => {
3131

3232
/**
3333
* Remove extra slashes in a URL.
34+
* @TODO replace with node `path` module.
3435
*/
3536
export const normalize = (url: string, keepTrailing = false): string => {
3637
return url.replace(/\/\/+/g, "/").replace(/\/+$/, keepTrailing ? "/" : "")

src/node/app.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { promises as fs } from "fs"
66
import http from "http"
77
import * as httpolyglot from "httpolyglot"
88
import { resolve } from "path"
9+
import { normalize } from "../common/util"
910
import { DefaultedArgs } from "./cli"
1011
import { rootPath } from "./constants"
1112
import { handleUpgrade } from "./http"
@@ -21,8 +22,10 @@ export const createApp = async (args: DefaultedArgs): Promise<[Express, http.Ser
2122
app.engine(
2223
"handlebars",
2324
exphbs({
25+
defaultLayout: "",
2426
helpers: {
2527
prod: () => prod,
28+
assetPath: (base: string, path: string) => normalize(base + path),
2629
/**
2730
* Converts to JSON string and encodes entities for use in HTML.
2831
* @TODO we can likely move JSON attributes to <script type="text/json">
@@ -33,7 +36,7 @@ export const createApp = async (args: DefaultedArgs): Promise<[Express, http.Ser
3336
}),
3437
)
3538

36-
app.set("views", resolve(rootPath, "src/browser/pages"))
39+
app.set("views", resolve(rootPath, "src/browser/views"))
3740
app.set("view engine", "handlebars")
3841

3942
const server = args.cert

src/node/http.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,14 @@ import safeCompare from "safe-compare"
88
import { HttpCode, HttpError } from "../common/http"
99
import { normalize, Options } from "../common/util"
1010
import { AuthType } from "./cli"
11-
import { commit, rootPath } from "./constants"
1211
import { Heart } from "./heart"
1312
import { hash } from "./util"
1413

1514
export interface Locals {
1615
heart: Heart
1716
}
1817

19-
export interface CommonTemplateVars {
20-
layout: boolean
21-
TO: string
22-
BASE: string
23-
CS_STATIC_BASE: string
18+
export interface CommonTemplateVars extends Options {
2419
coderOptions: Options
2520
}
2621

@@ -29,19 +24,27 @@ export const commonTemplateVars = <T extends Options>(
2924
extraOpts?: Omit<T, "base" | "csStaticBase" | "logLevel">,
3025
): CommonTemplateVars => {
3126
const base = relativeRoot(req)
27+
const csStaticBase = base + "/static/"
3228
const coderOptions: Options = {
3329
base,
34-
csStaticBase: base + "/static/" + commit + rootPath,
30+
csStaticBase,
3531
logLevel: logger.level,
3632
...extraOpts,
3733
}
3834

3935
return {
40-
TO: (typeof req.query.to === "string" && req.query.to) || "/",
41-
BASE: coderOptions.base,
42-
CS_STATIC_BASE: coderOptions.csStaticBase,
36+
...coderOptions,
4337
coderOptions,
44-
layout: false,
38+
}
39+
}
40+
41+
/**
42+
* Injects variables into template scope.
43+
*/
44+
export const templateMiddleware = (locals: express.Application["locals"]): express.RequestHandler => {
45+
return (req, _, next) => {
46+
Object.assign(locals, commonTemplateVars(req))
47+
next()
4548
}
4649
}
4750

src/node/routes/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { plural } from "../../common/util"
1111
import { AuthType, DefaultedArgs } from "../cli"
1212
import { rootPath } from "../constants"
1313
import { Heart } from "../heart"
14-
import { commonTemplateVars } from "../http"
14+
import { templateMiddleware } from "../http"
1515
import { loadPlugins } from "../plugin"
1616
import * as domainProxy from "../proxy"
1717
import { getMediaMime, paths } from "../util"
@@ -55,6 +55,7 @@ export const register = async (app: Express, server: http.Server, args: Defaulte
5555
app.use(cookieParser())
5656
app.use(bodyParser.json())
5757
app.use(bodyParser.urlencoded({ extended: true }))
58+
app.use(templateMiddleware(app.locals))
5859

5960
server.on("upgrade", () => {
6061
heart.beat()
@@ -84,15 +85,16 @@ export const register = async (app: Express, server: http.Server, args: Defaulte
8485
return next()
8586
})
8687

88+
app.use("/", _static.router)
8789
app.use("/", domainProxy.router)
8890
app.use("/", vscode.router)
8991
app.use("/", manifest.router)
92+
9093
app.use("/healthz", health.router)
9194
if (args.auth === AuthType.Password) {
9295
app.use("/login", login.router)
9396
}
9497
app.use("/proxy", proxy.router)
95-
app.use("/static", _static.router)
9698
app.use("/update", update.router)
9799
app.use("/vscode", vscode.router)
98100

@@ -111,7 +113,7 @@ export const register = async (app: Express, server: http.Server, args: Defaulte
111113

112114
try {
113115
res.status(status).render("error", {
114-
...commonTemplateVars(req),
116+
HOME_PATH: (typeof req.query.to === "string" && req.query.to) || "/",
115117
ERROR_TITLE: status,
116118
ERROR_HEADER: status,
117119
ERROR_BODY: err.message,

src/node/routes/login.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Router, ErrorRequestHandler } from "express"
22
import { RateLimiter as Limiter } from "limiter"
33
import safeCompare from "safe-compare"
4-
import { authenticated, getCookieDomain, redirect, commonTemplateVars } from "../http"
4+
import { authenticated, getCookieDomain, redirect } from "../http"
55
import { hash, humanPath } from "../util"
66

77
enum Cookie {
@@ -28,7 +28,6 @@ const rootHandler: ErrorRequestHandler = async (error: Error | undefined, req, r
2828
: `Check the config file at ${humanPath(req.args.config)} for the password.`
2929

3030
res.render("login", {
31-
...commonTemplateVars(req),
3231
PASSWORD_MSG: passwordMsg,
3332
ERROR: error?.message || "",
3433
})

src/node/routes/manifest.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
import { Router } from "express"
2+
import { normalize } from "../../common/util"
23
import { CommonTemplateVars, commonTemplateVars } from "../http"
34

45
export const router = Router()
56

67
const iconSizes = [96, 128, 192, 256, 384, 512]
78

8-
export const createWebManifest = ({ BASE, CS_STATIC_BASE }: CommonTemplateVars) => {
9+
export const createWebManifest = ({ base, csStaticBase }: CommonTemplateVars) => {
910
const icons = iconSizes.map((iconSize) => ({
10-
src: `${CS_STATIC_BASE}/src/browser/media/pwa-icon-${iconSize}.png`,
11+
src: normalize(`${csStaticBase}/media/pwa-icon-${iconSize}.png`),
1112
type: "image/png",
1213
sizes: `${iconSize}x${iconSize}`,
1314
}))
1415

1516
return {
1617
name: "code-server",
1718
short_name: "code-server",
18-
start_url: BASE,
19+
start_url: base,
1920
display: "fullscreen",
2021
"background-color": "#fff",
2122
description: "Run editors on a remote server.",

0 commit comments

Comments
 (0)