Skip to content

Conversation

@tylerbutler
Copy link
Member

@tylerbutler tylerbutler commented Jan 7, 2026

Description

Enables fluid-build to properly support ESLint 9 flat config files for incremental build tracking.

Changes

Config File Detection (taskUtils.ts)

Expands getEsLintConfigFilePath to detect ESLint 9 flat config files:

  • eslint.config.{mjs,mts,cjs,cts,js,ts} (checked first)
  • Legacy .eslintrc.{js,cjs,json} files (backwards compatibility)

Config File Parsing (fluidBuildTasks.ts)

Replaces manual config file parsing with ESLint's calculateConfigForFile() API to extract parserOptions.project for build task dependencies. This properly supports:

  • ESLint 9 flat configs (languageOptions.parserOptions.project)
  • Legacy eslintrc configs (parserOptions.project)
  • TypeScript config files (.mts, .cts, .ts)
  • ESM config files (.mjs)

The previous manual parsing with require() and JSON5.parse() couldn't handle ESLint 9's different config structure or TypeScript/ESM configs.

Motivation

Without these changes, packages using ESLint 9 flat configs cannot have proper incremental build tracking - fluid-build couldn't detect the config files or parse them to determine tsc task dependencies.

Related: #26017

The getEsLintConfigFilePath function now checks for ESLint 9 flat config
files in addition to legacy .eslintrc files. This enables fluid-build to
properly detect config files and generate done files for eslint tasks
when packages migrate to ESLint 9.

Supported flat config files (checked first):
- eslint.config.mjs, eslint.config.mts
- eslint.config.cjs, eslint.config.cts
- eslint.config.js, eslint.config.ts

Legacy files still supported for backwards compatibility:
- .eslintrc.js, .eslintrc.cjs, .eslintrc.json, .eslintrc
Copilot AI review requested due to automatic review settings January 7, 2026 21:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the getEsLintConfigFilePath function to detect ESLint 9 flat config files in addition to legacy .eslintrc files. This enables fluid-build to locate config files for packages migrating to ESLint 9, preventing errors during incremental build tracking.

Key Changes

  • Added detection for ESLint 9 flat config files (.mjs, .mts, .cjs, .cts, .js, .ts variants)
  • Maintained backwards compatibility with legacy eslintrc files
  • Established precedence order with ESLint 9 configs checked first
Comments suppressed due to low confidence (1)

build-tools/packages/build-tools/src/fluidBuild/tasks/taskUtils.ts:41

  • The function getEsLintConfigFilePath lacks test coverage. Other utility functions in the same file (like globFn and globWithGitignore) have comprehensive test coverage in src/test/globPatterns.test.ts.

Consider adding tests to verify:

  • Correct detection of ESLint 9 flat config files in the proper precedence order
  • Correct detection of legacy eslintrc files
  • Behavior when multiple config files exist (should return the first match based on precedence)
  • Behavior when no config file exists (returns undefined)
export function getEsLintConfigFilePath(dir: string) {
	// ESLint 9 flat config files (checked first as they take precedence)
	// Then legacy eslintrc files for backwards compatibility
	// TODO: we currently don't support .yaml and .yml, or config in package.json
	const possibleConfig = [
		// ESLint 9 flat config files
		"eslint.config.mjs",
		"eslint.config.mts",
		"eslint.config.cjs",
		"eslint.config.cts",
		"eslint.config.js",
		"eslint.config.ts",
		// Legacy eslintrc files
		".eslintrc.js",
		".eslintrc.cjs",
		".eslintrc.json",
		".eslintrc",
	];
	for (const configFile of possibleConfig) {
		const configFileFullPath = path.join(dir, configFile);
		if (existsSync(configFileFullPath)) {
			return configFileFullPath;
		}
	}
	return undefined;
}

@tylerbutler tylerbutler marked this pull request as draft January 7, 2026 21:32
…encies

Replace manual config file parsing with ESLint's calculateConfigForFile API.
This properly supports:
- ESLint 9 flat config files (eslint.config.{js,mjs,cjs,ts,mts,cts})
- Legacy eslintrc files (.eslintrc.{js,cjs,json})
- TypeScript config files that require transpilation
- ESM config files

The ESLint API resolves extends/overrides and returns the effective
parserOptions.project value, which is used to determine tsc task dependencies.

Adds @types/eslint as a dev dependency for type safety.
@tylerbutler tylerbutler changed the title fix(build-tools): support ESLint 9 flat config file detection fix(build-tools): support ESLint 9 flat config detection and parsing Jan 7, 2026
Remove fallback for pre-8.57.0 ESLint versions since loadESLint API
is required for proper flat config detection. Adds a clear error
message if older ESLint is detected.
- Add proper types for ESLint computed config (ParserOptions,
  ComputedESLintConfig) instead of using 'any' casts
- Add comment explaining why the dynamic import cast is safe
- Remove 'null' from type annotations per codebase conventions
tylerbutler added a commit to tylerbutler/FluidFramework that referenced this pull request Jan 7, 2026
Rename ESLint flat config files from JavaScript (.mjs) to TypeScript
(.mts) for consistency with PR microsoft#26070. Add jiti dependency to enable
runtime transpilation of TypeScript config files.

Also includes the ESLint 9 flat config detection fix from PR microsoft#26147.
@tylerbutler tylerbutler marked this pull request as ready for review January 7, 2026 23:08
@tylerbutler tylerbutler requested a review from a team January 7, 2026 23:08
@tylerbutler tylerbutler changed the title fix(build-tools): support ESLint 9 flat config detection and parsing feat(build-tools): support ESLint 9 flat config detection and parsing Jan 7, 2026
@tylerbutler tylerbutler merged commit a5b8587 into microsoft:main Jan 7, 2026
23 checks passed
@tylerbutler tylerbutler deleted the eslint9-config-detection branch January 7, 2026 23:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants