Skip to content

Commit

Permalink
Add build via esbuild
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jakebailey committed Sep 16, 2022
1 parent d5e59b6 commit 4173341
Show file tree
Hide file tree
Showing 24 changed files with 756 additions and 255 deletions.
307 changes: 125 additions & 182 deletions Gulpfile.js

Large diffs are not rendered by default.

549 changes: 549 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"chalk": "^4.1.2",
"del": "^6.1.1",
"diff": "^5.1.0",
"esbuild": "^0.15.7",
"eslint": "^8.22.0",
"eslint-formatter-autolinkable-stylish": "^1.2.0",
"eslint-plugin-import": "^2.26.0",
Expand Down
4 changes: 3 additions & 1 deletion scripts/build/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const ci = ["1", "true"].includes(process.env.CI);

/** @type {CommandLineOptions} */
module.exports = minimist(process.argv.slice(2), {
boolean: ["dirty", "light", "colors", "lkg", "soft", "fix", "failed", "keepFailed", "force", "built", "ci"],
boolean: ["dirty", "light", "colors", "lkg", "soft", "fix", "failed", "keepFailed", "force", "built", "ci", "bundle"],
string: ["browser", "tests", "break", "host", "reporter", "stackTraceLimit", "timeout", "shards", "shardId"],
alias: {
/* eslint-disable quote-props */
Expand Down Expand Up @@ -41,6 +41,7 @@ module.exports = minimist(process.argv.slice(2), {
dirty: false,
built: false,
ci,
bundle: true
}
});

Expand Down Expand Up @@ -69,6 +70,7 @@ if (module.exports.built) {
* @property {boolean} failed
* @property {boolean} keepFailed
* @property {boolean} ci
* @property {boolean} bundle
*
* @typedef {import("minimist").ParsedArgs & TypedOptions} CommandLineOptions
*/
Expand Down
22 changes: 11 additions & 11 deletions scripts/build/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,17 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode)
errorStatus = exitCode;
error = new Error(`Process exited with status code ${errorStatus}.`);
}
else if (cmdLineOptions.ci) {
// finally, do a sanity check and build the compiler with the built version of itself
log.info("Starting sanity check build...");
// Cleanup everything except lint rules (we'll need those later and would rather not waste time rebuilding them)
await exec("gulp", ["clean-tsc", "clean-services", "clean-tsserver", "clean-lssl", "clean-tests"]);
const { exitCode } = await exec("gulp", ["local", "--lkg=false"]);
if (exitCode !== 0) {
errorStatus = exitCode;
error = new Error(`Sanity check build process exited with status code ${errorStatus}.`);
}
}
// else if (cmdLineOptions.ci) {
// // finally, do a sanity check and build the compiler with the built version of itself
// log.info("Starting sanity check build...");
// // Cleanup everything except lint rules (we'll need those later and would rather not waste time rebuilding them)
// await exec("gulp", ["clean-tsc", "clean-services", "clean-tsserver", "clean-lssl", "clean-tests"]);
// const { exitCode } = await exec("gulp", ["local", "--lkg=false"]);
// if (exitCode !== 0) {
// errorStatus = exitCode;
// error = new Error(`Sanity check build process exited with status code ${errorStatus}.`);
// }
// }
}
catch (e) {
errorStatus = undefined;
Expand Down
4 changes: 3 additions & 1 deletion src/cancellationToken/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/cancellationToken",
"outDir": "../../built/local",
"tsBuildInfoFile": "../../built/local/cancellationToken.tsbuildinfo",
"rootDir": ".",
"module": "commonjs",
"types": [
"node"
Expand Down
21 changes: 12 additions & 9 deletions src/compiler/sys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,13 @@ export let sys: System = (() => {
const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
const fsRealpath = !!_fs.realpathSync.native ? process.platform === "win32" ? fsRealPathHandlingLongPath : _fs.realpathSync.native : _fs.realpathSync;

// If our filename is "sys.js", then we are executing unbundled on the raw tsc output.
// In that case, simulate a faked path in the directory where a bundle would normally
// appear (e.g. the directory containing lib.*.d.ts files).
//
// Note that if we ever emit as files like cjs/mjs, this check will be wrong.
const executingFilePath = __filename.endsWith("sys.js") ? _path.join(_path.dirname(__dirname), "__fake__.js") : __filename;

const fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
const getCurrentDirectory = memoize(() => process.cwd());
const { watchFile, watchDirectory } = createSystemWatchFunctions({
Expand Down Expand Up @@ -1525,14 +1532,7 @@ export let sys: System = (() => {
}
},
getExecutingFilePath() {
// This function previously returned a path like `built/local/tsc.js`.
// Now, with a module output, this file is now `built/local/compiler/sys.js`.
// We want to return a file that looks like the old one, so that callers
// can locate other assets like the lib.d.ts files.
//
// TODO(jakebailey): replace this function with one that returns the path
// to the lib folder (or package path)?.
return _path.join(_path.dirname(__dirname), "fake.js");
return executingFilePath;
},
getCurrentDirectory,
getDirectories,
Expand Down Expand Up @@ -1571,7 +1571,10 @@ export let sys: System = (() => {
debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || some(process.execArgv as string[], arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)),
tryEnableSourceMapsForHost() {
try {
require("source-map-support").install();
// Trick esbuild into not eagerly resolving a path to a JS file.
// See: https://github.com/evanw/esbuild/issues/1958
const moduleName = "source-map-support" as const;
(require(moduleName) as typeof import("source-map-support")).install();
}
catch {
// Could not enable source maps.
Expand Down
3 changes: 0 additions & 3 deletions src/debug/_namespaces/Debug.ts

This file was deleted.

8 changes: 0 additions & 8 deletions src/debug/dbg.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import * as Debug from "./_namespaces/Debug";

/// <reference lib="es2019" />

interface Node {
Expand Down Expand Up @@ -510,9 +508,3 @@ export function formatControlFlowGraph(flowNode: FlowNode) {
return s;
}
}

// Export as a module. NOTE: Can't use module exports as this is built using --outFile
declare const module: { exports: {} };
if (typeof module !== "undefined" && module.exports) {
module.exports = Debug;
}
1 change: 0 additions & 1 deletion src/debug/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@
},
"files": [
"dbg.ts",
"_namespaces/Debug.ts"
]
}
3 changes: 0 additions & 3 deletions src/dynamicImportCompat/_namespaces/ts.server.ts

This file was deleted.

4 changes: 0 additions & 4 deletions src/dynamicImportCompat/_namespaces/ts.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/dynamicImportCompat/dynamicImportCompat.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const dynamicImport = (id: string) => import(id);
(globalThis as any).dynamicImport = (id: string) => import(id);
8 changes: 4 additions & 4 deletions src/dynamicImportCompat/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/dynamicImportCompat",
"outDir": "../../built/local",
"tsBuildInfoFile": "../../built/local/dynamicImportCompat.tsbuildinfo",
"rootDir": ".",
"target": "esnext",
"module": "esnext",
"lib": ["esnext"]
"lib": ["esnext"],
"emitDeclarationOnly": false
},
"files": [
"dynamicImportCompat.ts",
"_namespaces/ts.server.ts",
"_namespaces/ts.ts"
]
}
6 changes: 3 additions & 3 deletions src/harness/fourslashImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4059,7 +4059,7 @@ export function runFourSlashTestContent(basePath: string, testType: FourSlashTes
function runCode(code: string, state: TestState, fileName: string): void {
// Compile and execute the test
const generatedFile = ts.changeExtension(fileName, ".js");
const wrappedCode = `(function(test, goTo, plugins, verify, edit, debug, format, cancellation, classification, completion, verifyOperationIsCancelled) {${code}\n//# sourceURL=${ts.getBaseFileName(generatedFile)}\n})`;
const wrappedCode = `(function(ts, test, goTo, config, verify, edit, debug, format, cancellation, classification, completion, verifyOperationIsCancelled, ignoreInterpolations) {${code}\n//# sourceURL=${ts.getBaseFileName(generatedFile)}\n})`;

type SourceMapSupportModule = typeof import("source-map-support") & {
// TODO(rbuckton): This is missing from the DT definitions and needs to be added.
Expand Down Expand Up @@ -4093,8 +4093,8 @@ function runCode(code: string, state: TestState, fileName: string): void {
const format = new FourSlashInterface.Format(state);
const cancellation = new FourSlashInterface.Cancellation(state);
// eslint-disable-next-line no-eval
const f = eval(wrappedCode);
f(test, goTo, config, verify, edit, debug, format, cancellation, FourSlashInterface.classification, FourSlashInterface.Completion, verifyOperationIsCancelled);
const f = (0, eval)(wrappedCode);
f(ts, test, goTo, config, verify, edit, debug, format, cancellation, FourSlashInterface.classification, FourSlashInterface.Completion, verifyOperationIsCancelled, ignoreInterpolations);
}
catch (err) {
// ensure 'source-map-support' is triggered while we still have the handler attached by accessing `error.stack`.
Expand Down
8 changes: 4 additions & 4 deletions src/server/scriptVersionCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,16 @@ class TextChange {

/** @internal */
export class ScriptVersionCache {
private static readonly changeNumberThreshold = 8;
private static readonly changeLengthThreshold = 256;
private static readonly maxVersions = 8;

private changes: TextChange[] = [];
private readonly versions: LineIndexSnapshot[] = new Array<LineIndexSnapshot>(ScriptVersionCache.maxVersions);
private minVersion = 0; // no versions earlier than min version will maintain change history

private currentVersion = 0;

private static readonly changeNumberThreshold = 8;
private static readonly changeLengthThreshold = 256;
private static readonly maxVersions = 8;

private versionToIndex(version: number) {
if (version < this.minVersion || version > this.currentVersion) {
return undefined;
Expand Down
2 changes: 2 additions & 0 deletions src/services/_namespaces/ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export * from "../transpile";
export * from "../services";
export * from "../transform";
export * from "../shims";
export * from "../globalThisShim";
export * from "../exportAsModule";
import * as BreakpointResolver from "./ts.BreakpointResolver";
export { BreakpointResolver };
import * as CallHierarchy from "./ts.CallHierarchy";
Expand Down
20 changes: 16 additions & 4 deletions src/services/exportAsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,19 @@ import * as ts from "./_namespaces/ts";
// Here we expose the TypeScript services as an external module
// so that it may be consumed easily like a node module.
// @ts-ignore
/** @internal */ declare const module: { exports: {} };
if (typeof module !== "undefined" && module.exports) {
module.exports = ts;
}
// /** @internal */ declare const module: { exports: {} };
// if (typeof module !== "undefined" && module.exports) {
// module.exports = ts;
// }

// If we are bundled with esbuild via IIFE, this is a hacky way to jump out of
// its module system and conditionally export to CJS in the bundle.
//
// We may want to do something different for this.

// eslint-disable-next-line no-eval
// eval("(ts) => { if (typeof module !== 'undefined' && module.exports) module.exports = ts }")(ts);

// TODO(jakebailey): remove; this is just here and ignored for now.
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
ts;
4 changes: 2 additions & 2 deletions src/services/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,9 +484,9 @@ class IdentifierObject extends TokenOrIdentifierObject implements Identifier {
}
IdentifierObject.prototype.kind = SyntaxKind.Identifier;
class PrivateIdentifierObject extends TokenOrIdentifierObject implements PrivateIdentifier {
public kind!: SyntaxKind.PrivateIdentifier;
public kind: SyntaxKind.PrivateIdentifier = SyntaxKind.PrivateIdentifier;
public escapedText!: __String;
public symbol!: Symbol;
// public symbol!: Symbol;
_primaryExpressionBrand: any;
_memberExpressionBrand: any;
_leftHandSideExpressionBrand: any;
Expand Down
5 changes: 5 additions & 0 deletions src/testRunner/_namespaces/Harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ export * from "../compilerRunner";
export * from "../externalCompileRunner";
export * from "../test262Runner";
export * from "../runner";


// Must be after runner.
// NOTE: if emitting CJS, comment this out, and uncomment the one in runner.ts.
import "./tests";
3 changes: 2 additions & 1 deletion src/testRunner/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,5 @@ function startTestEnvironment() {
startTestEnvironment();

// This brings in all of the unittests.
import "./_namespaces/tests";
// NOTE: if emitting CJS, uncomment this, and comment out the one in Harness.ts.
// import "./_namespaces/tests";
1 change: 1 addition & 0 deletions src/tsconfig-base.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"sourceMap": true,
"composite": true,
"noEmitOnError": true,
"emitDeclarationOnly": true,

"strictNullChecks": true,
"noImplicitAny": true,
Expand Down
2 changes: 1 addition & 1 deletion src/watchGuard/watchGuard.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="node" />

import * as fs from "fs";
import fs = require("fs");

if (process.argv.length < 3) {
process.exit(1);
Expand Down
23 changes: 11 additions & 12 deletions src/webServer/webServer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as server from "./_namespaces/ts.server";
import {
indent, Logger, LogLevel, ModuleImportResult, Msg, nowString, nullTypingsInstaller, protocol,
ServerCancellationToken, ServerHost, Session, SessionOptions,
Expand Down Expand Up @@ -126,11 +125,21 @@ export class MainProcessLogger extends BaseLogger {
}
}

let dynamicImport = async (_id: string): Promise<any> => {
throw new Error("Dynamic import not implemented");
};

// eslint-disable-next-line @typescript-eslint/naming-convention
declare const __import__: (_id: string) => Promise<any>;

// Attempt to load `dynamicImport`
if (typeof importScripts === "function") {
try {
// NOTE: importScripts is synchronous
importScripts("dynamicImportCompat.js");
// importScripts("dynamicImportCompat.js");
// dynamicImport = (globalThis as any).dynamicImport;
// delete (globalThis as any).dynamicImport;
dynamicImport = __import__;
}
catch {
// ignored
Expand All @@ -144,16 +153,6 @@ export function createWebSystem(host: WebHost, args: string[], getExecutingFileP
// Later we could map ^memfs:/ to do something special if we want to enable more functionality like module resolution or something like that
const getWebPath = (path: string) => startsWith(path, directorySeparator) ? path.replace(directorySeparator, getExecutingDirectoryPath()) : undefined;

const dynamicImport = async (id: string): Promise<any> => {
const serverDynamicImport: ((id: string) => Promise<any>) | undefined = (server as any).dynamicImport;
// Use syntactic dynamic import first, if available
if (serverDynamicImport) {
return serverDynamicImport(id);
}

throw new Error("Dynamic import not implemented");
};

return {
args,
newLine: "\r\n", // This can be configured by clients
Expand Down

0 comments on commit 4173341

Please sign in to comment.