Skip to content

Commit 4173341

Browse files
committed
Add build via esbuild
This configures the existing build tasks to use esbuild by defualt. If using the plain files is desired, passing `--bundle=false` will build using plain files and still produce a runnable system.
1 parent d5e59b6 commit 4173341

File tree

24 files changed

+756
-255
lines changed

24 files changed

+756
-255
lines changed

Gulpfile.js

Lines changed: 125 additions & 182 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 549 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"chalk": "^4.1.2",
7070
"del": "^6.1.1",
7171
"diff": "^5.1.0",
72+
"esbuild": "^0.15.7",
7273
"eslint": "^8.22.0",
7374
"eslint-formatter-autolinkable-stylish": "^1.2.0",
7475
"eslint-plugin-import": "^2.26.0",

scripts/build/options.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const ci = ["1", "true"].includes(process.env.CI);
66

77
/** @type {CommandLineOptions} */
88
module.exports = minimist(process.argv.slice(2), {
9-
boolean: ["dirty", "light", "colors", "lkg", "soft", "fix", "failed", "keepFailed", "force", "built", "ci"],
9+
boolean: ["dirty", "light", "colors", "lkg", "soft", "fix", "failed", "keepFailed", "force", "built", "ci", "bundle"],
1010
string: ["browser", "tests", "break", "host", "reporter", "stackTraceLimit", "timeout", "shards", "shardId"],
1111
alias: {
1212
/* eslint-disable quote-props */
@@ -41,6 +41,7 @@ module.exports = minimist(process.argv.slice(2), {
4141
dirty: false,
4242
built: false,
4343
ci,
44+
bundle: true
4445
}
4546
});
4647

@@ -69,6 +70,7 @@ if (module.exports.built) {
6970
* @property {boolean} failed
7071
* @property {boolean} keepFailed
7172
* @property {boolean} ci
73+
* @property {boolean} bundle
7274
*
7375
* @typedef {import("minimist").ParsedArgs & TypedOptions} CommandLineOptions
7476
*/

scripts/build/tests.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,17 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode)
123123
errorStatus = exitCode;
124124
error = new Error(`Process exited with status code ${errorStatus}.`);
125125
}
126-
else if (cmdLineOptions.ci) {
127-
// finally, do a sanity check and build the compiler with the built version of itself
128-
log.info("Starting sanity check build...");
129-
// Cleanup everything except lint rules (we'll need those later and would rather not waste time rebuilding them)
130-
await exec("gulp", ["clean-tsc", "clean-services", "clean-tsserver", "clean-lssl", "clean-tests"]);
131-
const { exitCode } = await exec("gulp", ["local", "--lkg=false"]);
132-
if (exitCode !== 0) {
133-
errorStatus = exitCode;
134-
error = new Error(`Sanity check build process exited with status code ${errorStatus}.`);
135-
}
136-
}
126+
// else if (cmdLineOptions.ci) {
127+
// // finally, do a sanity check and build the compiler with the built version of itself
128+
// log.info("Starting sanity check build...");
129+
// // Cleanup everything except lint rules (we'll need those later and would rather not waste time rebuilding them)
130+
// await exec("gulp", ["clean-tsc", "clean-services", "clean-tsserver", "clean-lssl", "clean-tests"]);
131+
// const { exitCode } = await exec("gulp", ["local", "--lkg=false"]);
132+
// if (exitCode !== 0) {
133+
// errorStatus = exitCode;
134+
// error = new Error(`Sanity check build process exited with status code ${errorStatus}.`);
135+
// }
136+
// }
137137
}
138138
catch (e) {
139139
errorStatus = undefined;

src/cancellationToken/tsconfig.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{
22
"extends": "../tsconfig-base",
33
"compilerOptions": {
4-
"outDir": "../../built/local/cancellationToken",
4+
"outDir": "../../built/local",
5+
"tsBuildInfoFile": "../../built/local/cancellationToken.tsbuildinfo",
6+
"rootDir": ".",
57
"module": "commonjs",
68
"types": [
79
"node"

src/compiler/sys.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,13 @@ export let sys: System = (() => {
14661466
const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
14671467
const fsRealpath = !!_fs.realpathSync.native ? process.platform === "win32" ? fsRealPathHandlingLongPath : _fs.realpathSync.native : _fs.realpathSync;
14681468

1469+
// If our filename is "sys.js", then we are executing unbundled on the raw tsc output.
1470+
// In that case, simulate a faked path in the directory where a bundle would normally
1471+
// appear (e.g. the directory containing lib.*.d.ts files).
1472+
//
1473+
// Note that if we ever emit as files like cjs/mjs, this check will be wrong.
1474+
const executingFilePath = __filename.endsWith("sys.js") ? _path.join(_path.dirname(__dirname), "__fake__.js") : __filename;
1475+
14691476
const fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
14701477
const getCurrentDirectory = memoize(() => process.cwd());
14711478
const { watchFile, watchDirectory } = createSystemWatchFunctions({
@@ -1525,14 +1532,7 @@ export let sys: System = (() => {
15251532
}
15261533
},
15271534
getExecutingFilePath() {
1528-
// This function previously returned a path like `built/local/tsc.js`.
1529-
// Now, with a module output, this file is now `built/local/compiler/sys.js`.
1530-
// We want to return a file that looks like the old one, so that callers
1531-
// can locate other assets like the lib.d.ts files.
1532-
//
1533-
// TODO(jakebailey): replace this function with one that returns the path
1534-
// to the lib folder (or package path)?.
1535-
return _path.join(_path.dirname(__dirname), "fake.js");
1535+
return executingFilePath;
15361536
},
15371537
getCurrentDirectory,
15381538
getDirectories,
@@ -1571,7 +1571,10 @@ export let sys: System = (() => {
15711571
debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || some(process.execArgv as string[], arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)),
15721572
tryEnableSourceMapsForHost() {
15731573
try {
1574-
require("source-map-support").install();
1574+
// Trick esbuild into not eagerly resolving a path to a JS file.
1575+
// See: https://github.com/evanw/esbuild/issues/1958
1576+
const moduleName = "source-map-support" as const;
1577+
(require(moduleName) as typeof import("source-map-support")).install();
15751578
}
15761579
catch {
15771580
// Could not enable source maps.

src/debug/_namespaces/Debug.ts

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

src/debug/dbg.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import * as Debug from "./_namespaces/Debug";
2-
31
/// <reference lib="es2019" />
42

53
interface Node {
@@ -510,9 +508,3 @@ export function formatControlFlowGraph(flowNode: FlowNode) {
510508
return s;
511509
}
512510
}
513-
514-
// Export as a module. NOTE: Can't use module exports as this is built using --outFile
515-
declare const module: { exports: {} };
516-
if (typeof module !== "undefined" && module.exports) {
517-
module.exports = Debug;
518-
}

src/debug/tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@
77
},
88
"files": [
99
"dbg.ts",
10-
"_namespaces/Debug.ts"
1110
]
1211
}

src/dynamicImportCompat/_namespaces/ts.server.ts

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

src/dynamicImportCompat/_namespaces/ts.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const dynamicImport = (id: string) => import(id);
1+
(globalThis as any).dynamicImport = (id: string) => import(id);

src/dynamicImportCompat/tsconfig.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"extends": "../tsconfig-base",
33
"compilerOptions": {
4-
"outDir": "../../built/local/dynamicImportCompat",
4+
"outDir": "../../built/local",
5+
"tsBuildInfoFile": "../../built/local/dynamicImportCompat.tsbuildinfo",
56
"rootDir": ".",
67
"target": "esnext",
78
"module": "esnext",
8-
"lib": ["esnext"]
9+
"lib": ["esnext"],
10+
"emitDeclarationOnly": false
911
},
1012
"files": [
1113
"dynamicImportCompat.ts",
12-
"_namespaces/ts.server.ts",
13-
"_namespaces/ts.ts"
1414
]
1515
}

src/harness/fourslashImpl.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4059,7 +4059,7 @@ export function runFourSlashTestContent(basePath: string, testType: FourSlashTes
40594059
function runCode(code: string, state: TestState, fileName: string): void {
40604060
// Compile and execute the test
40614061
const generatedFile = ts.changeExtension(fileName, ".js");
4062-
const wrappedCode = `(function(test, goTo, plugins, verify, edit, debug, format, cancellation, classification, completion, verifyOperationIsCancelled) {${code}\n//# sourceURL=${ts.getBaseFileName(generatedFile)}\n})`;
4062+
const wrappedCode = `(function(ts, test, goTo, config, verify, edit, debug, format, cancellation, classification, completion, verifyOperationIsCancelled, ignoreInterpolations) {${code}\n//# sourceURL=${ts.getBaseFileName(generatedFile)}\n})`;
40634063

40644064
type SourceMapSupportModule = typeof import("source-map-support") & {
40654065
// TODO(rbuckton): This is missing from the DT definitions and needs to be added.
@@ -4093,8 +4093,8 @@ function runCode(code: string, state: TestState, fileName: string): void {
40934093
const format = new FourSlashInterface.Format(state);
40944094
const cancellation = new FourSlashInterface.Cancellation(state);
40954095
// eslint-disable-next-line no-eval
4096-
const f = eval(wrappedCode);
4097-
f(test, goTo, config, verify, edit, debug, format, cancellation, FourSlashInterface.classification, FourSlashInterface.Completion, verifyOperationIsCancelled);
4096+
const f = (0, eval)(wrappedCode);
4097+
f(ts, test, goTo, config, verify, edit, debug, format, cancellation, FourSlashInterface.classification, FourSlashInterface.Completion, verifyOperationIsCancelled, ignoreInterpolations);
40984098
}
40994099
catch (err) {
41004100
// ensure 'source-map-support' is triggered while we still have the handler attached by accessing `error.stack`.

src/server/scriptVersionCache.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,16 +255,16 @@ class TextChange {
255255

256256
/** @internal */
257257
export class ScriptVersionCache {
258+
private static readonly changeNumberThreshold = 8;
259+
private static readonly changeLengthThreshold = 256;
260+
private static readonly maxVersions = 8;
261+
258262
private changes: TextChange[] = [];
259263
private readonly versions: LineIndexSnapshot[] = new Array<LineIndexSnapshot>(ScriptVersionCache.maxVersions);
260264
private minVersion = 0; // no versions earlier than min version will maintain change history
261265

262266
private currentVersion = 0;
263267

264-
private static readonly changeNumberThreshold = 8;
265-
private static readonly changeLengthThreshold = 256;
266-
private static readonly maxVersions = 8;
267-
268268
private versionToIndex(version: number) {
269269
if (version < this.minVersion || version > this.currentVersion) {
270270
return undefined;

src/services/_namespaces/ts.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export * from "../transpile";
1717
export * from "../services";
1818
export * from "../transform";
1919
export * from "../shims";
20+
export * from "../globalThisShim";
21+
export * from "../exportAsModule";
2022
import * as BreakpointResolver from "./ts.BreakpointResolver";
2123
export { BreakpointResolver };
2224
import * as CallHierarchy from "./ts.CallHierarchy";

src/services/exportAsModule.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,19 @@ import * as ts from "./_namespaces/ts";
33
// Here we expose the TypeScript services as an external module
44
// so that it may be consumed easily like a node module.
55
// @ts-ignore
6-
/** @internal */ declare const module: { exports: {} };
7-
if (typeof module !== "undefined" && module.exports) {
8-
module.exports = ts;
9-
}
6+
// /** @internal */ declare const module: { exports: {} };
7+
// if (typeof module !== "undefined" && module.exports) {
8+
// module.exports = ts;
9+
// }
10+
11+
// If we are bundled with esbuild via IIFE, this is a hacky way to jump out of
12+
// its module system and conditionally export to CJS in the bundle.
13+
//
14+
// We may want to do something different for this.
15+
16+
// eslint-disable-next-line no-eval
17+
// eval("(ts) => { if (typeof module !== 'undefined' && module.exports) module.exports = ts }")(ts);
18+
19+
// TODO(jakebailey): remove; this is just here and ignored for now.
20+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
21+
ts;

src/services/services.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,9 +484,9 @@ class IdentifierObject extends TokenOrIdentifierObject implements Identifier {
484484
}
485485
IdentifierObject.prototype.kind = SyntaxKind.Identifier;
486486
class PrivateIdentifierObject extends TokenOrIdentifierObject implements PrivateIdentifier {
487-
public kind!: SyntaxKind.PrivateIdentifier;
487+
public kind: SyntaxKind.PrivateIdentifier = SyntaxKind.PrivateIdentifier;
488488
public escapedText!: __String;
489-
public symbol!: Symbol;
489+
// public symbol!: Symbol;
490490
_primaryExpressionBrand: any;
491491
_memberExpressionBrand: any;
492492
_leftHandSideExpressionBrand: any;

src/testRunner/_namespaces/Harness.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@ export * from "../compilerRunner";
1111
export * from "../externalCompileRunner";
1212
export * from "../test262Runner";
1313
export * from "../runner";
14+
15+
16+
// Must be after runner.
17+
// NOTE: if emitting CJS, comment this out, and uncomment the one in runner.ts.
18+
import "./tests";

src/testRunner/runner.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,5 @@ function startTestEnvironment() {
293293
startTestEnvironment();
294294

295295
// This brings in all of the unittests.
296-
import "./_namespaces/tests";
296+
// NOTE: if emitting CJS, uncomment this, and comment out the one in Harness.ts.
297+
// import "./_namespaces/tests";

src/tsconfig-base.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"sourceMap": true,
1111
"composite": true,
1212
"noEmitOnError": true,
13+
"emitDeclarationOnly": true,
1314

1415
"strictNullChecks": true,
1516
"noImplicitAny": true,

src/watchGuard/watchGuard.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference types="node" />
22

3-
import * as fs from "fs";
3+
import fs = require("fs");
44

55
if (process.argv.length < 3) {
66
process.exit(1);

src/webServer/webServer.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as server from "./_namespaces/ts.server";
21
import {
32
indent, Logger, LogLevel, ModuleImportResult, Msg, nowString, nullTypingsInstaller, protocol,
43
ServerCancellationToken, ServerHost, Session, SessionOptions,
@@ -126,11 +125,21 @@ export class MainProcessLogger extends BaseLogger {
126125
}
127126
}
128127

128+
let dynamicImport = async (_id: string): Promise<any> => {
129+
throw new Error("Dynamic import not implemented");
130+
};
131+
132+
// eslint-disable-next-line @typescript-eslint/naming-convention
133+
declare const __import__: (_id: string) => Promise<any>;
134+
129135
// Attempt to load `dynamicImport`
130136
if (typeof importScripts === "function") {
131137
try {
132138
// NOTE: importScripts is synchronous
133-
importScripts("dynamicImportCompat.js");
139+
// importScripts("dynamicImportCompat.js");
140+
// dynamicImport = (globalThis as any).dynamicImport;
141+
// delete (globalThis as any).dynamicImport;
142+
dynamicImport = __import__;
134143
}
135144
catch {
136145
// ignored
@@ -144,16 +153,6 @@ export function createWebSystem(host: WebHost, args: string[], getExecutingFileP
144153
// Later we could map ^memfs:/ to do something special if we want to enable more functionality like module resolution or something like that
145154
const getWebPath = (path: string) => startsWith(path, directorySeparator) ? path.replace(directorySeparator, getExecutingDirectoryPath()) : undefined;
146155

147-
const dynamicImport = async (id: string): Promise<any> => {
148-
const serverDynamicImport: ((id: string) => Promise<any>) | undefined = (server as any).dynamicImport;
149-
// Use syntactic dynamic import first, if available
150-
if (serverDynamicImport) {
151-
return serverDynamicImport(id);
152-
}
153-
154-
throw new Error("Dynamic import not implemented");
155-
};
156-
157156
return {
158157
args,
159158
newLine: "\r\n", // This can be configured by clients

0 commit comments

Comments
 (0)