Skip to content

Commit bc349b5

Browse files
committed
refactor: upgrade to parcel v2
1 parent bf45e7c commit bc349b5

15 files changed

+1159
-3925
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
.tsbuildinfo
22
.cache
3-
dist*
43
/out*/
54
release/
65
release-npm-package/
@@ -18,3 +17,4 @@ coverage
1817
**/.DS_Store
1918
# Failed e2e test videos are saved here
2019
test/test-results
20+
/.parcel-cache

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ VS Code v0.00.0
6464
### Development
6565

6666
- fix(publish): update cdrci fork in brew-bump.sh #3468 @jsjoeio
67+
- chore(dev): upgrade to parcel v2 #3578 @jsjoeio
6768

6869
## 3.10.2
6970

ci/build/build-code-server.sh

+5-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ set -euo pipefail
77
MINIFY=${MINIFY-true}
88

99
main() {
10+
local opts=()
11+
[[ $MINIFY ]] && opts+=("-p" "tinyfy")
1012
cd "$(dirname "${0}")/../.."
1113

1214
tsc
@@ -32,14 +34,9 @@ main() {
3234
set -e
3335
fi
3436

35-
parcel build \
36-
--public-url "." \
37-
--out-dir dist \
38-
$([[ $MINIFY ]] || echo --no-minify) \
39-
src/browser/register.ts \
40-
src/browser/serviceWorker.ts \
41-
src/browser/pages/login.ts \
42-
src/browser/pages/vscode.ts
37+
yarn browserify "${opts[@]}" src/browser/register.ts -o out/browser/register.browserified.js
38+
yarn browserify "${opts[@]}" src/browser/pages/login.ts -o out/browser/pages/login.browserified.js
39+
yarn browserify "${opts[@]}" src/browser/pages/vscode.ts -o out/browser/pages/vscode.browserified.js
4340
}
4441

4542
main "$@"

ci/build/build-release.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@ main() {
2828
}
2929

3030
bundle_code_server() {
31-
rsync out dist "$RELEASE_PATH"
31+
rsync out "$RELEASE_PATH"
3232

3333
# For source maps and images.
3434
mkdir -p "$RELEASE_PATH/src/browser"
3535
rsync src/browser/media/ "$RELEASE_PATH/src/browser/media"
3636
mkdir -p "$RELEASE_PATH/src/browser/pages"
3737
rsync src/browser/pages/*.html "$RELEASE_PATH/src/browser/pages"
38+
rsync src/browser/pages/*.css "$RELEASE_PATH/src/browser/pages"
3839
rsync src/browser/robots.txt "$RELEASE_PATH/src/browser"
3940

4041
# Add typings for plugins

ci/dev/watch.ts

+27-33
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as cp from "child_process"
2-
import Bundler from "parcel-bundler"
32
import * as path from "path"
3+
import * as fs from "fs"
4+
import browserify from "browserify"
45

56
async function main(): Promise<void> {
67
try {
@@ -40,7 +41,6 @@ class Watcher {
4041
const plugin = process.env.PLUGIN_DIR
4142
? cp.spawn("yarn", ["build", "--watch"], { cwd: process.env.PLUGIN_DIR })
4243
: undefined
43-
const bundler = this.createBundler()
4444

4545
const cleanup = (code?: number | null): void => {
4646
Watcher.log("killing vs code watcher")
@@ -63,7 +63,7 @@ class Watcher {
6363
server.kill()
6464
}
6565

66-
Watcher.log("killing bundler")
66+
Watcher.log("killing watch")
6767
process.exit(code || 0)
6868
}
6969

@@ -84,23 +84,19 @@ class Watcher {
8484
cleanup(code)
8585
})
8686
}
87-
const bundle = bundler.bundle().catch(() => {
88-
Watcher.log("parcel watcher terminated unexpectedly")
89-
cleanup(1)
90-
})
91-
bundler.on("buildEnd", () => {
92-
console.log("[parcel] bundled")
93-
})
94-
bundler.on("buildError", (error) => {
95-
console.error("[parcel]", error)
96-
})
9787

9888
vscode.stderr.on("data", (d) => process.stderr.write(d))
9989
tsc.stderr.on("data", (d) => process.stderr.write(d))
10090
if (plugin) {
10191
plugin.stderr.on("data", (d) => process.stderr.write(d))
10292
}
10393

94+
const browserFiles = [
95+
path.join(this.rootPath, "out/browser/register.js"),
96+
path.join(this.rootPath, "out/browser/pages/login.js"),
97+
path.join(this.rootPath, "out/browser/pages/vscode.js"),
98+
]
99+
104100
// From https://github.com/chalk/ansi-regex
105101
const pattern = [
106102
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
@@ -143,7 +139,7 @@ class Watcher {
143139
startingVscode = true
144140
} else if (startingVscode && line.includes("Finished compilation")) {
145141
if (startedVscode) {
146-
bundle.then(restartServer)
142+
restartServer()
147143
}
148144
startedVscode = true
149145
}
@@ -155,7 +151,8 @@ class Watcher {
155151
console.log("[tsc]", original)
156152
}
157153
if (line.includes("Watching for file changes")) {
158-
bundle.then(restartServer)
154+
bundleBrowserCode(browserFiles)
155+
restartServer()
159156
}
160157
})
161158

@@ -166,29 +163,26 @@ class Watcher {
166163
console.log("[plugin]", original)
167164
}
168165
if (line.includes("Watching for file changes")) {
169-
bundle.then(restartServer)
166+
restartServer()
170167
}
171168
})
172169
}
173170
}
171+
}
174172

175-
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-
)
191-
}
173+
function bundleBrowserCode(inputFiles: string[]) {
174+
console.log(`[browser] bundling...`)
175+
inputFiles.forEach(async (path: string) => {
176+
const outputPath = path.replace(".js", ".browserified.js")
177+
browserify()
178+
.add(path)
179+
.bundle()
180+
.on("error", function (error: Error) {
181+
console.error(error.toString())
182+
})
183+
.pipe(fs.createWriteStream(outputPath))
184+
})
185+
console.log(`[browser] done bundling`)
192186
}
193187

194188
main()

package.json

+4-6
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@
2929
"lint": "./ci/dev/lint.sh",
3030
"test": "echo 'Run yarn test:unit or yarn test:e2e' && exit 1",
3131
"ci": "./ci/dev/ci.sh",
32-
"watch": "VSCODE_IPC_HOOK_CLI= NODE_OPTIONS=--max_old_space_size=32384 ts-node ./ci/dev/watch.ts",
32+
"watch": "VSCODE_IPC_HOOK_CLI= NODE_OPTIONS='--max_old_space_size=32384 --trace-warnings' ts-node ./ci/dev/watch.ts",
3333
"icons": "./ci/dev/gen_icons.sh",
3434
"coverage": "codecov"
3535
},
3636
"main": "out/node/entry.js",
3737
"devDependencies": {
3838
"@schemastore/package": "^0.0.6",
3939
"@types/body-parser": "^1.19.0",
40+
"@types/browserify": "^12.0.36",
4041
"@types/compression": "^1.7.0",
4142
"@types/cookie-parser": "^1.4.2",
4243
"@types/express": "^4.17.8",
4344
"@types/http-proxy": "^1.17.4",
4445
"@types/js-yaml": "^4.0.0",
4546
"@types/node": "^14.17.1",
46-
"@types/parcel-bundler": "^1.12.1",
4747
"@types/pem": "^1.9.5",
4848
"@types/proxy-from-env": "^1.0.1",
4949
"@types/safe-compare": "^1.1.0",
@@ -56,6 +56,7 @@
5656
"@typescript-eslint/eslint-plugin": "^4.7.0",
5757
"@typescript-eslint/parser": "^4.7.0",
5858
"audit-ci": "^4.0.0",
59+
"browserify": "^17.0.0",
5960
"codecov": "^3.8.1",
6061
"doctoc": "^2.0.0",
6162
"eslint": "^7.7.0",
@@ -64,12 +65,12 @@
6465
"eslint-plugin-import": "^2.18.2",
6566
"eslint-plugin-prettier": "^3.1.0",
6667
"leaked-handles": "^5.2.0",
67-
"parcel-bundler": "^1.12.5",
6868
"prettier": "^2.2.1",
6969
"prettier-plugin-sh": "^0.6.0",
7070
"shellcheck": "^1.0.0",
7171
"stylelint": "^13.0.0",
7272
"stylelint-config-recommended": "^5.0.0",
73+
"tinyify": "^3.0.0",
7374
"ts-node": "^10.0.0",
7475
"typescript": "^4.1.3",
7576
"wtfnode": "^0.9.0"
@@ -79,9 +80,6 @@
7980
"doctoc/underscore": "^1.13.1",
8081
"doctoc/**/trim": "^1.0.0",
8182
"postcss": "^8.2.1",
82-
"parcel-bundler/cssnano": "^5.0.2",
83-
"parcel-bundler/ws": "^7.4.6",
84-
"parcel-bundler/htmlnano/uncss/jsdom/ws": "^7.4.6",
8583
"browserslist": "^4.16.5",
8684
"safe-buffer": "^5.1.1",
8785
"vfile-message": "^2.0.2"

src/browser/pages/error.html

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
<link rel="manifest" href="{{CS_STATIC_BASE}}/src/browser/media/manifest.json" crossorigin="use-credentials" />
1717
<link rel="apple-touch-icon" sizes="192x192" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-192.png" />
1818
<link rel="apple-touch-icon" sizes="512x512" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-512.png" />
19-
<link href="{{CS_STATIC_BASE}}/dist/register.css" rel="stylesheet" />
19+
<link href="{{CS_STATIC_BASE}}/src/browser/pages/global.css" rel="stylesheet" />
20+
<link href="{{CS_STATIC_BASE}}/src/browser/pages/error.css" rel="stylesheet" />
2021
<meta id="coder-options" data-settings="{{OPTIONS}}" />
2122
</head>
2223
<body>
@@ -29,6 +30,6 @@ <h2 class="header">{{ERROR_HEADER}}</h2>
2930
</div>
3031
</div>
3132
</div>
32-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/register.js"></script>
33+
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/out/browser/register.browserified.js"></script>
3334
</body>
3435
</html>

src/browser/pages/login.html

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
<link rel="manifest" href="{{CS_STATIC_BASE}}/src/browser/media/manifest.json" crossorigin="use-credentials" />
1717
<link rel="apple-touch-icon" sizes="192x192" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-192.png" />
1818
<link rel="apple-touch-icon" sizes="512x512" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-512.png" />
19-
<link href="{{CS_STATIC_BASE}}/dist/register.css" rel="stylesheet" />
19+
<link href="{{CS_STATIC_BASE}}/src/browser/pages/global.css" rel="stylesheet" />
20+
<link href="{{CS_STATIC_BASE}}/src/browser/pages/login.css" rel="stylesheet" />
2021
<meta id="coder-options" data-settings="{{OPTIONS}}" />
2122
</head>
2223
<body>
@@ -48,6 +49,6 @@ <h1 class="main">Welcome to code-server</h1>
4849
</div>
4950
</div>
5051
</body>
51-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/register.js"></script>
52-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/pages/login.js"></script>
52+
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/out/browser/pages/login.browserified.js"></script>
53+
``
5354
</html>

src/browser/pages/login.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getOptions } from "../../common/util"
2+
import "../register"
23

34
const options = getOptions()
45
const el = document.getElementById("base") as HTMLInputElement

src/browser/pages/vscode.html

+1-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@
3939
<body aria-label=""></body>
4040

4141
<!-- Startup (do not modify order of script tags!) -->
42-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/pages/vscode.js"></script>
43-
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/register.js"></script>
42+
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/out/browser/pages/vscode.browserified.js"></script>
4443
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/lib/vscode/out/vs/loader.js"></script>
4544
<script>
4645
performance.mark("code/willLoadWorkbenchMain")

src/browser/pages/vscode.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getOptions } from "../../common/util"
2+
import "../register"
23

34
const options = getOptions()
45

@@ -30,8 +31,8 @@ try {
3031
/* Probably fine. */
3132
}
3233

33-
;(self.require as any) = {
34-
// Without the full URL VS Code will try to load file://.
34+
;(self as any).require = {
35+
// Without the full URL VS Code will try to load file://.w
3536
baseUrl: `${window.location.origin}${options.csStaticBase}/lib/vscode/out`,
3637
recordStats: true,
3738
paths: {

src/browser/register.ts

-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import { logger } from "@coder/logger"
22
import { getOptions, normalize, logError } from "../common/util"
33

4-
import "./pages/error.css"
5-
import "./pages/global.css"
6-
import "./pages/login.css"
7-
84
export async function registerServiceWorker(): Promise<void> {
95
const options = getOptions()
106
logger.level = options.logLevel

test/browser/pages/login.test.ts

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { JSDOM } from "jsdom"
2+
import { LocationLike } from "../../unit/util.test"
3+
4+
describe("login", () => {
5+
// TODO test for when el is defined
6+
describe("there is an element with id 'base'", () => {
7+
// let initialDom: Document
8+
beforeEach(() => {
9+
const dom = new JSDOM()
10+
// initialDom = dom.window.document
11+
global.document = dom.window.document
12+
13+
const location: LocationLike = {
14+
pathname: "/healthz",
15+
origin: "http://localhost:8080",
16+
}
17+
18+
global.location = location as Location
19+
})
20+
afterEach(() => {
21+
// Reset the global.document
22+
global.document = undefined as any as Document
23+
global.location = undefined as any as Location
24+
})
25+
it("should set the value to options.base", () => {
26+
// Mock getElementById
27+
const spy = jest.spyOn(document, "getElementById")
28+
// Create a fake element and set the attribute
29+
const mockElement = document.createElement("input")
30+
mockElement.setAttribute("id", "base")
31+
mockElement.setAttribute(
32+
"data-settings",
33+
'{"base":"./hello-world","csStaticBase":"./static/development/Users/jp/Dev/code-server","logLevel":2,"disableTelemetry":false,"disableUpdateCheck":false}',
34+
)
35+
document.body.appendChild(mockElement)
36+
spy.mockImplementation(() => mockElement)
37+
// Load file
38+
require("../../../src/browser/pages/login")
39+
// Called once by getOptions and the second in
40+
41+
const el: HTMLInputElement | null = document.querySelector("input#base")
42+
expect(el?.value).toBe("/hello-world")
43+
})
44+
})
45+
46+
describe("there is no element with id 'base'", () => {
47+
let initialDom: Document
48+
beforeEach(() => {
49+
const dom = new JSDOM()
50+
initialDom = dom.window.document
51+
global.document = dom.window.document
52+
53+
const location: LocationLike = {
54+
pathname: "/healthz",
55+
origin: "http://localhost:8080",
56+
}
57+
58+
global.location = location as Location
59+
})
60+
afterEach(() => {
61+
// Reset the global.document
62+
global.document = undefined as any as Document
63+
global.location = undefined as any as Location
64+
})
65+
66+
it("should not change the DOM", () => {
67+
// Load file
68+
require("../../../src/browser/pages/login")
69+
const currentDom = global.document
70+
expect(initialDom).toBe(currentDom)
71+
})
72+
})
73+
})

0 commit comments

Comments
 (0)