Skip to content

Commit

Permalink
Centralized browser tsconfig (Azure#32087)
Browse files Browse the repository at this point in the history
  • Loading branch information
deyaaeldeen authored Dec 7, 2024
1 parent f2c56f7 commit 03bdd2e
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 41 deletions.
67 changes: 66 additions & 1 deletion common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions common/tools/dev-tool/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"env-paths": "^2.2.1",
"express": "^4.19.2",
"fs-extra": "^11.2.0",
"memfs": "^4.14.1",
"minimist": "^1.2.8",
"prettier": "^3.3.3",
"rollup": "^4.22.0",
Expand Down
24 changes: 10 additions & 14 deletions common/tools/dev-tool/src/commands/run/build-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,11 @@
// Licensed under the MIT License.

import path from "node:path";
import {
cpSync,
existsSync,
mkdirSync,
readFileSync,
readdirSync,
statSync,
writeFileSync,
} from "node:fs";
import { cpSync, existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from "node:fs";
import { leafCommand, makeCommandInfo } from "../../framework/command";
import { createPrinter } from "../../util/printer";
import { resolveProject } from "../../util/resolveProject";
import { resolveConfig } from "../../util/resolveTsConfig";
import { spawnSync } from "node:child_process";

const log = createPrinter("build-test");
Expand Down Expand Up @@ -107,15 +100,18 @@ function compileForEnvironment(
overrideMap: Map<string, string>,
): boolean {
const tsconfigPath = path.join(process.cwd(), tsConfig);
const tsConfigFile = readFileSync(tsconfigPath, "utf8");
const tsConfigJSON = JSON.parse(tsConfigFile);
const tsConfigJSON = resolveConfig(tsconfigPath);
const outputPath = tsConfigJSON.compilerOptions.outDir;
if (!existsSync(tsconfigPath)) {
log.error(`TypeScript config ${tsConfig} does not exist`);
return false;
}

const browserTestPath = path.join(process.cwd(), outputPath);
const browserTestPath = outputPath;
if (!browserTestPath) {
log.error(`Output path not defined in ${tsConfig}`);
return false;
}
if (!existsSync(browserTestPath)) {
mkdirSync(browserTestPath, { recursive: true });
}
Expand Down Expand Up @@ -191,8 +187,8 @@ function overrideFile(
sourceFile: string,
destinationFile: string,
): void {
const sourceFileType = path.join(process.cwd(), rootDir, relativeDir, sourceFile);
const destFileType = path.join(process.cwd(), rootDir, relativeDir, destinationFile);
const sourceFileType = path.join(rootDir, relativeDir, sourceFile);
const destFileType = path.join(rootDir, relativeDir, destinationFile);

cpSync(sourceFileType, destFileType, { force: true });
}
Expand Down
60 changes: 60 additions & 0 deletions common/tools/dev-tool/src/util/resolveTsConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import * as path from "path";
import * as fs from "fs";
import ts from "typescript";

type Config = { compilerOptions: ts.CompilerOptions };

function resolveConfigDir(configPath: string, unresolvedPath: string) {
return unresolvedPath.replace(/\$\{configDir\}/g, path.dirname(configPath));
}

function mergeConfig(config1: Config, config2: Config) {
return {
...config1,
...config2,
compilerOptions: {
...config1.compilerOptions,
...config2.compilerOptions,
},
};
}

/**
* Generates a complete TypeScript configuration by reading and parsing a given tsconfig file.
*
* @param configPath - The path to the tsconfig file.
* @returns A record containing the raw parsed configuration.
*/
export function resolveConfig(configPath: string) {
function helper(configPath: string) {
const absolutePath = path.resolve(configPath);
const configDir = path.dirname(absolutePath);
const rawConfig = JSON.parse(
fs.readFileSync(
!absolutePath.toLowerCase().endsWith(".json") ? `${absolutePath}.json` : absolutePath,
"utf8",
),
);

let resolvedConfig = {} as Config;
const { extends: parents, ...rest } = rawConfig;
if (parents) {
const baseConfigs = Array.isArray(parents) ? parents : [parents];
for (const baseConfigPath of baseConfigs) {
const baseConfigAbsolutePath = path.resolve(configDir, baseConfigPath);
const baseConfig = helper(baseConfigAbsolutePath);
resolvedConfig = mergeConfig(resolvedConfig, baseConfig);
}
}
return mergeConfig(resolvedConfig, rest);
}
const resolvedConfig = helper(configPath);
const outDir = resolvedConfig.compilerOptions.outDir;
if (outDir) {
resolvedConfig.compilerOptions.outDir = resolveConfigDir(configPath, outDir);
}
return resolvedConfig;
}
117 changes: 117 additions & 0 deletions common/tools/dev-tool/test/resolveTsConfig.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License

import { describe, it, beforeEach, expect, vi } from "vitest";
import { vol } from "memfs";
import { resolveConfig } from "../src/util/resolveTsConfig";

vi.mock("fs", async () => {
const memfs = await import("memfs");
return {
...memfs.fs,
};
});

describe("resolveConfig", () => {
beforeEach(() => {
vol.reset();
});

it("should resolve a simple tsconfig.json", () => {
const def = {
compilerOptions: {
target: "ES6",
},
};
vol.fromJSON({
"/project/tsconfig.json": JSON.stringify(def),
});

const result = resolveConfig("/project/tsconfig.json");
expect(result).toEqual(def);
});

it("should resolve tsconfig.json with single extend", () => {
vol.fromJSON({
"/project/tsconfig.base.json": JSON.stringify({
compilerOptions: {
target: "ES5",
module: "CommonJS",
},
}),
"/project/tsconfig.json": JSON.stringify({
extends: "./tsconfig.base.json",
compilerOptions: {
strict: true,
},
}),
});

const result = resolveConfig("/project/tsconfig.json");
expect(result).toEqual({
compilerOptions: {
target: "ES5",
module: "CommonJS",
strict: true,
},
});
});

it("should resolve tsconfig.json with single extend and conflicting option", () => {
vol.fromJSON({
"/project/tsconfig.base.json": JSON.stringify({
compilerOptions: {
target: "ES5",
outDir: "path1",
},
}),
"/project/tsconfig.json": JSON.stringify({
extends: "./tsconfig.base.json",
compilerOptions: {
strict: true,
outDir: "path2",
},
}),
});

const result = resolveConfig("/project/tsconfig.json");
expect(result).toEqual({
compilerOptions: {
target: "ES5",
strict: true,
outDir: "path2",
},
});
});

it("should resolve tsconfig.json with multiple extends with conflicting options in parents", () => {
vol.fromJSON({
"/project/tsconfig.base1.json": JSON.stringify({
compilerOptions: {
target: "ES5",
outDir: "path1",
},
}),
"/project/tsconfig.base2.json": JSON.stringify({
compilerOptions: {
outDir: "path2",
},
}),
"/project/tsconfig.json": JSON.stringify({
extends: ["./tsconfig.base1.json", "./tsconfig.base2.json"],
compilerOptions: {
strict: true,
},
}),
});

const result = resolveConfig("/project/tsconfig.json");
expect(result).toEqual({
compilerOptions: {
target: "ES5",
strict: true,
outDir: "path2",
},
});
});
});
8 changes: 2 additions & 6 deletions sdk/eventhub/event-hubs/tsconfig.browser.config.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
{
"extends": "./tsconfig.test.json",
"exclude": ["./test/**/node", "./test/stress"],
"compilerOptions": {
"outDir": "./dist-test/browser",
"noEmit": false
}
"extends": ["./tsconfig.test.json", "../../../tsconfig.browser.base.json"],
"exclude": ["./test/**/node", "./test/stress"]
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
{
"extends": "./tsconfig.test.json",
"exclude": ["./test/**/node"],
"compilerOptions": {
"outDir": "./dist-test/browser",
"noEmit": false
}
"extends": ["./tsconfig.test.json", "../../../tsconfig.browser.base.json"]
}
8 changes: 2 additions & 6 deletions sdk/identity/identity/tsconfig.browser.config.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
{
"extends": "./tsconfig.test.json",
"exclude": ["./test/**/node", "./test/manual*"],
"compilerOptions": {
"outDir": "./dist-test/browser",
"noEmit": false
}
"extends": ["./tsconfig.test.json", "../../../tsconfig.browser.base.json"],
"exclude": ["./test/**/node", "./test/manual*"]
}
7 changes: 1 addition & 6 deletions sdk/openai/openai/tsconfig.browser.config.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
{
"extends": "./tsconfig.test.json",
"exclude": ["./test/**/node"],
"compilerOptions": {
"outDir": "./dist-test/browser",
"noEmit": false
}
"extends": ["./tsconfig.test.json", "../../../tsconfig.browser.base.json"]
}
Loading

0 comments on commit 03bdd2e

Please sign in to comment.