diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf6cb012289dd..68f2cdb805817 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,13 @@ jobs: - "*" - lts/* - lts/-1 + bundle: + - "true" + include: + - node-version: "*" + bundle: "false" + + name: Test Node ${{ matrix.node-version }} with --bundle=${{ matrix.bundle }} steps: - uses: actions/checkout@v3 @@ -32,7 +39,7 @@ jobs: - run: npm ci - name: Tests - run: npm test + run: npm run test -- --bundle=${{ matrix.bundle }} lint: runs-on: ubuntu-latest @@ -68,6 +75,21 @@ jobs: - name: Validate the browser can import TypeScript run: gulp test-browser-integration + typecheck: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "*" + check-latest: true + - run: npm ci + + - name: Build src + run: npx hereby build-src + + misc: runs-on: ubuntu-latest @@ -84,3 +106,23 @@ jobs: - name: ESLint tests run: gulp run-eslint-rules-tests + + self-check: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "*" + check-latest: true + - run: npm ci + + - name: Build tsc + run: gulp tsc + + - name: Clean + run: gulp clean-src + + - name: Self build + run: gulp build-src --built diff --git a/Gulpfile.mjs b/Gulpfile.mjs index 7a257b2fd4cc4..1b178f24961c9 100644 --- a/Gulpfile.mjs +++ b/Gulpfile.mjs @@ -3,25 +3,53 @@ import path from "path"; import fs from "fs"; import log from "fancy-log"; import newer from "gulp-newer"; -import sourcemaps from "gulp-sourcemaps"; import del from "del"; import rename from "gulp-rename"; import concat from "gulp-concat"; import merge2 from "merge2"; import gulp from "gulp"; -import { append, transform } from "gulp-insert"; -import { prependFile } from "./scripts/build/prepend.mjs"; +import { transform } from "gulp-insert"; import { exec, readJson, needsUpdate, getDiffTool, getDirSize, rm } from "./scripts/build/utils.mjs"; import { runConsoleTests, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } from "./scripts/build/tests.mjs"; -import { buildProject, cleanProject, watchProject } from "./scripts/build/projects.mjs"; +import { buildProject as realBuildProject, cleanProject, watchProject } from "./scripts/build/projects.mjs"; +import { localizationDirectories } from "./scripts/build/localization.mjs"; import cmdLineOptions from "./scripts/build/options.mjs"; +import esbuild from "esbuild"; const { src, dest, task, parallel, series, watch } = gulp; const copyright = "CopyrightNotice.txt"; const cleanTasks = []; -const testRunner = "./built/local/testRunner/runner.js"; + +// TODO(jakebailey): This is really gross. Waiting on https://github.com/microsoft/TypeScript/issues/25613, +// or at least control over noEmit / emitDeclarationOnly in build mode. +let currentlyBuilding = 0; +let oldTsconfigBase; + +/** @type {typeof realBuildProject} */ +const buildProjectWithEmit = async (...args) => { + const tsconfigBasePath = "./src/tsconfig-base.json"; + + if (currentlyBuilding === 0) { + oldTsconfigBase = fs.readFileSync(tsconfigBasePath, "utf-8"); + fs.writeFileSync(tsconfigBasePath, oldTsconfigBase.replace(`"emitDeclarationOnly": true,`, `"emitDeclarationOnly": false, // DO NOT COMMIT`)); + } + + currentlyBuilding++; + + await realBuildProject(...args); + + currentlyBuilding--; + + if (currentlyBuilding === 0) { + fs.writeFileSync(tsconfigBasePath, oldTsconfigBase); + } +}; + + +const buildProject = cmdLineOptions.bundle ? realBuildProject : buildProjectWithEmit; + const buildScripts = () => buildProject("scripts"); task("scripts", buildScripts); @@ -82,8 +110,7 @@ const generatedLCGFile = "built/local/enu/diagnosticMessages.generated.json.lcg" * 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg' * generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json */ -const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"] - .map(f => f.toLowerCase()) +const localizationTargets = localizationDirectories .map(f => `built/local/${f}/diagnosticMessages.generated.json`) .concat(generatedLCGFile); @@ -101,23 +128,140 @@ task("build-src", series(preSrc, buildSrc)); const cleanSrc = () => cleanProject("src"); task("clean-src", cleanSrc); -const buildDebugTools = () => buildProject("src/debug"); -const cleanDebugTools = () => cleanProject("src/debug"); + +/** @type {string | undefined} */ +let copyrightHeader; +function getCopyrightHeader() { + if (copyrightHeader === undefined) { + copyrightHeader = fs.readFileSync(copyright, "utf-8"); + } + return copyrightHeader; +} + +/** + * @param {string} entrypoint + * @param {string} outfile + * @param {boolean} exportIsTsObject True if this file exports the TS object and should have relevant code injected. + */ +function esbuildTask(entrypoint, outfile, exportIsTsObject = false) { + // Note: we do not use --minify, as that would hide function names from user backtraces + // (we don't ship our sourcemaps), and would break consumers like monaco which modify + // typescript.js for their own needs. Also, using --sourcesContent=false doesn't help, + // as even though it's a smaller source map that could be shipped to users for better + // stack traces via names, the maps are bigger than the actual source files themselves. + /** @type {esbuild.BuildOptions} */ + const options = { + entryPoints: [entrypoint], + banner: { js: getCopyrightHeader() }, + bundle: true, + outfile, + platform: "node", + target: "es2018", + format: "cjs", + sourcemap: "linked", + external: ["./node_modules/*"], + conditions: ["require"], + // legalComments: "none", // If we add copyright headers to the source files, uncomment. + plugins: [ + { + name: "fix-require", + setup: (build) => { + build.onEnd(async () => { + // esbuild converts calls to "require" to "__require"; this function + // calls the real require if it exists, or throws if it does not (rather than + // throwing an error like "require not defined"). But, since we want typescript + // to be consumable by other bundlers, we need to convert these calls back to + // require so our imports are visible again. + // + // Note that this step breaks source maps, but only for lines that reference + // "__require", which is an okay tradeoff for the performance of not running + // the output through transpileModule/babel/etc. + // + // See: https://github.com/evanw/esbuild/issues/1905 + let contents = await fs.promises.readFile(outfile, "utf-8"); + contents = contents.replace(/__require\(/g, "require("); + await fs.promises.writeFile(outfile, contents); + }); + }, + } + ] + }; + + if (exportIsTsObject) { + options.format = "iife"; // We use an IIFE so we can inject the code below. + options.globalName = "ts"; // Name the variable ts, matching our old big bundle and so we can use the code below. + options.footer = { + // These snippets cannot appear in the actual source files, otherwise they will be rewritten + // to things like exports or requires. + js: ` +if (typeof module !== "undefined" && module.exports) { + // If we are in a CJS context, export the ts namespace. + module.exports = ts; +} +if (ts.server) { + // If we are in a server bundle, inject the dynamicImport function. + ts.server.dynamicImport = id => import(id); +}` + }; + } + + return { + build: () => esbuild.build(options), + clean: () => del([outfile, `${outfile}.map`]), + watch: () => esbuild.build({ ...options, watch: true }), + }; +} + +/** + * Writes a CJS module that reexports another CJS file via + * `module.exports = require("...")`. + * + * @param {string} infile Relative path from the repo root to the file to be required. + * @param {string} outfile Relative path from the repo root to the output file. + */ +function writeCJSReexport(infile, outfile) { + const outDir = path.dirname(outfile); + fs.mkdirSync(outDir, { recursive: true }); + const inRelativeToOut = path.relative(outDir, infile); + fs.writeFileSync(outfile, `module.exports = require("./${inRelativeToOut}")`); +} + +const esbuildDebugTools = esbuildTask("./src/debug/compilerDebug.ts", "./built/local/compiler-debug.js"); + +const buildDebugTools = () => { + if (cmdLineOptions.bundle) return esbuildDebugTools.build(); + writeCJSReexport("./built/local/debug/compilerDebug.js", "./built/local/compiler-debug.js") + return buildProject("src/debug") +}; +const cleanDebugTools = () => cmdLineOptions.bundle ? esbuildDebugTools.build() : cleanProject("src/debug"); cleanTasks.push(cleanDebugTools); // Pre-build steps when targeting the LKG compiler const lkgPreBuild = parallel(generateLibs, series(generateDiagnostics, buildDebugTools)); -const buildTsc = () => buildProject("src/tsc"); + +const esbuildTsc = esbuildTask("./src/tsc/tsc.ts", "./built/local/tsc.js", /* exportIsTsObject */ true); +const writeTscCJSShim = () => writeCJSReexport("./built/local/tsc/tsc.js", "./built/local/tsc.js"); + + +const buildTsc = () => { + if (cmdLineOptions.bundle) return esbuildTsc.build(); + writeTscCJSShim(); + return buildProject("src/tsc"); +}; task("tsc", series(lkgPreBuild, buildTsc)); task("tsc").description = "Builds the command-line compiler"; -const cleanTsc = () => cleanProject("src/tsc"); +const cleanTsc = () => cmdLineOptions.bundle ? esbuildTsc.clean() : cleanProject("src/tsc"); cleanTasks.push(cleanTsc); task("clean-tsc", cleanTsc); task("clean-tsc").description = "Cleans outputs for the command-line compiler"; -const watchTsc = () => watchProject("src/tsc"); +const watchTsc = () => { + if (cmdLineOptions.bundle) return esbuildTsc.watch(); + writeTscCJSShim(); + return watchProject("src/tsc"); +}; task("watch-tsc", series(lkgPreBuild, parallel(watchLib, watchDiagnostics, watchTsc))); task("watch-tsc").description = "Watch for changes and rebuild the command-line compiler only."; @@ -127,92 +271,48 @@ const localPreBuild = parallel(generateLibs, series(generateDiagnostics, buildDe // Pre-build steps to use based on supplied options. const preBuild = cmdLineOptions.lkg ? lkgPreBuild : localPreBuild; -const buildServices = (() => { - // build typescriptServices.out.js - const buildTypescriptServicesOut = () => buildProject("src/typescriptServices/tsconfig.json", cmdLineOptions); - - // create typescriptServices.js - const createTypescriptServicesJs = () => src("built/local/typescriptServices.out.js") - .pipe(newer("built/local/typescriptServices.js")) - .pipe(sourcemaps.init({ loadMaps: true })) - .pipe(prependFile(copyright)) - .pipe(rename("typescriptServices.js")) - .pipe(sourcemaps.write(".", { includeContent: false, destPath: "built/local" })) - .pipe(dest("built/local")); - - // create typescriptServices.d.ts - const createTypescriptServicesDts = () => src("built/local/typescriptServices.out.d.ts") - .pipe(newer("built/local/typescriptServices.d.ts")) - .pipe(prependFile(copyright)) - .pipe(transform(content => content.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, "$1$2enum $3 {$4"))) - .pipe(rename("typescriptServices.d.ts")) - .pipe(dest("built/local")); - - // create typescript.js - const createTypescriptJs = () => src("built/local/typescriptServices.js") - .pipe(newer("built/local/typescript.js")) - .pipe(sourcemaps.init({ loadMaps: true })) - .pipe(rename("typescript.js")) - .pipe(sourcemaps.write(".", { includeContent: false, destPath: "built/local" })) - .pipe(dest("built/local")); - - // create typescript.d.ts - const createTypescriptDts = () => src("built/local/typescriptServices.d.ts") - .pipe(newer("built/local/typescript.d.ts")) - .pipe(append("\nexport = ts;")) - .pipe(rename("typescript.d.ts")) - .pipe(dest("built/local")); - - return series( - buildTypescriptServicesOut, - createTypescriptServicesJs, - createTypescriptServicesDts, - createTypescriptJs, - createTypescriptDts, - ); -})(); +const esbuildServices = esbuildTask("./src/typescript/typescript.ts", "./built/local/typescript.js", /* exportIsTsObject */ true); +const writeServicesCJSShim = () => writeCJSReexport("./built/local/typescript/typescript.js", "./built/local/typescript.js"); +const buildServicesProject = () => buildProject("src/typescript"); + +const buildServices = () => { + if (cmdLineOptions.bundle) return esbuildServices.build(); + writeServicesCJSShim(); + return buildServicesProject(); +}; + task("services", series(preBuild, buildServices)); task("services").description = "Builds the language service"; task("services").flags = { " --built": "Compile using the built version of the compiler." }; -const cleanServices = async () => { - if (fs.existsSync("built/local/typescriptServices.tsconfig.json")) { - await cleanProject("built/local/typescriptServices.tsconfig.json"); - } - await del([ - "built/local/typescriptServices.out.js", - "built/local/typescriptServices.out.d.ts", - "built/local/typescriptServices.out.tsbuildinfo", - "built/local/typescriptServices.js", - "built/local/typescript.js", - "built/local/typescript.d.ts", - ]); -}; +const cleanServices = () => cmdLineOptions.bundle ? esbuildServices.clean() : cleanProject("src/typescript"); + cleanTasks.push(cleanServices); task("clean-services", cleanServices); task("clean-services").description = "Cleans outputs for the language service"; -const watchServices = () => watch([ - "src/compiler/tsconfig.json", - "src/compiler/**/*.ts", - "src/jsTyping/tsconfig.json", - "src/jsTyping/**/*.ts", - "src/services/tsconfig.json", - "src/services/**/*.ts", -], series(preBuild, buildServices)); +const watchServices = () => { + if (cmdLineOptions.bundle) return esbuildServices.watch(); + writeServicesCJSShim(); + return watchProject("src/typescript"); +}; task("watch-services", series(preBuild, parallel(watchLib, watchDiagnostics, watchServices))); task("watch-services").description = "Watches for changes and rebuild language service only"; task("watch-services").flags = { " --built": "Compile using the built version of the compiler." }; -const buildDynamicImportCompat = () => buildProject("src/dynamicImportCompat", cmdLineOptions); -task("dynamicImportCompat", buildDynamicImportCompat); -const buildServerMain = () => buildProject("src/tsserver", cmdLineOptions); -const buildServer = series(buildDynamicImportCompat, buildServerMain); +const esbuildServer = esbuildTask("./src/tsserver/server.ts", "./built/local/tsserver.js", /* exportIsTsObject */ true); +const writeServerCJSShim = () => writeCJSReexport("./built/local/tsserver/server.js", "./built/local/tsserver.js"); + +const buildServer = () => { + if (cmdLineOptions.bundle) return esbuildServer.build(); + writeServerCJSShim(); + return buildProject("src/tsserver"); +}; buildServer.displayName = "buildServer"; task("tsserver", series(preBuild, buildServer)); task("tsserver").description = "Builds the language server"; @@ -220,17 +320,18 @@ task("tsserver").flags = { " --built": "Compile using the built version of the compiler." }; -const cleanDynamicImportCompat = () => cleanProject("src/dynamicImportCompat"); -const cleanServerMain = () => cleanProject("src/tsserver"); -const cleanServer = series(cleanDynamicImportCompat, cleanServerMain); +const cleanServer = () => cmdLineOptions.bundle ? esbuildServer.clean() : cleanProject("src/tsserver"); cleanServer.displayName = "cleanServer"; cleanTasks.push(cleanServer); task("clean-tsserver", cleanServer); task("clean-tsserver").description = "Cleans outputs for the language server"; -const watchDynamicImportCompat = () => watchProject("src/dynamicImportCompat", cmdLineOptions); -const watchServer = () => watchProject("src/tsserver", cmdLineOptions); -task("watch-tsserver", series(preBuild, parallel(watchLib, watchDiagnostics, watchDynamicImportCompat, watchServer))); +const watchServer = () => { + if (cmdLineOptions.bundle) return esbuildServer.watch(); + writeServerCJSShim(); + return watchProject("src/tsserver"); +}; +task("watch-tsserver", series(preBuild, parallel(watchLib, watchDiagnostics, watchServer))); task("watch-tsserver").description = "Watch for changes and rebuild the language server only"; task("watch-tsserver").flags = { " --built": "Compile using the built version of the compiler." @@ -251,89 +352,61 @@ task("watch-min").flags = { " --built": "Compile using the built version of the compiler." }; -const buildLssl = (() => { - // build tsserverlibrary.out.js - const buildServerLibraryOut = () => buildProject("src/tsserverlibrary/tsconfig.json", cmdLineOptions); - - // create tsserverlibrary.js - const createServerLibraryJs = () => src("built/local/tsserverlibrary.out.js") - .pipe(newer("built/local/tsserverlibrary.js")) - .pipe(sourcemaps.init({ loadMaps: true })) - .pipe(prependFile(copyright)) - .pipe(rename("tsserverlibrary.js")) - .pipe(sourcemaps.write(".", { includeContent: false, destPath: "built/local" })) - .pipe(dest("built/local")); - - // create tsserverlibrary.d.ts - const createServerLibraryDts = () => src("built/local/tsserverlibrary.out.d.ts") - .pipe(newer("built/local/tsserverlibrary.d.ts")) - .pipe(prependFile(copyright)) - .pipe(transform(content => content.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, "$1$2enum $3 {$4"))) - .pipe(append("\nexport = ts;\nexport as namespace ts;")) - .pipe(rename("tsserverlibrary.d.ts")) - .pipe(dest("built/local")); - - return series( - buildServerLibraryOut, - createServerLibraryJs, - createServerLibraryDts, - ); -})(); +const esbuildLssl = esbuildTask("./src/tsserverlibrary/tsserverlibrary.ts", "./built/local/tsserverlibrary.js", /* exportIsTsObject */ true); +const writeLsslCJSShim = () => writeCJSReexport("./built/local/tsserverlibrary/tsserverlibrary.js", "./built/local/tsserverlibrary.js"); + +const buildLssl = () => { + if (cmdLineOptions.bundle) return esbuildLssl.build(); + writeLsslCJSShim(); + return buildProject("src/tsserverlibrary"); +}; task("lssl", series(preBuild, buildLssl)); task("lssl").description = "Builds language service server library"; task("lssl").flags = { " --built": "Compile using the built version of the compiler." }; -const cleanLssl = async () => { - if (fs.existsSync("built/local/tsserverlibrary.tsconfig.json")) { - await cleanProject("built/local/tsserverlibrary.tsconfig.json"); - } - await del([ - "built/local/tsserverlibrary.out.js", - "built/local/tsserverlibrary.out.d.ts", - "built/local/tsserverlibrary.out.tsbuildinfo", - "built/local/tsserverlibrary.js", - "built/local/tsserverlibrary.d.ts", - ]); -}; +const cleanLssl = () => cmdLineOptions.bundle ? esbuildLssl.clean() : cleanProject("src/tsserverlibrary"); cleanTasks.push(cleanLssl); task("clean-lssl", cleanLssl); task("clean-lssl").description = "Clean outputs for the language service server library"; -const watchLssl = () => watch([ - "src/compiler/tsconfig.json", - "src/compiler/**/*.ts", - "src/jsTyping/tsconfig.json", - "src/jsTyping/**/*.ts", - "src/services/tsconfig.json", - "src/services/**/*.ts", - "src/server/tsconfig.json", - "src/server/**/*.ts", - "src/webServer/tsconfig.json", - "src/webServer/**/*.ts", - "src/tsserver/tsconfig.json", - "src/tsserver/**/*.ts", -], buildLssl); +const watchLssl = () => { + if (cmdLineOptions.bundle) return esbuildLssl.watch(); + writeLsslCJSShim(); + return watchProject("src/tsserverlibrary"); +}; task("watch-lssl", series(preBuild, parallel(watchLib, watchDiagnostics, watchLssl))); task("watch-lssl").description = "Watch for changes and rebuild tsserverlibrary only"; task("watch-lssl").flags = { " --built": "Compile using the built version of the compiler." }; -const buildTests = () => buildProject("src/testRunner"); +const testRunner = "./built/local/run.js"; +const esbuildTests = esbuildTask("./src/testRunner/_namespaces/Harness.ts", testRunner); +const writeTestsCJSShim = () => writeCJSReexport("./built/local/testRunner/runner.js", testRunner); + +const buildTests = () => { + if (cmdLineOptions.bundle) return esbuildTests.build(); + writeTestsCJSShim(); + return buildProject("src/testRunner"); +}; task("tests", series(preBuild, parallel(buildLssl, buildTests))); task("tests").description = "Builds the test infrastructure"; task("tests").flags = { " --built": "Compile using the built version of the compiler." }; -const cleanTests = () => cleanProject("src/testRunner"); +const cleanTests = () => cmdLineOptions.bundle ? esbuildTests.clean() : cleanProject("src/testRunner"); cleanTasks.push(cleanTests); task("clean-tests", cleanTests); task("clean-tests").description = "Cleans the outputs for the test infrastructure"; -const watchTests = () => watchProject("src/testRunner", cmdLineOptions); +const watchTests = () => { + if (cmdLineOptions.bundle) return esbuildTests.watch(); + writeTestsCJSShim(); + return watchProject("src/testRunner"); +}; const runEslintRulesTests = () => runConsoleTests("scripts/eslint/tests", "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ false); task("run-eslint-rules-tests", runEslintRulesTests); @@ -364,16 +437,35 @@ lint.displayName = "lint"; task("lint", lint); task("lint").description = "Runs eslint on the compiler and scripts sources."; -const buildCancellationToken = () => buildProject("src/cancellationToken"); -const cleanCancellationToken = () => cleanProject("src/cancellationToken"); + +const esbuildCancellationToken = esbuildTask("./src/cancellationToken/cancellationToken.ts", "./built/local/cancellationToken.js"); + +const buildCancellationToken = () => { + if (cmdLineOptions.bundle) return esbuildCancellationToken.build() + writeCJSReexport("./built/local/cancellationToken/cancellationToken.js", "./built/local/cancellationToken.js"); + return buildProject("src/cancellationToken") +}; +const cleanCancellationToken = () => cmdLineOptions.bundle ? esbuildCancellationToken.clean() : cleanProject("src/cancellationToken"); cleanTasks.push(cleanCancellationToken); -const buildTypingsInstaller = () => buildProject("src/typingsInstaller"); -const cleanTypingsInstaller = () => cleanProject("src/typingsInstaller"); +const esbuildTypingsInstaller = esbuildTask("./src/typingsInstaller/nodeTypingsInstaller.ts", "./built/local/typingsInstaller.js"); + +const buildTypingsInstaller = () => { + if (cmdLineOptions.bundle) return esbuildTypingsInstaller.build(); + writeCJSReexport("./built/local/typingsInstaller/nodeTypingsInstaller.js", "./built/local/typingsInstaller.js"); + return buildProject("src/typingsInstaller"); +}; +const cleanTypingsInstaller = () => cmdLineOptions.bundle ? esbuildTypingsInstaller.clean() : cleanProject("src/typingsInstaller"); cleanTasks.push(cleanTypingsInstaller); -const buildWatchGuard = () => buildProject("src/watchGuard"); -const cleanWatchGuard = () => cleanProject("src/watchGuard"); +const esbuildWatchGuard = esbuildTask("./src/watchGuard/watchGuard.ts", "./built/local/watchGuard.js"); + +const buildWatchGuard = () => { + if (cmdLineOptions.bundle) return esbuildWatchGuard.build(); + writeCJSReexport("./built/local/watchGuard/watchGuard.js", "./built/local/watchGuard.js"); + return buildProject("src/watchGuard"); +}; +const cleanWatchGuard = () => cmdLineOptions.bundle ? esbuildWatchGuard.clean() : cleanProject("src/watchGuard"); cleanTasks.push(cleanWatchGuard); const generateTypesMap = () => src("src/server/typesMap.json") @@ -416,7 +508,7 @@ const preTest = parallel(buildTsc, buildTests, buildServices, buildLssl); preTest.displayName = "preTest"; const runTests = () => runConsoleTests(testRunner, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ false); -task("runtests", series(/*preBuild, preTest,*/ task("build-src"), runTests)); // TODO(jakebailey): fix this for modules +task("runtests", series(preBuild, preTest, runTests)); task("runtests").description = "Runs the tests using the built run.js file."; task("runtests").flags = { "-t --tests=": "Pattern for tests to run.", @@ -435,7 +527,7 @@ task("runtests").flags = { }; const runTestsParallel = () => runConsoleTests(testRunner, "min", /*runInParallel*/ cmdLineOptions.workers > 1, /*watchMode*/ false); -task("runtests-parallel", series(/*preBuild, preTest,*/ task("build-src"), runTestsParallel)); // TODO(jakebailey): fix this for modules +task("runtests-parallel", series(preBuild, preTest, runTestsParallel)); task("runtests-parallel").description = "Runs all the tests in parallel using the built run.js file."; task("runtests-parallel").flags = { " --light": "Run tests in light mode (fewer verifications, but tests run faster).", @@ -489,25 +581,23 @@ const importDefinitelyTypedTests = () => exec(process.execPath, ["scripts/import task("importDefinitelyTypedTests", importDefinitelyTypedTests); task("importDefinitelyTypedTests").description = "Runs the importDefinitelyTypedTests script to copy DT's tests to the TS-internal RWC tests"; -const buildReleaseTsc = () => buildProject("src/tsc/tsconfig.release.json"); -const cleanReleaseTsc = () => cleanProject("src/tsc/tsconfig.release.json"); -cleanTasks.push(cleanReleaseTsc); - const cleanBuilt = () => del("built"); const produceLKG = async () => { + if (!cmdLineOptions.bundle) { + throw new Error("LKG cannot be created when --bundle=false"); + } + const expectedFiles = [ - "built/local/tsc.release.js", - "built/local/typescriptServices.js", - "built/local/typescriptServices.d.ts", + "built/local/cancellationToken.js", + "built/local/tsc.js", "built/local/tsserver.js", - "built/local/dynamicImportCompat.js", - "built/local/typescript.js", - "built/local/typescript.d.ts", "built/local/tsserverlibrary.js", "built/local/tsserverlibrary.d.ts", + "built/local/typescript.js", + "built/local/typescript.d.ts", "built/local/typingsInstaller.js", - "built/local/cancellationToken.js" + "built/local/watchGuard.js", ].concat(libs.map(lib => lib.target)); const missingFiles = expectedFiles .concat(localizationTargets) @@ -523,7 +613,8 @@ const produceLKG = async () => { } }; -task("LKG", series(lkgPreBuild, parallel(localize, buildTsc, buildServer, buildServices, buildLssl, buildOtherOutputs, buildReleaseTsc), produceLKG)); +// TODO(jakebailey): dependencies on dts +task("LKG", series(lkgPreBuild, parallel(localize, buildTsc, buildServer, buildServices, buildLssl, buildOtherOutputs), produceLKG)); task("LKG").description = "Makes a new LKG out of the built js files"; task("LKG").flags = { " --built": "Compile using the built version of the compiler.", diff --git a/package-lock.json b/package-lock.json index a4bd45434708d..52590f85786db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "chalk": "^4.1.2", "del": "^6.1.1", "diff": "^5.1.0", + "esbuild": "^0.15.13", "eslint": "^8.22.0", "eslint-formatter-autolinkable-stylish": "^1.2.0", "eslint-plugin-import": "^2.26.0", @@ -87,6 +88,38 @@ "node": "^14 || ^16 || ^17 || ^18 || ^19" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz", + "integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz", + "integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", @@ -2266,6 +2299,363 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/esbuild": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz", + "integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.15.13", + "@esbuild/linux-loong64": "0.15.13", + "esbuild-android-64": "0.15.13", + "esbuild-android-arm64": "0.15.13", + "esbuild-darwin-64": "0.15.13", + "esbuild-darwin-arm64": "0.15.13", + "esbuild-freebsd-64": "0.15.13", + "esbuild-freebsd-arm64": "0.15.13", + "esbuild-linux-32": "0.15.13", + "esbuild-linux-64": "0.15.13", + "esbuild-linux-arm": "0.15.13", + "esbuild-linux-arm64": "0.15.13", + "esbuild-linux-mips64le": "0.15.13", + "esbuild-linux-ppc64le": "0.15.13", + "esbuild-linux-riscv64": "0.15.13", + "esbuild-linux-s390x": "0.15.13", + "esbuild-netbsd-64": "0.15.13", + "esbuild-openbsd-64": "0.15.13", + "esbuild-sunos-64": "0.15.13", + "esbuild-windows-32": "0.15.13", + "esbuild-windows-64": "0.15.13", + "esbuild-windows-arm64": "0.15.13" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz", + "integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz", + "integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz", + "integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz", + "integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz", + "integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz", + "integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz", + "integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz", + "integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz", + "integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz", + "integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz", + "integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz", + "integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz", + "integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz", + "integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz", + "integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz", + "integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz", + "integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz", + "integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz", + "integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz", + "integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -8686,6 +9076,20 @@ "jsdoc-type-pratt-parser": "~3.1.0" } }, + "@esbuild/android-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz", + "integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz", + "integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==", + "dev": true, + "optional": true + }, "@eslint/eslintrc": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", @@ -10404,6 +10808,176 @@ "es6-symbol": "^3.1.1" } }, + "esbuild": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz", + "integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.15.13", + "@esbuild/linux-loong64": "0.15.13", + "esbuild-android-64": "0.15.13", + "esbuild-android-arm64": "0.15.13", + "esbuild-darwin-64": "0.15.13", + "esbuild-darwin-arm64": "0.15.13", + "esbuild-freebsd-64": "0.15.13", + "esbuild-freebsd-arm64": "0.15.13", + "esbuild-linux-32": "0.15.13", + "esbuild-linux-64": "0.15.13", + "esbuild-linux-arm": "0.15.13", + "esbuild-linux-arm64": "0.15.13", + "esbuild-linux-mips64le": "0.15.13", + "esbuild-linux-ppc64le": "0.15.13", + "esbuild-linux-riscv64": "0.15.13", + "esbuild-linux-s390x": "0.15.13", + "esbuild-netbsd-64": "0.15.13", + "esbuild-openbsd-64": "0.15.13", + "esbuild-sunos-64": "0.15.13", + "esbuild-windows-32": "0.15.13", + "esbuild-windows-64": "0.15.13", + "esbuild-windows-arm64": "0.15.13" + } + }, + "esbuild-android-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz", + "integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz", + "integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz", + "integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz", + "integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz", + "integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz", + "integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz", + "integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz", + "integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz", + "integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz", + "integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz", + "integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz", + "integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz", + "integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz", + "integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz", + "integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz", + "integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz", + "integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz", + "integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz", + "integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz", + "integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==", + "dev": true, + "optional": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", diff --git a/package.json b/package.json index 215a104ee59db..d4325da91aa21 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "chalk": "^4.1.2", "del": "^6.1.1", "diff": "^5.1.0", + "esbuild": "^0.15.13", "eslint": "^8.22.0", "eslint-formatter-autolinkable-stylish": "^1.2.0", "eslint-plugin-import": "^2.26.0", diff --git a/scripts/build/localization.mjs b/scripts/build/localization.mjs new file mode 100644 index 0000000000000..142bd14c1a073 --- /dev/null +++ b/scripts/build/localization.mjs @@ -0,0 +1 @@ +export const localizationDirectories = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"].map(f => f.toLowerCase()); diff --git a/scripts/build/options.mjs b/scripts/build/options.mjs index 78240aa9aecca..314d9f6802673 100644 --- a/scripts/build/options.mjs +++ b/scripts/build/options.mjs @@ -4,7 +4,7 @@ import os from "os"; const ci = ["1", "true"].includes(process.env.CI ?? ""); const parsed = 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 */ @@ -39,6 +39,7 @@ const parsed = minimist(process.argv.slice(2), { dirty: false, built: false, ci, + bundle: true } }); @@ -77,5 +78,7 @@ export default options; * @property {boolean} ci * @property {string} shards * @property {string} shardId + * @property {string} break + * @property {boolean} bundle */ void 0; diff --git a/scripts/build/prepend.mjs b/scripts/build/prepend.mjs deleted file mode 100644 index 115cd3b3d599c..0000000000000 --- a/scripts/build/prepend.mjs +++ /dev/null @@ -1,61 +0,0 @@ -import stream from "stream"; -import ts from "../../lib/typescript.js"; -import fs from "fs"; -import { base64VLQFormatEncode } from "./sourcemaps.mjs"; - -/** - * @param {string | ((file: import("vinyl")) => string)} data - */ -export function prepend(data) { - return new stream.Transform({ - objectMode: true, - /** - * @param {string | Buffer | import("vinyl")} input - * @param {(error: Error | null, data?: any) => void} cb - */ - transform(input, _, cb) { - if (typeof input === "string" || Buffer.isBuffer(input)) return cb(new Error("Only Vinyl files are supported.")); - if (!input.isBuffer()) return cb(new Error("Streams not supported.")); - try { - const output = input.clone(); - const prependContent = typeof data === "function" ? data(input) : data; - output.contents = Buffer.concat([Buffer.from(prependContent, "utf8"), input.contents]); - if (input.sourceMap) { - if (typeof input.sourceMap === "string") input.sourceMap = /**@type {import("./sourcemaps.mjs").RawSourceMap}*/(JSON.parse(input.sourceMap)); - const lineStarts = /**@type {*}*/(ts).computeLineStarts(prependContent); - let prependMappings = ""; - for (let i = 1; i < lineStarts.length; i++) { - prependMappings += ";"; - } - const offset = prependContent.length - lineStarts[lineStarts.length - 1]; - if (offset > 0) { - prependMappings += base64VLQFormatEncode(offset) + ","; - } - output.sourceMap = { - version: input.sourceMap.version, - file: input.sourceMap.file, - sources: input.sourceMap.sources, - sourceRoot: input.sourceMap.sourceRoot, - mappings: prependMappings + input.sourceMap.mappings, - names: input.names, - sourcesContent: input.sourcesContent - }; - } - // eslint-disable-next-line local/boolean-trivia, no-null/no-null - return cb(null, output); - } - catch (e) { - return cb(/** @type {Error} */(e)); - } - } - }); -} - -/** - * @param {string | ((file: import("vinyl")) => string)} file - */ -export function prependFile(file) { - const data = typeof file === "string" ? fs.readFileSync(file, "utf8") : - (/** @type {import("vinyl")} */ vinyl) => fs.readFileSync(file(vinyl), "utf8"); - return prepend(data); -} diff --git a/scripts/build/projects.mjs b/scripts/build/projects.mjs index 1061f5521b2b5..537eea00a1c29 100644 --- a/scripts/build/projects.mjs +++ b/scripts/build/projects.mjs @@ -1,69 +1,57 @@ import { exec, Debouncer } from "./utils.mjs"; import { resolve } from "path"; import { findUpRoot } from "./findUpDir.mjs"; -import assert from "assert"; +import cmdLineOptions from "./options.mjs"; class ProjectQueue { /** - * @param {(projects: string[], lkg: boolean, force: boolean) => Promise} action + * @param {(projects: string[]) => Promise} action */ constructor(action) { - /** @type {{ lkg: boolean, force: boolean, projects?: string[], debouncer: Debouncer }[]} */ - this._debouncers = []; - this._action = action; + /** @type {string[] | undefined} */ + this._projects = undefined; + this._debouncer = new Debouncer(100, async () => { + const projects = this._projects; + if (projects) { + this._projects = undefined; + await action(projects); + } + }); } /** * @param {string} project - * @param {{ lkg?: boolean; force?: boolean; }} options */ - enqueue(project, { lkg = true, force = false } = {}) { - let entry = this._debouncers.find(entry => entry.lkg === lkg && entry.force === force); - if (!entry) { - const debouncer = new Debouncer(100, async () => { - assert(entry); - const projects = entry.projects; - if (projects) { - entry.projects = undefined; - await this._action(projects, lkg, force); - } - }); - this._debouncers.push(entry = { lkg, force, debouncer }); - } - if (!entry.projects) entry.projects = []; - entry.projects.push(project); - return entry.debouncer.enqueue(); + enqueue(project) { + if (!this._projects) this._projects = []; + this._projects.push(project); + return this._debouncer.enqueue(); } } -const execTsc = (/** @type {boolean} */ lkg, /** @type {string[]} */ ...args) => +const execTsc = (/** @type {string[]} */ ...args) => exec(process.execPath, - [resolve(findUpRoot(), lkg ? "./lib/tsc" : "./built/local/tsc"), + [resolve(findUpRoot(), cmdLineOptions.lkg ? "./lib/tsc.js" : "./built/local/tsc.js"), "-b", ...args], { hidePrompt: true }); -const projectBuilder = new ProjectQueue((projects, lkg, force) => execTsc(lkg, ...(force ? ["--force"] : []), ...projects)); +const projectBuilder = new ProjectQueue((projects) => execTsc(...projects)); /** * @param {string} project - * @param {object} options - * @param {boolean} [options.lkg=true] - * @param {boolean} [options.force=false] */ -export const buildProject = (project, { lkg, force } = {}) => projectBuilder.enqueue(project, { lkg, force }); +export const buildProject = (project) => projectBuilder.enqueue(project); -const projectCleaner = new ProjectQueue((projects, lkg) => execTsc(lkg, "--clean", ...projects)); +const projectCleaner = new ProjectQueue((projects) => execTsc("--clean", ...projects)); /** * @param {string} project */ export const cleanProject = (project) => projectCleaner.enqueue(project); -const projectWatcher = new ProjectQueue((projects) => execTsc(/*lkg*/ true, "--watch", ...projects)); +const projectWatcher = new ProjectQueue((projects) => execTsc("--watch", ...projects)); /** * @param {string} project - * @param {object} options - * @param {boolean} [options.lkg=true] */ -export const watchProject = (project, { lkg } = {}) => projectWatcher.enqueue(project, { lkg }); +export const watchProject = (project) => projectWatcher.enqueue(project); diff --git a/scripts/build/tests.mjs b/scripts/build/tests.mjs index dce50403c0d9c..4d2edb3e2730d 100644 --- a/scripts/build/tests.mjs +++ b/scripts/build/tests.mjs @@ -122,17 +122,6 @@ export async function runConsoleTests(runJs, defaultReporter, runInParallel, _wa errorStatus = exitCode; error = new Error(`Process exited with status code ${errorStatus}.`); } - else if (cmdLineOptions.ci && runJs.startsWith("built")) { - // 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; diff --git a/scripts/produceLKG.mjs b/scripts/produceLKG.mjs index 0d1ea0f8bc500..1683b7a5c1c56 100644 --- a/scripts/produceLKG.mjs +++ b/scripts/produceLKG.mjs @@ -3,6 +3,7 @@ import path from "path"; import glob from "glob"; import url from "url"; import del from "del"; +import { localizationDirectories } from "./build/localization.mjs"; const __filename = url.fileURLToPath(new URL(import.meta.url)); const __dirname = path.dirname(__filename); @@ -29,15 +30,9 @@ async function copyLibFiles() { } async function copyLocalizedDiagnostics() { - const dir = await fs.readdir(source); - const ignoredFolders = ["enu"]; - - for (const d of dir) { + for (const d of localizationDirectories) { const fileName = path.join(source, d); - if ( - fs.statSync(fileName).isDirectory() && - ignoredFolders.indexOf(d) < 0 - ) { + if (fs.statSync(fileName).isDirectory()) { await fs.copy(fileName, path.join(dest, d)); } } @@ -48,21 +43,18 @@ async function copyTypesMap() { } async function copyScriptOutputs() { - await copyWithCopyright("cancellationToken.js"); - await copyWithCopyright("tsc.release.js", "tsc.js"); - await copyWithCopyright("tsserver.js"); - await copyWithCopyright("dynamicImportCompat.js"); - await copyFromBuiltLocal("tsserverlibrary.js"); // copyright added by build - await copyFromBuiltLocal("typescript.js"); // copyright added by build - await copyFromBuiltLocal("typescriptServices.js"); // copyright added by build - await copyWithCopyright("typingsInstaller.js"); - await copyWithCopyright("watchGuard.js"); + await copyFromBuiltLocal("cancellationToken.js"); + await copyFromBuiltLocal("tsc.js"); + await copyFromBuiltLocal("tsserver.js"); + await copyFromBuiltLocal("tsserverlibrary.js"); + await copyFromBuiltLocal("typescript.js"); + await copyFromBuiltLocal("typingsInstaller.js"); + await copyFromBuiltLocal("watchGuard.js"); } async function copyDeclarationOutputs() { - await copyFromBuiltLocal("tsserverlibrary.d.ts"); // copyright added by build - await copyFromBuiltLocal("typescript.d.ts"); // copyright added by build - await copyFromBuiltLocal("typescriptServices.d.ts"); // copyright added by build + await copyWithCopyright("tsserverlibrary.d.ts"); + await copyWithCopyright("typescript.d.ts"); } async function writeGitAttributes() { diff --git a/src/cancellationToken/tsconfig.json b/src/cancellationToken/tsconfig.json index ca3cf90c100d5..9249fae5d1795 100644 --- a/src/cancellationToken/tsconfig.json +++ b/src/cancellationToken/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/cancellationToken", "module": "commonjs", "types": [ "node" diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index ffacb3f1fd721..e4cbb90009ce6 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -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(); - 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) { diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index fdffb214503cc..6b8d0464146b6 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/compiler", "types": ["node"] }, diff --git a/src/debug/_namespaces/Debug.ts b/src/debug/_namespaces/Debug.ts deleted file mode 100644 index 449c31bdaefbe..0000000000000 --- a/src/debug/_namespaces/Debug.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* Generated file to emulate the Debug namespace. */ - -export * from "../dbg"; diff --git a/src/debug/dbg.ts b/src/debug/compilerDebug.ts similarity index 95% rename from src/debug/dbg.ts rename to src/debug/compilerDebug.ts index 202681c34a308..906a166332a0d 100644 --- a/src/debug/dbg.ts +++ b/src/debug/compilerDebug.ts @@ -1,7 +1,3 @@ -import * as Debug from "./_namespaces/Debug"; - -/// - 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; -} diff --git a/src/debug/tsconfig.json b/src/debug/tsconfig.json index 06b94b3b2cbb5..ab17c2cab1a99 100644 --- a/src/debug/tsconfig.json +++ b/src/debug/tsconfig.json @@ -3,7 +3,6 @@ "compilerOptions": { "target": "es2019", "lib": ["es2019"], - "outDir": "../../built/local/debug" }, "include": ["**/*"] } diff --git a/src/deprecatedCompat/tsconfig.json b/src/deprecatedCompat/tsconfig.json index 571628bf16b3f..e0e98fac65db6 100644 --- a/src/deprecatedCompat/tsconfig.json +++ b/src/deprecatedCompat/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/deprecatedCompat" }, "references": [ { "path": "../compiler" } diff --git a/src/dynamicImportCompat/_namespaces/ts.server.ts b/src/dynamicImportCompat/_namespaces/ts.server.ts deleted file mode 100644 index 729da9c24ef35..0000000000000 --- a/src/dynamicImportCompat/_namespaces/ts.server.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* Generated file to emulate the ts.server namespace. */ - -export * from "../dynamicImportCompat"; diff --git a/src/dynamicImportCompat/_namespaces/ts.ts b/src/dynamicImportCompat/_namespaces/ts.ts deleted file mode 100644 index 91d7693414440..0000000000000 --- a/src/dynamicImportCompat/_namespaces/ts.ts +++ /dev/null @@ -1,4 +0,0 @@ -/* Generated file to emulate the ts namespace. */ - -import * as server from "./ts.server"; -export { server }; diff --git a/src/dynamicImportCompat/dynamicImportCompat.ts b/src/dynamicImportCompat/dynamicImportCompat.ts deleted file mode 100644 index 5981d8c7e968e..0000000000000 --- a/src/dynamicImportCompat/dynamicImportCompat.ts +++ /dev/null @@ -1 +0,0 @@ -export const dynamicImport = (id: string) => import(id); \ No newline at end of file diff --git a/src/dynamicImportCompat/tsconfig.json b/src/dynamicImportCompat/tsconfig.json deleted file mode 100644 index 3abacb2133d0a..0000000000000 --- a/src/dynamicImportCompat/tsconfig.json +++ /dev/null @@ -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" - ] -} diff --git a/src/executeCommandLine/tsconfig.json b/src/executeCommandLine/tsconfig.json index 103bd54a282c2..c988aed5d19c3 100644 --- a/src/executeCommandLine/tsconfig.json +++ b/src/executeCommandLine/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/executeCommandLine" }, "references": [ diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index ff8de94c2ef9c..ff4946a41f68d 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -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`. diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index dea8d57947f7a..8349a275831e4 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/harness", "types": [ "node", "mocha", "chai" ], diff --git a/src/jsTyping/tsconfig.json b/src/jsTyping/tsconfig.json index e987ba35de5d9..048e3437794d4 100644 --- a/src/jsTyping/tsconfig.json +++ b/src/jsTyping/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/jsTyping", "types": [ "node" ], diff --git a/src/loggedIO/tsconfig.json b/src/loggedIO/tsconfig.json index 8d51cd6926594..820cd1cb57b7f 100644 --- a/src/loggedIO/tsconfig.json +++ b/src/loggedIO/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/loggedIO", "types": [ ], "lib": [ diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index 6c99b15ecb9e2..13a2fbe6a0a45 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -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(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; diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json index 340768af8e2fb..3ab8107c3e15b 100644 --- a/src/server/tsconfig.json +++ b/src/server/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/server", "types": [ "node" ] diff --git a/src/services/_namespaces/ts.ts b/src/services/_namespaces/ts.ts index eae114fd2e834..55fca06914ebd 100644 --- a/src/services/_namespaces/ts.ts +++ b/src/services/_namespaces/ts.ts @@ -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"; diff --git a/src/services/exportAsModule.ts b/src/services/exportAsModule.ts deleted file mode 100644 index 757f9f7cd34fe..0000000000000 --- a/src/services/exportAsModule.ts +++ /dev/null @@ -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; -} diff --git a/src/services/services.ts b/src/services/services.ts index 10a1299bcc15e..3380fe9ff2dcc 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -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. "); diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 3bab5eb0b81c1..42c124fdd8156 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/services" }, "references": [ { "path": "../compiler" }, diff --git a/src/testRunner/_namespaces/Harness.ts b/src/testRunner/_namespaces/Harness.ts index a5b5cb5ab35b1..a9e4e0904b3fb 100644 --- a/src/testRunner/_namespaces/Harness.ts +++ b/src/testRunner/_namespaces/Harness.ts @@ -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"); diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index be32183573d0b..ffcb8601da878 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/testRunner", "types": [ "node", "mocha", "chai" ], diff --git a/src/tsc/tsconfig.json b/src/tsc/tsconfig.json index a649d4b9fdf54..21e193ad5d70c 100644 --- a/src/tsc/tsconfig.json +++ b/src/tsc/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/tsc" }, "references": [ { "path": "../compiler" }, diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index c3f416245b8a6..d0efb21a159c0 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -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, diff --git a/src/tsconfig.json b/src/tsconfig.json index bb93273166a2c..213e1eda3c3b2 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -6,7 +6,6 @@ { "path": "./compiler" }, { "path": "./debug" }, { "path": "./deprecatedCompat" }, - { "path": "./dynamicImportCompat" }, { "path": "./executeCommandLine" }, { "path": "./harness" }, { "path": "./jsTyping" }, diff --git a/src/tsserver/nodeServer.ts b/src/tsserver/nodeServer.ts index de9b8a0ad672e..4292b8cc02f84 100644 --- a/src/tsserver/nodeServer.ts +++ b/src/tsserver/nodeServer.ts @@ -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 diff --git a/src/tsserver/tsconfig.json b/src/tsserver/tsconfig.json index d687a82d6f94e..8408638400761 100644 --- a/src/tsserver/tsconfig.json +++ b/src/tsserver/tsconfig.json @@ -2,7 +2,6 @@ "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/tsserver", "types": [ "node" ] diff --git a/src/tsserverlibrary/tsconfig.json b/src/tsserverlibrary/tsconfig.json index 7253696321bd0..97af0d95294c1 100644 --- a/src/tsserverlibrary/tsconfig.json +++ b/src/tsserverlibrary/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/tsserverlibrary" }, "references": [ { "path": "../compiler" }, diff --git a/src/typescript/tsconfig.json b/src/typescript/tsconfig.json index a1e1447379bbf..4bc23cc65b439 100644 --- a/src/typescript/tsconfig.json +++ b/src/typescript/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/typescript" }, "references": [ { "path": "../compiler" }, diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index f043e44a18e43..c1dd5d67b42ee 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -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); diff --git a/src/typingsInstaller/tsconfig.json b/src/typingsInstaller/tsconfig.json index 7301536476d8b..528f3580c186c 100644 --- a/src/typingsInstaller/tsconfig.json +++ b/src/typingsInstaller/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/typingsInstaller", "types": [ "node" ], diff --git a/src/typingsInstallerCore/tsconfig.json b/src/typingsInstallerCore/tsconfig.json index e5920e87c606a..83fabc202f5f1 100644 --- a/src/typingsInstallerCore/tsconfig.json +++ b/src/typingsInstallerCore/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/typingsInstallerCore", "types": [ "node" ], diff --git a/src/watchGuard/tsconfig.json b/src/watchGuard/tsconfig.json index 0a32df080d690..636a871a94ba3 100644 --- a/src/watchGuard/tsconfig.json +++ b/src/watchGuard/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/watchGuard", "types": [ "node" ], diff --git a/src/webServer/tsconfig.json b/src/webServer/tsconfig.json index 69955d2baa434..5b4c1fdbf5605 100644 --- a/src/webServer/tsconfig.json +++ b/src/webServer/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../tsconfig-base", "compilerOptions": { - "outDir": "../../built/local/webServer", "types": [ "node" ] diff --git a/src/webServer/webServer.ts b/src/webServer/webServer.ts index 11980d1a0e49c..ba41fc8af57ed 100644 --- a/src/webServer/webServer.ts +++ b/src/webServer/webServer.ts @@ -1,8 +1,6 @@ /// /// -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 => { + 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 => { - const serverDynamicImport: ((id: string) => Promise) | 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