From bc21d81f6c91fe937eb1e3aa0a67f652d1e9f1bd Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Tue, 14 Jan 2025 19:35:45 +0000 Subject: [PATCH] refactor: add explicit types for `createBuilder` exports This is necessary as with the new compilation, leveraging pnpm-linked first party dependencies, there are cases **during migration** where multiple locations of the same package exist. e.g. - `@angular_devkit/architect/node_modules/@angular-devkit/core` (pnpm package output) - `@angular_devkit/core` (plain js sources) This is fine, and there is no risk of wrong types, and this should only occur during migration anyway, but it causes a few type issues as TypeScript is unable to emit proper types for inference. This is okay, as we'd likely even want to make use of `isolatedDeclarations` at some point, but we just add explicit types right now. (also making `Builder` type more type safe, checking assignability properly). --- .../angular_devkit/architect/index.api.md | 12 ++++++++++ packages/angular/build/BUILD.bazel | 1 + .../build/src/builders/application/index.ts | 8 +++++-- .../build/src/builders/dev-server/index.ts | 10 +++++++-- .../build/src/builders/extract-i18n/index.ts | 9 ++++++-- .../build/src/builders/ng-packagr/index.ts | 9 ++++++-- .../architect/src/create-builder.ts | 5 +++++ .../angular_devkit/architect/src/index.ts | 2 +- .../angular_devkit/architect/src/internal.ts | 1 + .../angular_devkit/build_webpack/BUILD.bazel | 1 + .../src/builders/webpack-dev-server/index.ts | 22 +++++++++++-------- .../src/builders/webpack/index.ts | 18 +++++++++------ 12 files changed, 73 insertions(+), 25 deletions(-) diff --git a/goldens/public-api/angular_devkit/architect/index.api.md b/goldens/public-api/angular_devkit/architect/index.api.md index 7089d2124556..0ae8751719b5 100644 --- a/goldens/public-api/angular_devkit/architect/index.api.md +++ b/goldens/public-api/angular_devkit/architect/index.api.md @@ -25,6 +25,18 @@ export class Architect { scheduleTarget(target: Target, overrides?: json.JsonObject, scheduleOptions?: ScheduleOptions): Promise; } +// @public +export interface Builder { + // (undocumented) + [BuilderSymbol]: true; + // (undocumented) + [BuilderVersionSymbol]: string; + // (undocumented) + __OptionT: OptionT; + // (undocumented) + handler: JobHandler; +} + // @public export interface BuilderContext { addTeardown(teardown: () => Promise | void): void; diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index 1d5fc6434982..958988bb23fa 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -107,6 +107,7 @@ ts_project( "//packages/angular/ssr:ssr_rjs", "//packages/angular/ssr/node:node_rjs", "//packages/angular_devkit/architect:architect_rjs", + "//packages/angular_devkit/core:core_rjs", ], ) diff --git a/packages/angular/build/src/builders/application/index.ts b/packages/angular/build/src/builders/application/index.ts index 118f54c2013f..f8c850e5a5ab 100644 --- a/packages/angular/build/src/builders/application/index.ts +++ b/packages/angular/build/src/builders/application/index.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.dev/license */ -import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect'; +import { Builder, BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect'; +import { json } from '@angular-devkit/core'; import assert from 'node:assert'; import fs from 'node:fs/promises'; import path from 'node:path'; @@ -259,4 +260,7 @@ function generateFullPath( return fullFilePath; } -export default createBuilder(buildApplication); +const builder: Builder = + createBuilder(buildApplication); + +export default builder; diff --git a/packages/angular/build/src/builders/dev-server/index.ts b/packages/angular/build/src/builders/dev-server/index.ts index 0410d1b0f2d8..bb405cf67746 100644 --- a/packages/angular/build/src/builders/dev-server/index.ts +++ b/packages/angular/build/src/builders/dev-server/index.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.dev/license */ -import { createBuilder } from '@angular-devkit/architect'; +import { Builder, createBuilder } from '@angular-devkit/architect'; +import { json } from '@angular-devkit/core'; import { execute } from './builder'; import type { DevServerBuilderOutput } from './output'; import type { Schema as DevServerBuilderOptions } from './schema'; @@ -16,7 +17,12 @@ export { type DevServerBuilderOutput, execute as executeDevServerBuilder, }; -export default createBuilder(execute); +const builder: Builder = createBuilder< + DevServerBuilderOptions, + DevServerBuilderOutput +>(execute); + +export default builder; // Temporary export to support specs export { execute as executeDevServer }; diff --git a/packages/angular/build/src/builders/extract-i18n/index.ts b/packages/angular/build/src/builders/extract-i18n/index.ts index d751e3df5beb..fd4e1a9ccec4 100644 --- a/packages/angular/build/src/builders/extract-i18n/index.ts +++ b/packages/angular/build/src/builders/extract-i18n/index.ts @@ -6,9 +6,14 @@ * found in the LICENSE file at https://angular.dev/license */ -import { createBuilder } from '@angular-devkit/architect'; +import { Builder, createBuilder } from '@angular-devkit/architect'; +import { json } from '@angular-devkit/core'; import { execute } from './builder'; import type { Schema as ExtractI18nBuilderOptions } from './schema'; export { ExtractI18nBuilderOptions, execute }; -export default createBuilder(execute); + +const builder: Builder = + createBuilder(execute); + +export default builder; diff --git a/packages/angular/build/src/builders/ng-packagr/index.ts b/packages/angular/build/src/builders/ng-packagr/index.ts index df32d691aa43..b377fe19ced0 100644 --- a/packages/angular/build/src/builders/ng-packagr/index.ts +++ b/packages/angular/build/src/builders/ng-packagr/index.ts @@ -6,9 +6,14 @@ * found in the LICENSE file at https://angular.dev/license */ -import { createBuilder } from '@angular-devkit/architect'; +import { Builder, createBuilder } from '@angular-devkit/architect'; +import { json } from '@angular-devkit/core'; import { execute } from './builder'; import type { Schema as NgPackagrBuilderOptions } from './schema'; export { type NgPackagrBuilderOptions, execute }; -export default createBuilder(execute); + +const builder: Builder = + createBuilder(execute); + +export default builder; diff --git a/packages/angular_devkit/architect/src/create-builder.ts b/packages/angular_devkit/architect/src/create-builder.ts index c98cae63c3f2..d2fc8cfba5eb 100644 --- a/packages/angular_devkit/architect/src/create-builder.ts +++ b/packages/angular_devkit/architect/src/create-builder.ts @@ -37,6 +37,8 @@ import { Builder, BuilderSymbol, BuilderVersionSymbol } from './internal'; import { JobInboundMessageKind, createJobHandler } from './jobs'; import { scheduleByName, scheduleByTarget } from './schedule-by-name'; +export type { Builder }; + // eslint-disable-next-line max-lines-per-function export function createBuilder( fn: BuilderHandlerFn, @@ -252,6 +254,9 @@ export function createBuilder { // Metadata associated with this builder. [BuilderSymbol]: true; [BuilderVersionSymbol]: string; + __OptionT: OptionT; } export interface ArchitectHost { diff --git a/packages/angular_devkit/build_webpack/BUILD.bazel b/packages/angular_devkit/build_webpack/BUILD.bazel index 5b5eeba2aa15..8fb516402c78 100644 --- a/packages/angular_devkit/build_webpack/BUILD.bazel +++ b/packages/angular_devkit/build_webpack/BUILD.bazel @@ -50,6 +50,7 @@ ts_project( "//:node_modules/webpack", "//:node_modules/webpack-dev-server", "//packages/angular_devkit/architect:architect_rjs", + "//packages/angular_devkit/core:core_rjs", ], ) diff --git a/packages/angular_devkit/build_webpack/src/builders/webpack-dev-server/index.ts b/packages/angular_devkit/build_webpack/src/builders/webpack-dev-server/index.ts index a927f573dc10..7e21b837fcbe 100644 --- a/packages/angular_devkit/build_webpack/src/builders/webpack-dev-server/index.ts +++ b/packages/angular_devkit/build_webpack/src/builders/webpack-dev-server/index.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.dev/license */ -import { BuilderContext, createBuilder } from '@angular-devkit/architect'; +import { Builder, BuilderContext, createBuilder } from '@angular-devkit/architect'; +import { json } from '@angular-devkit/core'; import { resolve as pathResolve } from 'path'; import { Observable, from, isObservable, of, switchMap } from 'rxjs'; import webpack from 'webpack'; @@ -124,12 +125,15 @@ export function runWebpackDevServer( ); } -export default createBuilder( - (options, context) => { - const configPath = pathResolve(context.workspaceRoot, options.webpackConfig); +const builder: Builder = createBuilder< + WebpackDevServerBuilderSchema, + DevServerBuildOutput +>((options, context) => { + const configPath = pathResolve(context.workspaceRoot, options.webpackConfig); - return from(getWebpackConfig(configPath)).pipe( - switchMap((config) => runWebpackDevServer(config, context)), - ); - }, -); + return from(getWebpackConfig(configPath)).pipe( + switchMap((config) => runWebpackDevServer(config, context)), + ); +}); + +export default builder; diff --git a/packages/angular_devkit/build_webpack/src/builders/webpack/index.ts b/packages/angular_devkit/build_webpack/src/builders/webpack/index.ts index a7ef459c95b7..470b92970446 100644 --- a/packages/angular_devkit/build_webpack/src/builders/webpack/index.ts +++ b/packages/angular_devkit/build_webpack/src/builders/webpack/index.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.dev/license */ -import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect'; +import { Builder, BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect'; +import { json } from '@angular-devkit/core'; import { resolve as pathResolve } from 'path'; import { Observable, from, isObservable, of, switchMap } from 'rxjs'; import webpack from 'webpack'; @@ -120,10 +121,13 @@ export function runWebpack( ); } -export default createBuilder((options, context) => { - const configPath = pathResolve(context.workspaceRoot, options.webpackConfig); +const builder: Builder = + createBuilder((options, context) => { + const configPath = pathResolve(context.workspaceRoot, options.webpackConfig); - return from(getWebpackConfig(configPath)).pipe( - switchMap((config) => runWebpack(config, context)), - ); -}); + return from(getWebpackConfig(configPath)).pipe( + switchMap((config) => runWebpack(config, context)), + ); + }); + +export default builder;