mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-15 14:05:47 -05:00
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:
1
scripts/build/localization.mjs
Normal file
1
scripts/build/localization.mjs
Normal file
@@ -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());
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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<any>} action
|
||||
* @param {(projects: string[]) => Promise<any>} 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user