Skip to content

Commit 4cd2f2c

Browse files
committed
Simplify build and development steps
1 parent 88cef85 commit 4cd2f2c

File tree

3 files changed

+50
-58
lines changed

3 files changed

+50
-58
lines changed

README.md

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,13 @@ arguments when launching code-server with Docker. See
5858

5959
### Build
6060

61-
- If you also plan on developing, set the `OUT` environment variable. Otherwise
62-
it will build in this directory which will cause issues because `yarn watch`
63-
will try to compile the build directory as well.
64-
- Run `yarn build ${vscodeVersion} ${codeServerVersion}` in this directory (for
65-
example: `yarn build 1.36.0 development`).
66-
- If you target the same VS Code version our Travis builds do everything will
67-
work but if you target some other version it might not (we have to do some
68-
patching to VS Code so different versions aren't always compatible).
69-
- You can run the built code with `node path/to/build/out/vs/server/main.js` or run
70-
`yarn binary` with the same arguments in the previous step to package the
71-
code into a single binary.
61+
```shell
62+
export OUT=/path/to/output/build # Optional if only building. Required if also developing.
63+
yarn build ${vscodeVersion} ${codeServerVersion} # See travis.yml for the VS Code version to use.
64+
# The code-server version can be anything you want.
65+
node ~/path/to/output/build/out/vs/server/main.js # You can run the built JavaScript with Node.
66+
yarn binary ${vscodeVersion} ${codeServerVersion} # Or you can package it into a binary.
67+
```
7268

7369
## Known Issues
7470

@@ -109,11 +105,12 @@ data collected to improve code-server.
109105
```shell
110106
git clone https://github.com/microsoft/vscode
111107
cd vscode
112-
git checkout <see travis.yml for the VS Code version to use here>
108+
git checkout ${vscodeVersion} # See travis.yml for the version to use.
109+
yarn
113110
git clone https://github.com/cdr/code-server src/vs/server
114111
cd src/vs/server
115-
yarn patch:apply
116112
yarn
113+
yarn patch:apply
117114
yarn watch
118115
# Wait for the initial compilation to complete (it will say "Finished compilation").
119116
# Run the next command in another shell.

package.json

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22
"license": "MIT",
33
"scripts": {
44
"runner": "cd ./scripts && node --max-old-space-size=32384 -r ts-node/register ./build.ts",
5-
"preinstall": "yarn runner ensure-in-vscode && cd ../../../ && yarn || true",
6-
"postinstall": "rm -rf node_modules/@types/node",
7-
"start": "yarn runner ensure-in-vscode && nodemon --watch ../../../out --verbose ../../../out/vs/server/main.js",
8-
"watch": "yarn runner ensure-in-vscode && cd ../../../ && yarn watch",
9-
"build": "yarn --ignore-scripts && yarn runner build",
5+
"start": "nodemon --watch ../../../out --verbose ../../../out/vs/server/main.js",
6+
"watch": "cd ../../../ && yarn watch",
7+
"build": "yarn && yarn runner build",
108
"package": "yarn runner package",
119
"binary": "yarn runner binary",
12-
"patch:generate": "yarn runner ensure-in-vscode && cd ../../../ && git diff --staged > ./src/vs/server/scripts/vscode.patch",
13-
"patch:apply": "yarn runner ensure-in-vscode && cd ../../../ && git apply ./src/vs/server/scripts/vscode.patch"
10+
"patch:generate": "cd ../../../ && git diff --staged > ./src/vs/server/scripts/vscode.patch",
11+
"patch:apply": "cd ../../../ && git apply ./src/vs/server/scripts/vscode.patch"
1412
},
1513
"devDependencies": {
1614
"@coder/nbin": "^1.2.2",

scripts/build.ts

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,34 @@ class Builder {
2020
private readonly rootPath = path.resolve(__dirname, "..");
2121
private readonly outPath = process.env.OUT || this.rootPath;
2222
private _target?: "darwin" | "alpine" | "linux";
23-
private task?: Task;
23+
private currentTask?: Task;
2424

2525
public run(task: Task | undefined, args: string[]): void {
26-
this.task = task;
26+
this.currentTask = task;
2727
this.doRun(task, args).catch((error) => {
2828
console.error(error.message);
2929
process.exit(1);
3030
});
3131
}
3232

33+
private async task<T>(message: string, fn: () => Promise<T>): Promise<T> {
34+
const time = Date.now();
35+
this.log(`${message}...`, true);
36+
try {
37+
const t = await fn();
38+
process.stdout.write(`took ${Date.now() - time}ms\n`);
39+
return t;
40+
} catch (error) {
41+
process.stdout.write("failed\n");
42+
throw error;
43+
}
44+
}
45+
3346
/**
3447
* Writes to stdout with an optional newline.
3548
*/
3649
private log(message: string, skipNewline: boolean = false): void {
37-
process.stdout.write(`[${this.task || "default"}] ${message}`);
50+
process.stdout.write(`[${this.currentTask || "default"}] ${message}`);
3851
if (!skipNewline) {
3952
process.stdout.write("\n");
4053
}
@@ -140,43 +153,28 @@ class Builder {
140153
* Build code-server within VS Code.
141154
*/
142155
private async build(vscodeSourcePath: string, vscodeVersion: string, codeServerVersion: string, finalBuildPath: string): Promise<void> {
143-
const task = async <T>(message: string, fn: () => Promise<T>): Promise<T> => {
144-
const time = Date.now();
145-
this.log(`${message}...`, true);
146-
try {
147-
const t = await fn();
148-
process.stdout.write(`took ${Date.now() - time}ms\n`);
149-
return t;
150-
} catch (error) {
151-
process.stdout.write("failed\n");
152-
throw error;
153-
}
154-
};
155-
156156
// Install dependencies (should be cached by CI).
157-
// Ignore scripts since we'll install VS Code dependencies separately.
158-
await task("Installing code-server dependencies", async () => {
159-
await util.promisify(cp.exec)("yarn --ignore-scripts", { cwd: this.rootPath });
160-
await util.promisify(cp.exec)("yarn postinstall", { cwd: this.rootPath });
157+
await this.task("Installing code-server dependencies", async () => {
158+
await util.promisify(cp.exec)("yarn", { cwd: this.rootPath });
161159
});
162160

163161
// Download and prepare VS Code if necessary (should be cached by CI).
164162
const exists = fs.existsSync(vscodeSourcePath);
165163
if (exists) {
166164
this.log("Using existing VS Code directory");
167165
} else {
168-
await task("Cloning VS Code", () => {
166+
await this.task("Cloning VS Code", () => {
169167
return util.promisify(cp.exec)(
170168
"git clone https://github.com/microsoft/vscode"
171169
+ ` --quiet --branch "${vscodeVersion}"`
172170
+ ` --single-branch --depth=1 "${vscodeSourcePath}"`);
173171
});
174172

175-
await task("Installing VS Code dependencies", () => {
173+
await this.task("Installing VS Code dependencies", () => {
176174
return util.promisify(cp.exec)("yarn", { cwd: vscodeSourcePath });
177175
});
178176

179-
await task("Building default extensions", () => {
177+
await this.task("Building default extensions", () => {
180178
return util.promisify(cp.exec)(
181179
"yarn gulp compile-extensions-build --max-old-space-size=32384",
182180
{ cwd: vscodeSourcePath },
@@ -185,31 +183,31 @@ class Builder {
185183
}
186184

187185
// Clean before patching or it could fail if already patched.
188-
await task("Patching VS Code", async () => {
186+
await this.task("Patching VS Code", async () => {
189187
await util.promisify(cp.exec)("git reset --hard", { cwd: vscodeSourcePath });
190188
await util.promisify(cp.exec)("git clean -fd", { cwd: vscodeSourcePath });
191189
await util.promisify(cp.exec)(`git apply ${this.rootPath}/scripts/vscode.patch`, { cwd: vscodeSourcePath });
192190
});
193191

194192
const serverPath = path.join(vscodeSourcePath, "src/vs/server");
195-
await task("Copying code-server into VS Code", async () => {
193+
await this.task("Copying code-server into VS Code", async () => {
196194
await fs.remove(serverPath);
197195
await fs.mkdirp(serverPath);
198196
await Promise.all(["main.js", "node_modules", "src", "typings"].map((fileName) => {
199197
return fs.copy(path.join(this.rootPath, fileName), path.join(serverPath, fileName));
200198
}));
201199
});
202200

203-
await task("Building VS Code", () => {
201+
await this.task("Building VS Code", () => {
204202
return util.promisify(cp.exec)("yarn gulp compile-build --max-old-space-size=32384", { cwd: vscodeSourcePath });
205203
});
206204

207-
await task("Optimizing VS Code", async () => {
205+
await this.task("Optimizing VS Code", async () => {
208206
await fs.copyFile(path.join(this.rootPath, "scripts/optimize.js"), path.join(vscodeSourcePath, "coder.js"));
209207
await util.promisify(cp.exec)(`yarn gulp optimize --max-old-space-size=32384 --gulpfile ./coder.js`, { cwd: vscodeSourcePath });
210208
});
211209

212-
const { productJson, packageJson } = await task("Generating final package.json and product.json", async () => {
210+
const { productJson, packageJson } = await this.task("Generating final package.json and product.json", async () => {
213211
const merge = async (name: string, extraJson: { [key: string]: string } = {}): Promise<{ [key: string]: string }> => {
214212
const [aJson, bJson] = (await Promise.all([
215213
fs.readFile(path.join(vscodeSourcePath, `${name}.json`), "utf8"),
@@ -247,13 +245,13 @@ class Builder {
247245
});
248246

249247
if (process.env.MINIFY) {
250-
await task("Minifying VS Code", () => {
248+
await this.task("Minifying VS Code", () => {
251249
return util.promisify(cp.exec)("yarn gulp minify --max-old-space-size=32384 --gulpfile ./coder.js", { cwd: vscodeSourcePath });
252250
});
253251
}
254252

255253
const finalServerPath = path.join(finalBuildPath, "out/vs/server");
256-
await task("Copying into final build directory", async () => {
254+
await this.task("Copying into final build directory", async () => {
257255
await fs.remove(finalBuildPath);
258256
await fs.mkdirp(finalBuildPath);
259257
await Promise.all([
@@ -271,18 +269,17 @@ class Builder {
271269
});
272270

273271
if (process.env.MINIFY) {
274-
await task("Restricting to production dependencies", async () => {
272+
await this.task("Restricting to production dependencies", async () => {
275273
await Promise.all(["package.json", "yarn.lock"].map((fileName) => {
276274
Promise.all([
277275
fs.copy(path.join(this.rootPath, fileName), path.join(finalServerPath, fileName)),
278276
fs.copy(path.join(path.join(vscodeSourcePath, "remote"), fileName), path.join(finalBuildPath, fileName)),
279277
]);
280278
}));
281279

282-
await Promise.all([
283-
util.promisify(cp.exec)("yarn --production --ignore-scripts", { cwd: finalServerPath }),
284-
util.promisify(cp.exec)("yarn --production", { cwd: finalBuildPath }),
285-
]);
280+
await Promise.all([finalServerPath, finalBuildPath].map((cwd) => {
281+
return util.promisify(cp.exec)("yarn --production", { cwd });
282+
}));
286283

287284
await Promise.all(["package.json", "yarn.lock"].map((fileName) => {
288285
return Promise.all([
@@ -293,15 +290,15 @@ class Builder {
293290
});
294291
}
295292

296-
await task("Writing final package.json and product.json", () => {
293+
await this.task("Writing final package.json and product.json", () => {
297294
return Promise.all([
298295
fs.writeFile(path.join(finalBuildPath, "package.json"), JSON.stringify(packageJson, null, 2)),
299296
fs.writeFile(path.join(finalBuildPath, "product.json"), JSON.stringify(productJson, null, 2)),
300297
]);
301298
});
302299

303300
// This is so it doesn't get cached along with VS Code (no point).
304-
await task("Removing copied server", () => fs.remove(serverPath));
301+
await this.task("Removing copied server", () => fs.remove(serverPath));
305302

306303
// Prepend code to the target which enables finding files within the binary.
307304
const prependLoader = async (relativeFilePath: string): Promise<void> => {
@@ -322,7 +319,7 @@ class Builder {
322319
await fs.writeFile(filePath, shim + (await fs.readFile(filePath, "utf8")));
323320
};
324321

325-
await task("Prepending nbin loader", () => {
322+
await this.task("Prepending nbin loader", () => {
326323
return Promise.all([
327324
prependLoader("out/vs/server/main.js"),
328325
prependLoader("out/bootstrap-fork.js"),

0 commit comments

Comments
 (0)