Add build via esbuild

This configures the existing build tasks to use esbuild by default. If
using the plain files is desired, passing `--bundle=false` will build
using plain files and still produce a runnable system.

This is only a basic build; a more efficient build is provided later
when gulp is replaced by hereby.
This commit is contained in:
Jake Bailey
2022-09-13 16:21:03 -07:00
parent 36e29448e9
commit 4139807e75
47 changed files with 955 additions and 409 deletions

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/cancellationToken",
"module": "commonjs",
"types": [
"node"

View File

@@ -1463,6 +1463,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({
@@ -1521,14 +1528,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,
@@ -1567,7 +1567,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.
@@ -1642,7 +1645,7 @@ export let sys: System = (() => {
function cleanupPaths(profile: import("inspector").Profiler.Profile) {
let externalFileCounter = 0;
const remappedPaths = new Map<string, string>();
const normalizedDir = normalizeSlashes(__dirname);
const normalizedDir = normalizeSlashes(_path.dirname(executingFilePath));
// Windows rooted dir names need an extra `/` prepended to be valid file:/// urls
const fileUrlRoot = `file://${getRootLength(normalizedDir) === 1 ? "" : "/"}${normalizedDir}`;
for (const node of profile.nodes) {

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/compiler",
"types": ["node"]
},

View File

@@ -1,3 +0,0 @@
/* Generated file to emulate the Debug namespace. */
export * from "../dbg";

View File

@@ -1,7 +1,3 @@
import * as Debug from "./_namespaces/Debug";
/// <reference lib="es2019" />
interface Node {
kind: number;
}
@@ -510,9 +506,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;
}

View File

@@ -3,7 +3,6 @@
"compilerOptions": {
"target": "es2019",
"lib": ["es2019"],
"outDir": "../../built/local/debug"
},
"include": ["**/*"]
}

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/deprecatedCompat"
},
"references": [
{ "path": "../compiler" }

View File

@@ -1,3 +0,0 @@
/* Generated file to emulate the ts.server namespace. */
export * from "../dynamicImportCompat";

View File

@@ -1,4 +0,0 @@
/* Generated file to emulate the ts namespace. */
import * as server from "./ts.server";
export { server };

View File

@@ -1 +0,0 @@
export const dynamicImport = (id: string) => import(id);

View File

@@ -1,15 +0,0 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/dynamicImportCompat",
"rootDir": ".",
"target": "esnext",
"module": "esnext",
"lib": ["esnext"]
},
"files": [
"dynamicImportCompat.ts",
"_namespaces/ts.server.ts",
"_namespaces/ts.ts"
]
}

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/executeCommandLine"
},
"references": [

View File

@@ -4069,7 +4069,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.
@@ -4103,8 +4103,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`.

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/harness",
"types": [
"node", "mocha", "chai"
],

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/jsTyping",
"types": [
"node"
],

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/loggedIO",
"types": [
],
"lib": [

View File

@@ -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;

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/server",
"types": [
"node"
]

View File

@@ -17,6 +17,7 @@ export * from "../transpile";
export * from "../services";
export * from "../transform";
export * from "../shims";
export * from "../globalThisShim";
import * as BreakpointResolver from "./ts.BreakpointResolver";
export { BreakpointResolver };
import * as CallHierarchy from "./ts.CallHierarchy";

View File

@@ -1,9 +0,0 @@
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;
}

View File

@@ -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;
@@ -2922,18 +2922,14 @@ function isArgumentOfElementAccessExpression(node: Node) {
(node.parent as ElementAccessExpression).argumentExpression === node;
}
/// getDefaultLibraryFilePath
declare const __dirname: string;
/**
* Get the path of the default library files (lib.d.ts) as distributed with the typescript
* node package.
* The functionality is not supported if the ts module is consumed outside of a node module.
*/
export function getDefaultLibFilePath(options: CompilerOptions): string {
// Check __dirname is defined and that we are on a node.js system.
if (typeof __dirname !== "undefined") {
return combinePaths(__dirname, getDefaultLibFileName(options));
if (ts.sys) {
return combinePaths(getDirectoryPath(normalizePath(ts.sys.getExecutingFilePath())), getDefaultLibFileName(options));
}
throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. ");

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/services"
},
"references": [
{ "path": "../compiler" },

View File

@@ -12,6 +12,7 @@ export * from "../externalCompileRunner";
export * from "../test262Runner";
export * from "../runner";
// If running as emitted CJS, don't start executing the tests here; instead start in runner.ts.
// If running bundled, we want this to be here so that esbuild places the tests after runner.ts.
if (!__filename.endsWith("Harness.js")) {
require("../tests");

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/testRunner",
"types": [
"node", "mocha", "chai"
],

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/tsc"
},
"references": [
{ "path": "../compiler" },

View File

@@ -1,5 +1,8 @@
{
"compilerOptions": {
"rootDir": ".",
"outDir": "../built/local",
"pretty": true,
"lib": ["es2018"],
"target": "es2018",
@@ -11,6 +14,7 @@
"sourceMap": true,
"composite": true,
"noEmitOnError": true,
"emitDeclarationOnly": true,
"strictNullChecks": true,
"noImplicitAny": true,

View File

@@ -6,7 +6,6 @@
{ "path": "./compiler" },
{ "path": "./debug" },
{ "path": "./deprecatedCompat" },
{ "path": "./dynamicImportCompat" },
{ "path": "./executeCommandLine" },
{ "path": "./harness" },
{ "path": "./jsTyping" },

View File

@@ -13,7 +13,7 @@ import {
import {
ApplyCodeActionCommandResult, assertType, CharacterCodes, combinePaths, createQueue, Debug, directorySeparator,
DirectoryWatcherCallback, ESMap, FileWatcher, getDirectoryPath, getEntries, getNodeMajorVersion, getRootLength,
JsTyping, LanguageServiceMode, Map, MapLike, noop, noopFileWatcher, normalizeSlashes, resolveJSModule,
JsTyping, LanguageServiceMode, Map, MapLike, noop, noopFileWatcher, normalizePath, normalizeSlashes, resolveJSModule,
SortedReadonlyArray, startTracing, stripQuotes, sys, toFileNameLowerCase, tracing, TypeAcquisition,
validateLocaleAndSetLanguage, versionMajorMinor, WatchOptions,
} from "./_namespaces/ts";
@@ -193,6 +193,8 @@ export function initializeNodeSystem(): StartInput {
}
}
const libDirectory = getDirectoryPath(normalizePath(sys.getExecutingFilePath()));
const nodeVersion = getNodeMajorVersion();
// use watchGuard process on Windows when node version is 4 or later
const useWatchGuard = process.platform === "win32" && nodeVersion! >= 4;
@@ -227,7 +229,7 @@ export function initializeNodeSystem(): StartInput {
logger.info(`${cacheKey} for path ${path} not found in cache...`);
}
try {
const args = [combinePaths(__dirname, "watchGuard.js"), path];
const args = [combinePaths(libDirectory, "watchGuard.js"), path];
if (logger.hasLevel(LogLevel.verbose)) {
logger.info(`Starting ${process.execPath} with args:${stringifyIndented(args)}`);
}
@@ -326,7 +328,7 @@ export function initializeNodeSystem(): StartInput {
const unsubstitutedLogFileName = cmdLineLogFileName
? stripQuotes(cmdLineLogFileName)
: envLogOptions.logToFile
? envLogOptions.file || (__dirname + "/.log" + process.pid.toString())
? envLogOptions.file || (libDirectory + "/.log" + process.pid.toString())
: undefined;
const substitutedLogFileName = unsubstitutedLogFileName
@@ -526,8 +528,8 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
}
}
// TODO(jakebailey): fix this for module transform
this.installer = childProcess.fork(combinePaths(__dirname, "..", "typingsInstaller", "nodeTypingsInstaller.js"), args, { execArgv });
const typingsInstaller = combinePaths(getDirectoryPath(sys.getExecutingFilePath()), "typingsInstaller.js");
this.installer = childProcess.fork(typingsInstaller, args, { execArgv });
this.installer.on("message", m => this.handleMessage(m));
// We have to schedule this event to the next tick

View File

@@ -2,7 +2,6 @@
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/tsserver",
"types": [
"node"
]

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/tsserverlibrary"
},
"references": [
{ "path": "../compiler" },

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/typescript"
},
"references": [
{ "path": "../compiler" },

View File

@@ -11,7 +11,7 @@ import {
} from "./_namespaces/ts.server";
import {
combinePaths, createGetCanonicalFileName, Debug, ESMap, forEachAncestorDirectory, getDirectoryPath, getEntries, Map,
MapLike, normalizeSlashes, stringContains, sys, toPath, version,
MapLike, normalizePath, normalizeSlashes, stringContains, sys, toPath, version,
} from "./_namespaces/ts";
class FileLog implements Log {
@@ -89,11 +89,12 @@ export class NodeTypingsInstaller extends TypingsInstaller {
private delayedInitializationError: InitializationFailedResponse | undefined;
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, typesMapLocation: string, npmLocation: string | undefined, validateDefaultNpmLocation: boolean, throttleLimit: number, log: Log) {
const libDirectory = getDirectoryPath(normalizePath(sys.getExecutingFilePath()));
super(
sys,
globalTypingsCacheLocation,
typingSafeListLocation ? toPath(typingSafeListLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
typesMapLocation ? toPath(typesMapLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typesMap.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
typingSafeListLocation ? toPath(typingSafeListLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typingSafeList.json", libDirectory, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
typesMapLocation ? toPath(typesMapLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typesMap.json", libDirectory, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
throttleLimit,
log);
this.npmPath = npmLocation !== undefined ? npmLocation : getDefaultNPMLocation(process.argv[0], validateDefaultNpmLocation, this.installTypingHost);

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/typingsInstaller",
"types": [
"node"
],

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/typingsInstallerCore",
"types": [
"node"
],

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/watchGuard",
"types": [
"node"
],

View File

@@ -1,7 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outDir": "../../built/local/webServer",
"types": [
"node"
]

View File

@@ -1,8 +1,6 @@
/// <reference lib="dom" />
/// <reference lib="webworker.importscripts" />
import * as server from "./_namespaces/ts.server";
import {
indent, Logger, LogLevel, ModuleImportResult, Msg, nowString, nullTypingsInstaller, protocol,
ServerCancellationToken, ServerHost, Session, SessionOptions,
@@ -127,16 +125,11 @@ export class MainProcessLogger extends BaseLogger {
}
}
// Attempt to load `dynamicImport`
if (typeof importScripts === "function") {
try {
// NOTE: importScripts is synchronous
importScripts("dynamicImportCompat.js");
}
catch {
// ignored
}
}
/** @internal */
// eslint-disable-next-line prefer-const
export let dynamicImport = async (_id: string): Promise<any> => {
throw new Error("Dynamic import not implemented");
};
/** @internal */
export function createWebSystem(host: WebHost, args: string[], getExecutingFilePath: () => string): ServerHost {
@@ -145,16 +138,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