Merge pull request #3658 from cdr/jsjoeio/migrate-parcel

chore(dev): migrate away from parcel and replace with browserify
This commit is contained in:
Joe Previte 2021-06-28 12:04:10 -07:00 committed by GitHub
commit e1d291e59c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 581 additions and 3935 deletions

21
.github/codecov.yml vendored Normal file
View File

@ -0,0 +1,21 @@
codecov:
require_ci_to_pass: yes
allow_coverage_offsets: True
coverage:
precision: 2
round: down
range: "70...100"
parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no
comment:
layout: "reach,diff,flags,files,footer"
behavior: default
require_changes: no

1
.gitignore vendored
View File

@ -1,6 +1,5 @@
.tsbuildinfo .tsbuildinfo
.cache .cache
dist*
/out*/ /out*/
release/ release/
release-npm-package/ release-npm-package/

View File

@ -65,6 +65,7 @@ VS Code v0.00.0
### Development ### Development
- fix(publish): update cdrci fork in brew-bump.sh #3468 @jsjoeio - fix(publish): update cdrci fork in brew-bump.sh #3468 @jsjoeio
- chore(dev): migrate away from parcel #3578 @jsjoeio
## 3.10.2 ## 3.10.2

View File

@ -3,9 +3,6 @@ set -euo pipefail
# Builds code-server into out and the frontend into dist. # Builds code-server into out and the frontend into dist.
# MINIFY controls whether parcel minifies dist.
MINIFY=${MINIFY-true}
main() { main() {
cd "$(dirname "${0}")/../.." cd "$(dirname "${0}")/../.."
@ -32,14 +29,9 @@ main() {
set -e set -e
fi fi
parcel build \ yarn browserify out/browser/register.js -o out/browser/register.browserified.js
--public-url "." \ yarn browserify out/browser/pages/login.js -o out/browser/pages/login.browserified.js
--out-dir dist \ yarn browserify out/browser/pages/vscode.js -o out/browser/pages/vscode.browserified.js
$([[ $MINIFY ]] || echo --no-minify) \
src/browser/register.ts \
src/browser/serviceWorker.ts \
src/browser/pages/login.ts \
src/browser/pages/vscode.ts
} }
main "$@" main "$@"

View File

@ -28,13 +28,14 @@ main() {
} }
bundle_code_server() { bundle_code_server() {
rsync out dist "$RELEASE_PATH" rsync out "$RELEASE_PATH"
# For source maps and images. # For source maps and images.
mkdir -p "$RELEASE_PATH/src/browser" mkdir -p "$RELEASE_PATH/src/browser"
rsync src/browser/media/ "$RELEASE_PATH/src/browser/media" rsync src/browser/media/ "$RELEASE_PATH/src/browser/media"
mkdir -p "$RELEASE_PATH/src/browser/pages" mkdir -p "$RELEASE_PATH/src/browser/pages"
rsync src/browser/pages/*.html "$RELEASE_PATH/src/browser/pages" rsync src/browser/pages/*.html "$RELEASE_PATH/src/browser/pages"
rsync src/browser/pages/*.css "$RELEASE_PATH/src/browser/pages"
rsync src/browser/robots.txt "$RELEASE_PATH/src/browser" rsync src/browser/robots.txt "$RELEASE_PATH/src/browser"
# Add typings for plugins # Add typings for plugins

View File

@ -1,5 +1,6 @@
import browserify from "browserify"
import * as cp from "child_process" import * as cp from "child_process"
import Bundler from "parcel-bundler" import * as fs from "fs"
import * as path from "path" import * as path from "path"
async function main(): Promise<void> { async function main(): Promise<void> {
@ -40,7 +41,6 @@ class Watcher {
const plugin = process.env.PLUGIN_DIR const plugin = process.env.PLUGIN_DIR
? cp.spawn("yarn", ["build", "--watch"], { cwd: process.env.PLUGIN_DIR }) ? cp.spawn("yarn", ["build", "--watch"], { cwd: process.env.PLUGIN_DIR })
: undefined : undefined
const bundler = this.createBundler()
const cleanup = (code?: number | null): void => { const cleanup = (code?: number | null): void => {
Watcher.log("killing vs code watcher") Watcher.log("killing vs code watcher")
@ -63,7 +63,7 @@ class Watcher {
server.kill() server.kill()
} }
Watcher.log("killing bundler") Watcher.log("killing watch")
process.exit(code || 0) process.exit(code || 0)
} }
@ -84,16 +84,6 @@ class Watcher {
cleanup(code) cleanup(code)
}) })
} }
const bundle = bundler.bundle().catch(() => {
Watcher.log("parcel watcher terminated unexpectedly")
cleanup(1)
})
bundler.on("buildEnd", () => {
console.log("[parcel] bundled")
})
bundler.on("buildError", (error) => {
console.error("[parcel]", error)
})
vscode.stderr.on("data", (d) => process.stderr.write(d)) vscode.stderr.on("data", (d) => process.stderr.write(d))
tsc.stderr.on("data", (d) => process.stderr.write(d)) tsc.stderr.on("data", (d) => process.stderr.write(d))
@ -101,6 +91,12 @@ class Watcher {
plugin.stderr.on("data", (d) => process.stderr.write(d)) plugin.stderr.on("data", (d) => process.stderr.write(d))
} }
const browserFiles = [
path.join(this.rootPath, "out/browser/register.js"),
path.join(this.rootPath, "out/browser/pages/login.js"),
path.join(this.rootPath, "out/browser/pages/vscode.js"),
]
// From https://github.com/chalk/ansi-regex // From https://github.com/chalk/ansi-regex
const pattern = [ const pattern = [
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
@ -143,7 +139,7 @@ class Watcher {
startingVscode = true startingVscode = true
} else if (startingVscode && line.includes("Finished compilation")) { } else if (startingVscode && line.includes("Finished compilation")) {
if (startedVscode) { if (startedVscode) {
bundle.then(restartServer) restartServer()
} }
startedVscode = true startedVscode = true
} }
@ -155,7 +151,8 @@ class Watcher {
console.log("[tsc]", original) console.log("[tsc]", original)
} }
if (line.includes("Watching for file changes")) { if (line.includes("Watching for file changes")) {
bundle.then(restartServer) bundleBrowserCode(browserFiles)
restartServer()
} }
}) })
@ -166,29 +163,26 @@ class Watcher {
console.log("[plugin]", original) console.log("[plugin]", original)
} }
if (line.includes("Watching for file changes")) { if (line.includes("Watching for file changes")) {
bundle.then(restartServer) restartServer()
} }
}) })
} }
} }
}
private createBundler(out = "dist"): Bundler { function bundleBrowserCode(inputFiles: string[]) {
return new Bundler( console.log(`[browser] bundling...`)
[ inputFiles.forEach(async (path: string) => {
path.join(this.rootPath, "src/browser/register.ts"), const outputPath = path.replace(".js", ".browserified.js")
path.join(this.rootPath, "src/browser/serviceWorker.ts"), browserify()
path.join(this.rootPath, "src/browser/pages/login.ts"), .add(path)
path.join(this.rootPath, "src/browser/pages/vscode.ts"), .bundle()
], .on("error", function (error: Error) {
{ console.error(error.toString())
outDir: path.join(this.rootPath, out), })
cacheDir: path.join(this.rootPath, ".cache"), .pipe(fs.createWriteStream(outputPath))
minify: !!process.env.MINIFY, })
logLevel: 1, console.log(`[browser] done bundling`)
publicUrl: ".",
},
)
}
} }
main() main()

View File

@ -29,7 +29,7 @@
"lint": "./ci/dev/lint.sh", "lint": "./ci/dev/lint.sh",
"test": "echo 'Run yarn test:unit or yarn test:e2e' && exit 1", "test": "echo 'Run yarn test:unit or yarn test:e2e' && exit 1",
"ci": "./ci/dev/ci.sh", "ci": "./ci/dev/ci.sh",
"watch": "VSCODE_IPC_HOOK_CLI= NODE_OPTIONS=--max_old_space_size=32384 ts-node ./ci/dev/watch.ts", "watch": "VSCODE_IPC_HOOK_CLI= NODE_OPTIONS='--max_old_space_size=32384 --trace-warnings' ts-node ./ci/dev/watch.ts",
"icons": "./ci/dev/gen_icons.sh", "icons": "./ci/dev/gen_icons.sh",
"coverage": "codecov" "coverage": "codecov"
}, },
@ -37,13 +37,13 @@
"devDependencies": { "devDependencies": {
"@schemastore/package": "^0.0.6", "@schemastore/package": "^0.0.6",
"@types/body-parser": "^1.19.0", "@types/body-parser": "^1.19.0",
"@types/browserify": "^12.0.36",
"@types/compression": "^1.7.0", "@types/compression": "^1.7.0",
"@types/cookie-parser": "^1.4.2", "@types/cookie-parser": "^1.4.2",
"@types/express": "^4.17.8", "@types/express": "^4.17.8",
"@types/http-proxy": "^1.17.4", "@types/http-proxy": "^1.17.4",
"@types/js-yaml": "^4.0.0", "@types/js-yaml": "^4.0.0",
"@types/node": "^14.17.1", "@types/node": "^14.17.1",
"@types/parcel-bundler": "^1.12.1",
"@types/pem": "^1.9.5", "@types/pem": "^1.9.5",
"@types/proxy-from-env": "^1.0.1", "@types/proxy-from-env": "^1.0.1",
"@types/safe-compare": "^1.1.0", "@types/safe-compare": "^1.1.0",
@ -56,6 +56,7 @@
"@typescript-eslint/eslint-plugin": "^4.7.0", "@typescript-eslint/eslint-plugin": "^4.7.0",
"@typescript-eslint/parser": "^4.7.0", "@typescript-eslint/parser": "^4.7.0",
"audit-ci": "^4.0.0", "audit-ci": "^4.0.0",
"browserify": "^17.0.0",
"codecov": "^3.8.1", "codecov": "^3.8.1",
"doctoc": "^2.0.0", "doctoc": "^2.0.0",
"eslint": "^7.7.0", "eslint": "^7.7.0",
@ -64,7 +65,6 @@
"eslint-plugin-import": "^2.18.2", "eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.0", "eslint-plugin-prettier": "^3.1.0",
"leaked-handles": "^5.2.0", "leaked-handles": "^5.2.0",
"parcel-bundler": "^1.12.5",
"prettier": "^2.2.1", "prettier": "^2.2.1",
"prettier-plugin-sh": "^0.7.1", "prettier-plugin-sh": "^0.7.1",
"shellcheck": "^1.0.0", "shellcheck": "^1.0.0",
@ -79,9 +79,6 @@
"doctoc/underscore": "^1.13.1", "doctoc/underscore": "^1.13.1",
"doctoc/**/trim": "^1.0.0", "doctoc/**/trim": "^1.0.0",
"postcss": "^8.2.1", "postcss": "^8.2.1",
"parcel-bundler/cssnano": "^5.0.2",
"parcel-bundler/ws": "^7.4.6",
"parcel-bundler/htmlnano/uncss/jsdom/ws": "^7.4.6",
"browserslist": "^4.16.5", "browserslist": "^4.16.5",
"safe-buffer": "^5.1.1", "safe-buffer": "^5.1.1",
"vfile-message": "^2.0.2" "vfile-message": "^2.0.2"

View File

@ -16,7 +16,8 @@
<link rel="manifest" href="{{CS_STATIC_BASE}}/src/browser/media/manifest.json" crossorigin="use-credentials" /> <link rel="manifest" href="{{CS_STATIC_BASE}}/src/browser/media/manifest.json" crossorigin="use-credentials" />
<link rel="apple-touch-icon" sizes="192x192" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-192.png" /> <link rel="apple-touch-icon" sizes="192x192" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-192.png" />
<link rel="apple-touch-icon" sizes="512x512" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-512.png" /> <link rel="apple-touch-icon" sizes="512x512" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-512.png" />
<link href="{{CS_STATIC_BASE}}/dist/register.css" rel="stylesheet" /> <link href="{{CS_STATIC_BASE}}/src/browser/pages/global.css" rel="stylesheet" />
<link href="{{CS_STATIC_BASE}}/src/browser/pages/error.css" rel="stylesheet" />
<meta id="coder-options" data-settings="{{OPTIONS}}" /> <meta id="coder-options" data-settings="{{OPTIONS}}" />
</head> </head>
<body> <body>
@ -29,6 +30,6 @@
</div> </div>
</div> </div>
</div> </div>
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/register.js"></script> <script data-cfasync="false" src="{{CS_STATIC_BASE}}/out/browser/register.browserified.js"></script>
</body> </body>
</html> </html>

View File

@ -16,7 +16,8 @@
<link rel="manifest" href="{{CS_STATIC_BASE}}/src/browser/media/manifest.json" crossorigin="use-credentials" /> <link rel="manifest" href="{{CS_STATIC_BASE}}/src/browser/media/manifest.json" crossorigin="use-credentials" />
<link rel="apple-touch-icon" sizes="192x192" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-192.png" /> <link rel="apple-touch-icon" sizes="192x192" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-192.png" />
<link rel="apple-touch-icon" sizes="512x512" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-512.png" /> <link rel="apple-touch-icon" sizes="512x512" href="{{CS_STATIC_BASE}}/src/browser/media/pwa-icon-512.png" />
<link href="{{CS_STATIC_BASE}}/dist/register.css" rel="stylesheet" /> <link href="{{CS_STATIC_BASE}}/src/browser/pages/global.css" rel="stylesheet" />
<link href="{{CS_STATIC_BASE}}/src/browser/pages/login.css" rel="stylesheet" />
<meta id="coder-options" data-settings="{{OPTIONS}}" /> <meta id="coder-options" data-settings="{{OPTIONS}}" />
</head> </head>
<body> <body>
@ -48,6 +49,5 @@
</div> </div>
</div> </div>
</body> </body>
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/register.js"></script> <script data-cfasync="false" src="{{CS_STATIC_BASE}}/out/browser/pages/login.browserified.js"></script>
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/pages/login.js"></script>
</html> </html>

View File

@ -1,4 +1,5 @@
import { getOptions } from "../../common/util" import { getOptions } from "../../common/util"
import "../register"
const options = getOptions() const options = getOptions()
const el = document.getElementById("base") as HTMLInputElement const el = document.getElementById("base") as HTMLInputElement

View File

@ -39,8 +39,7 @@
<body aria-label=""></body> <body aria-label=""></body>
<!-- Startup (do not modify order of script tags!) --> <!-- Startup (do not modify order of script tags!) -->
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/pages/vscode.js"></script> <script data-cfasync="false" src="{{CS_STATIC_BASE}}/out/browser/pages/vscode.browserified.js"></script>
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/dist/register.js"></script>
<script data-cfasync="false" src="{{CS_STATIC_BASE}}/lib/vscode/out/vs/loader.js"></script> <script data-cfasync="false" src="{{CS_STATIC_BASE}}/lib/vscode/out/vs/loader.js"></script>
<script> <script>
performance.mark("code/willLoadWorkbenchMain") performance.mark("code/willLoadWorkbenchMain")

View File

@ -1,4 +1,5 @@
import { getOptions } from "../../common/util" import { getOptions } from "../../common/util"
import "../register"
const options = getOptions() const options = getOptions()

View File

@ -1,10 +1,6 @@
import { logger } from "@coder/logger" import { logger } from "@coder/logger"
import { getOptions, normalize, logError } from "../common/util" import { getOptions, normalize, logError } from "../common/util"
import "./pages/error.css"
import "./pages/global.css"
import "./pages/login.css"
export async function registerServiceWorker(): Promise<void> { export async function registerServiceWorker(): Promise<void> {
const options = getOptions() const options = getOptions()
logger.level = options.logLevel logger.level = options.logLevel

View File

@ -0,0 +1,45 @@
import { JSDOM } from "jsdom"
import { LocationLike } from "../../unit/util.test"
describe("login", () => {
describe("there is an element with id 'base'", () => {
beforeEach(() => {
const dom = new JSDOM()
global.document = dom.window.document
const location: LocationLike = {
pathname: "/healthz",
origin: "http://localhost:8080",
}
global.location = location as Location
})
afterEach(() => {
// Reset the global.document
global.document = undefined as any as Document
global.location = undefined as any as Location
})
it("should set the value to options.base", () => {
// Mock getElementById
const spy = jest.spyOn(document, "getElementById")
// Create a fake element and set the attribute
const mockElement = document.createElement("input")
mockElement.setAttribute("id", "base")
const expected = {
base: "./hello-world",
csStaticBase: "./static/development/Users/jp/Dev/code-server",
logLevel: 2,
disableTelemetry: false,
disableUpdateCheck: false,
}
mockElement.setAttribute("data-settings", JSON.stringify(expected))
document.body.appendChild(mockElement)
spy.mockImplementation(() => mockElement)
// Load file
require("../../../src/browser/pages/login")
const el: HTMLInputElement | null = document.querySelector("input#base")
expect(el?.value).toBe("/hello-world")
})
})
})

View File

@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es5", "target": "es2020",
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"strict": true, "strict": true,
@ -8,7 +8,7 @@
"noUnusedLocals": true, "noUnusedLocals": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"outDir": "./out", "outDir": "./out",
"declaration": true, "declaration": false,
"experimentalDecorators": true, "experimentalDecorators": true,
"esModuleInterop": true, "esModuleInterop": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,

4338
yarn.lock

File diff suppressed because it is too large Load Diff