| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 8c273b0 commit 76dd17d
13 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,14 +24,11 @@ import { purgeStaleBuildCache } from '../../utils/purge-cache'; | |||
| 24 | 24 | import { getSupportedBrowsers } from '../../utils/supported-browsers'; | |
| 25 | 25 | import { assertCompatibleAngularVersion } from '../../utils/version'; | |
| 26 | 26 | import type { BuildWatcher } from '../../utils/watcher'; | |
| 27 | - import { | ||
| 28 | - type NormalizedLibraryOptions, | ||
| 29 | - type PackageJsonData, | ||
| 30 | - normalizeLibraryOptions, | ||
| 31 | - } from './options'; | ||
| 32 | - import type { SingleBuildState } from './pipeline/build-action'; | ||
| 27 | + import { normalizeLibraryOptions } from './options'; | ||
| 28 | + import { updateWatchedEntryPoints } from './pipeline/entry-points'; | ||
| 33 | 29 | import type { createComponentStylesheetBundlerForLibrary } from './pipeline/stylesheet-bundler'; | |
| 34 | 30 | import type { Schema as LibraryBuilderOptions } from './schema'; | |
| 31 | + import type { NormalizedLibraryOptions, PackageJsonData, SingleBuildState } from './types'; | ||
| 35 | 32 | ||
| 36 | 33 | /** | |
| 37 | 34 | * Executes the library builder to compile, bundle, and package an Angular library into the Angular Package Format (APF). | |
@@ -275,6 +272,19 @@ async function* runWatchLoop( | |||
| 275 | 272 | try { | |
| 276 | 273 | const packageJson = await loadPackageJson(packageJsonPath); | |
| 277 | 274 | options.packageJson = packageJson; | |
| 275 | + if (!packageJson.name) { | ||
| 276 | + throw new Error(`The package.json at '${packageJsonPath}' must contain a 'name'.`); | ||
| 277 | + } | ||
| 278 | + options.packageName = packageJson.name; | ||
| 279 | + | ||
| 280 | + updateWatchedEntryPoints( | ||
| 281 | + packageJson, | ||
| 282 | + options, | ||
| 283 | + buildState, | ||
| 284 | + allWatchedFiles, | ||
| 285 | + packageJsonPath, | ||
| 286 | + ); | ||
| 287 | + | ||
| 278 | 288 | hasPackageJsonChanges = true; | |
| 279 | 289 | } catch (error) { | |
| 280 | 290 | assertIsError(error); | |
@@ -290,7 +300,8 @@ async function* runWatchLoop( | |||
| 290 | 300 | ||
| 291 | 301 | const hasSourceChanges = | |
| 292 | 302 | !buildState.singleProgramCache || | |
| 293 | - Boolean(buildState.hasCompilationError) || | ||
| 303 | + buildState.hasCompilationError || | ||
| 304 | + buildState.hasEntryPointsChanges || | ||
| 294 | 305 | hasModifiedWatchedFile(changedFiles, allWatchedFiles, posixPackageJsonPath); | |
| 295 | 306 | ||
| 296 | 307 | if ( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,66 +14,16 @@ import { normalizeAssetPatterns } from '../../utils'; | |||
| 14 | 14 | import { supportColor } from '../../utils/color'; | |
| 15 | 15 | import { assertIsError } from '../../utils/error'; | |
| 16 | 16 | import { normalizeCacheOptions } from '../../utils/normalize-cache'; | |
| 17 | - import { isSubDirectory, toPosixPath } from '../../utils/path'; | ||
| 17 | + import { isSubDirectory } from '../../utils/path'; | ||
| 18 | 18 | import { | |
| 19 | - type PostcssConfiguration, | ||
| 20 | 19 | generateSearchDirectories, | |
| 21 | 20 | getTailwindConfig, | |
| 22 | 21 | loadPostcssConfiguration, | |
| 23 | 22 | } from '../../utils/postcss-configuration'; | |
| 24 | 23 | import { getProjectRootPaths } from '../../utils/project-metadata'; | |
| 25 | - import { type NormalizedEntryPoint, getEntryPointBundleName } from './pipeline/entry-points'; | ||
| 24 | + import { normalizeEntryPoints } from './pipeline/entry-points'; | ||
| 26 | 25 | import type { Schema as LibraryBuilderOptions } from './schema'; | |
| 27 | - | ||
| 28 | - export type { NormalizedEntryPoint } from './pipeline/entry-points'; | ||
| 29 | - | ||
| 30 | - export interface PackageJsonData { | ||
| 31 | - name: string; | ||
| 32 | - version?: string; | ||
| 33 | - type?: string; | ||
| 34 | - main?: string; | ||
| 35 | - module?: string; | ||
| 36 | - typings?: string; | ||
| 37 | - types?: string; | ||
| 38 | - sideEffects?: boolean | string[]; | ||
| 39 | - exports?: string | Record<string, unknown>; | ||
| 40 | - scripts?: Record<string, string>; | ||
| 41 | - workspaces?: unknown; | ||
| 42 | - dependencies?: Record<string, string>; | ||
| 43 | - optionalDependencies?: Record<string, string>; | ||
| 44 | - peerDependencies?: Record<string, string>; | ||
| 45 | - peerDependenciesMeta?: Record<string, { optional?: boolean }>; | ||
| 46 | - [key: string]: unknown; | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | - export interface NormalizedLibraryOptions { | ||
| 50 | - workspaceRoot: string; | ||
| 51 | - projectRoot: string; | ||
| 52 | - packageName: string; | ||
| 53 | - packageJson: PackageJsonData; | ||
| 54 | - outputPath: string; | ||
| 55 | - deleteOutputPath: boolean; | ||
| 56 | - packageJsonPath: string; | ||
| 57 | - tsConfigPath: string; | ||
| 58 | - entryPoints: Map<string, NormalizedEntryPoint>; | ||
| 59 | - inlineStyleLanguage: 'css' | 'less' | 'sass' | 'scss'; | ||
| 60 | - styleIncludePaths: string[]; | ||
| 61 | - sass?: StylesheetPluginsass; | ||
| 62 | - assets: ReturnType<typeof normalizeAssetPatterns>; | ||
| 63 | - compilationMode: 'partial' | 'full'; | ||
| 64 | - declarationMap: boolean; | ||
| 65 | - allowedNonPeerDependencies: RegExp[]; | ||
| 66 | - keepLifecycleScripts: boolean; | ||
| 67 | - watch: boolean; | ||
| 68 | - poll?: number; | ||
| 69 | - preserveSymlinks: boolean; | ||
| 70 | - progress: boolean; | ||
| 71 | - clearScreen?: boolean; | ||
| 72 | - cacheOptions: ReturnType<typeof normalizeCacheOptions>; | ||
| 73 | - postcssConfiguration?: { config: PostcssConfiguration; configPath: string }; | ||
| 74 | - tailwindConfiguration?: { file: string; package: string }; | ||
| 75 | - colors: boolean; | ||
| 76 | - } | ||
| 26 | + import type { NormalizedLibraryOptions, PackageJsonData } from './types'; | ||
| 77 | 27 | ||
| 78 | 28 | export async function normalizeLibraryOptions( | |
| 79 | 29 | context: BuilderContext, | |
@@ -217,147 +167,3 @@ export async function normalizeLibraryOptions( | |||
| 217 | 167 | tailwindConfiguration, | |
| 218 | 168 | }; | |
| 219 | 169 | } | |
| 220 | - | ||
| 221 | - /** | ||
| 222 | - * Normalizes a single entry point specification. | ||
| 223 | - * | ||
| 224 | - * @param key The entry point key from package.json exports (e.g. '.' or './testing'). | ||
| 225 | - * @param posixKey Normalized POSIX key without trailing slashes. | ||
| 226 | - * @param isPrimary Whether this is the primary entry point. | ||
| 227 | - * @param targetPath The relative file path string from exports. | ||
| 228 | - * @param projectRoot The library project root directory. | ||
| 229 | - * @param packageName The root package name (e.g. `@my/lib`). | ||
| 230 | - * @returns The normalized entry point descriptor. | ||
| 231 | - */ | ||
| 232 | - function normalizeEntryPoint( | ||
| 233 | - key: string, | ||
| 234 | - posixKey: string, | ||
| 235 | - isPrimary: boolean, | ||
| 236 | - targetPath: string, | ||
| 237 | - projectRoot: string, | ||
| 238 | - packageName: string, | ||
| 239 | - ): NormalizedEntryPoint { | ||
| 240 | - const name = isPrimary | ||
| 241 | - ? '.' | ||
| 242 | - : posixKey[0] === '.' && posixKey[1] === '/' | ||
| 243 | - ? posixKey.slice(2) | ||
| 244 | - : posixKey; | ||
| 245 | - | ||
| 246 | - if (name !== '.' && (path.posix.isAbsolute(name) || name.includes('..'))) { | ||
| 247 | - throw new Error( | ||
| 248 | - `Invalid entry point key '${key}'. Entry point keys must be relative subpaths without '..' (e.g. './testing').`, | ||
| 249 | - ); | ||
| 250 | - } | ||
| 251 | - | ||
| 252 | - const subpath = isPrimary ? '.' : `./${name}`; | ||
| 253 | - const displayName = isPrimary ? packageName : `${packageName}/${name}`; | ||
| 254 | - const bundleName = getEntryPointBundleName(packageName, name); | ||
| 255 | - | ||
| 256 | - const entryFilePath = path.resolve(projectRoot, targetPath); | ||
| 257 | - | ||
| 258 | - if (!/(?<!\.d)\.(?:ts|mts)$/.test(entryFilePath)) { | ||
| 259 | - throw new Error( | ||
| 260 | - `Entry point '${key}' file path must be a TypeScript file ('.ts' or '.mts'): '${entryFilePath}'.`, | ||
| 261 | - ); | ||
| 262 | - } | ||
| 263 | - | ||
| 264 | - return { | ||
| 265 | - subpath, | ||
| 266 | - name, | ||
| 267 | - displayName, | ||
| 268 | - bundleName, | ||
| 269 | - entryFilePath, | ||
| 270 | - isPrimary, | ||
| 271 | - }; | ||
| 272 | - } | ||
| 273 | - | ||
| 274 | - /** | ||
| 275 | - * Normalizes all entry points from the library's `package.json` `exports` field. | ||
| 276 | - * | ||
| 277 | - * @param rawExports The `exports` field from `package.json`. | ||
| 278 | - * @param projectRoot The library project root directory. | ||
| 279 | - * @param packageJsonPath Path to `package.json` for error reporting. | ||
| 280 | - * @param packageName The root package name (e.g. `@my/lib`). | ||
| 281 | - * @returns A Map of normalized entry points keyed by name. | ||
| 282 | - */ | ||
| 283 | - function normalizeEntryPoints( | ||
| 284 | - rawExports: PackageJsonData['exports'], | ||
| 285 | - projectRoot: string, | ||
| 286 | - packageJsonPath: string, | ||
| 287 | - packageName: string, | ||
| 288 | - ): Map<string, NormalizedEntryPoint> { | ||
| 289 | - if (!rawExports || (typeof rawExports !== 'string' && typeof rawExports !== 'object')) { | ||
| 290 | - throw new Error( | ||
| 291 | - `The 'package.json' at '${packageJsonPath}' must contain an 'exports' field defining the primary entry point ('.').`, | ||
| 292 | - ); | ||
| 293 | - } | ||
| 294 | - | ||
| 295 | - const exportsRecord = typeof rawExports === 'string' ? { '.': rawExports } : rawExports; | ||
| 296 | - | ||
| 297 | - const entryPoints = new Map<string, NormalizedEntryPoint>(); | ||
| 298 | - let hasPrimary = false; | ||
| 299 | - | ||
| 300 | - for (const [key, value] of Object.entries(exportsRecord)) { | ||
| 301 | - let target: string | undefined; | ||
| 302 | - | ||
| 303 | - if (typeof value === 'string') { | ||
| 304 | - target = value; | ||
| 305 | - } else if ( | ||
| 306 | - typeof value === 'object' && | ||
| 307 | - value !== null && | ||
| 308 | - !Array.isArray(value) && | ||
| 309 | - typeof (value as Record<string, unknown>)['default'] === 'string' | ||
| 310 | - ) { | ||
| 311 | - target = (value as Record<string, unknown>)['default'] as string; | ||
| 312 | - } | ||
| 313 | - | ||
| 314 | - const posixKey = toPosixPath(key).replace(/\/+$/, ''); | ||
| 315 | - const isPrimary = posixKey === '.' || posixKey === ''; | ||
| 316 | - | ||
| 317 | - if (!target) { | ||
| 318 | - if (isPrimary) { | ||
| 319 | - throw new Error( | ||
| 320 | - `The primary entry point '.' in '${packageJsonPath}' must specify a string path ` + | ||
| 321 | - `or a 'default' condition pointing to a TypeScript file.`, | ||
| 322 | - ); | ||
| 323 | - } | ||
| 324 | - | ||
| 325 | - // Non-JS/TS conditional export (e.g., sass/style-only subpath); preserve in package.json without compiling. | ||
| 326 | - continue; | ||
| 327 | - } | ||
| 328 | - | ||
| 329 | - if (!isPrimary && !/\.m?ts$/.test(target)) { | ||
| 330 | - // Static asset, stylesheet, or package.json export; preserve in package.json without compiling. | ||
| 331 | - continue; | ||
| 332 | - } | ||
| 333 | - | ||
| 334 | - const entryPoint = normalizeEntryPoint( | ||
| 335 | - key, | ||
| 336 | - posixKey, | ||
| 337 | - isPrimary, | ||
| 338 | - target, | ||
| 339 | - projectRoot, | ||
| 340 | - packageName, | ||
| 341 | - ); | ||
| 342 | - | ||
| 343 | - if (entryPoints.has(entryPoint.name)) { | ||
| 344 | - throw new Error( | ||
| 345 | - `Duplicate entry point detected: '${key}' resolves to the same name ('${entryPoint.name}') as an existing entry point.`, | ||
| 346 | - ); | ||
| 347 | - } | ||
| 348 | - | ||
| 349 | - entryPoints.set(entryPoint.name, entryPoint); | ||
| 350 | - | ||
| 351 | - if (entryPoint.isPrimary) { | ||
| 352 | - hasPrimary = true; | ||
| 353 | - } | ||
| 354 | - } | ||
| 355 | - | ||
| 356 | - if (!hasPrimary) { | ||
| 357 | - throw new Error( | ||
| 358 | - `The 'exports' field in '${packageJsonPath}' must contain a primary entry point with key '.'.`, | ||
| 359 | - ); | ||
| 360 | - } | ||
| 361 | - | ||
| 362 | - return entryPoints; | ||
| 363 | - } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,7 @@ import path from 'node:path'; | |||
| 11 | 11 | import picomatch from 'picomatch'; | |
| 12 | 12 | import { toPosixPath } from '../../../utils/path'; | |
| 13 | 13 | import { DEFAULT_ASSET_IGNORE, resolveAssets } from '../../../utils/resolve-assets'; | |
| 14 | - import type { NormalizedLibraryOptions } from '../options'; | ||
| 14 | + import type { NormalizedLibraryOptions } from '../types'; | ||
| 15 | 15 | import { type DiskOutputFile, createDiskOutputFile } from './utils'; | |
| 16 | 16 | ||
| 17 | 17 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,28 +11,14 @@ import { constants, copyFile, mkdir, writeFile } from 'node:fs/promises'; | |||
| 11 | 11 | import path from 'node:path'; | |
| 12 | 12 | import { emitFilesToDisk } from '../../../tools/esbuild/utils'; | |
| 13 | 13 | import { toPosixPath } from '../../../utils/path'; | |
| 14 | - import type { NormalizedLibraryOptions } from '../options'; | ||
| 14 | + import type { NormalizedLibraryOptions, SingleBuildState } from '../types'; | ||
| 15 | 15 | import { collectAssetsToEmit } from './assets'; | |
| 16 | - import { type BundleEntryPointInput, type BundleResult, bundleEntryPoints } from './bundler'; | ||
| 17 | - import { type SingleProgramCache, compileLibrary } from './compilation'; | ||
| 16 | + import { type BundleEntryPointInput, bundleEntryPoints } from './bundler'; | ||
| 17 | + import { compileLibrary } from './compilation'; | ||
| 18 | 18 | import { generatePackageManifests } from './package-manifests'; | |
| 19 | 19 | import type { createComponentStylesheetBundlerForLibrary } from './stylesheet-bundler'; | |
| 20 | 20 | import type { OutputFile } from './utils'; | |
| 21 | 21 | ||
| 22 | - /** | ||
| 23 | - * State preserved across incremental builds in watch mode. | ||
| 24 | - */ | ||
| 25 | - export interface SingleBuildState { | ||
| 26 | - singleProgramCache?: SingleProgramCache; | ||
| 27 | - previousBundleResults: Map<string, BundleResult>; | ||
| 28 | - pendingChangedEsmFiles: Set<string>; | ||
| 29 | - pendingChangedDtsFiles: Set<string>; | ||
| 30 | - hasCompilationError?: boolean; | ||
| 31 | - hasEmittedManifests?: boolean; | ||
| 32 | - hasEmittedAssets?: boolean; | ||
| 33 | - directoryExists: Set<string>; | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | 22 | /** | |
| 37 | 23 | * Creates a fresh {@link SingleBuildState} instance. | |
| 38 | 24 | */ | |
@@ -86,7 +72,8 @@ export async function buildAction(actionContext: BuildActionContext): Promise<vo | |||
| 86 | 72 | const shouldCompileEntryPoints = | |
| 87 | 73 | !modifiedFiles || | |
| 88 | 74 | !buildState.singleProgramCache || | |
| 89 | - Boolean(buildState.hasCompilationError) || | ||
| 75 | + buildState.hasCompilationError || | ||
| 76 | + buildState.hasEntryPointsChanges || | ||
| 90 | 77 | pendingChangedEsmFiles.size > 0 || | |
| 91 | 78 | pendingChangedDtsFiles.size > 0 || | |
| 92 | 79 | hasModifiedWatchedFile(modifiedFiles, allWatchedFiles, posixPackageJsonPath); | |
@@ -100,6 +87,7 @@ export async function buildAction(actionContext: BuildActionContext): Promise<vo | |||
| 100 | 87 | ||
| 101 | 88 | if (shouldCompileEntryPoints) { | |
| 102 | 89 | buildState.hasCompilationError = true; | |
| 90 | + buildState.hasEntryPointsChanges = false; | ||
| 103 | 91 | ||
| 104 | 92 | const { | |
| 105 | 93 | esmFiles, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,25 +17,14 @@ import { | |||
| 17 | 17 | } from 'rolldown'; | |
| 18 | 18 | import { dts } from 'rolldown-plugin-dts'; | |
| 19 | 19 | import { toPosixPath } from '../../../utils/path'; | |
| 20 | - import type { NormalizedEntryPoint, NormalizedLibraryOptions } from '../options'; | ||
| 20 | + import type { BundleResult, NormalizedEntryPoint, NormalizedLibraryOptions } from '../types'; | ||
| 21 | 21 | import { | |
| 22 | 22 | FESM_OUTPUT_DIR, | |
| 23 | 23 | type MemoryOutputFile, | |
| 24 | 24 | TYPES_OUTPUT_DIR, | |
| 25 | 25 | createMemoryOutputFile, | |
| 26 | 26 | } from './utils'; | |
| 27 | 27 | ||
| 28 | - /** | ||
| 29 | - * Cached module ID sets for a bundled entry point. | ||
| 30 | - */ | ||
| 31 | - export interface BundleResult { | ||
| 32 | - /** Exact set of virtual ESM module IDs bundled into this entry point. */ | ||
| 33 | - esmModuleIds: ReadonlySet<string>; | ||
| 34 | - | ||
| 35 | - /** Exact set of virtual DTS module IDs bundled into this entry point. */ | ||
| 36 | - dtsModuleIds: ReadonlySet<string>; | ||
| 37 | - } | ||
| 38 | - | ||
| 39 | 28 | /** | |
| 40 | 29 | * Output of the entry point bundling process. | |
| 41 | 30 | */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,28 +15,11 @@ import { | |||
| 15 | 15 | import type { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/component-stylesheets'; | |
| 16 | 16 | import { useTypeChecking } from '../../../utils/environment-options'; | |
| 17 | 17 | import { toPosixPath } from '../../../utils/path'; | |
| 18 | - import type { NormalizedEntryPoint, NormalizedLibraryOptions } from '../options'; | ||
| 18 | + import type { NormalizedEntryPoint, NormalizedLibraryOptions, SingleProgramCache } from '../types'; | ||
| 19 | 19 | import { isDeclarationFile, isDeclarationSourceMapFile } from './utils'; | |
| 20 | 20 | ||
| 21 | 21 | const EMITTED_EXTENSIONS = ['.js', '.mjs', '.cjs', '.d.ts', '.d.mts', '.d.cts']; | |
| 22 | 22 | ||
| 23 | - /** | ||
| 24 | - * Cached state for the single unified library compilation. | ||
| 25 | - */ | ||
| 26 | - export interface SingleProgramCache { | ||
| 27 | - /** The active Angular compilation instance. */ | ||
| 28 | - readonly compilationInstance: AngularCompilation; | ||
| 29 | - | ||
| 30 | - /** In-memory map of emitted JavaScript files keyed by relative output path. */ | ||
| 31 | - readonly esmFiles: Map<string, string>; | ||
| 32 | - | ||
| 33 | - /** In-memory map of emitted TypeScript declaration files keyed by relative output path. */ | ||
| 34 | - readonly dtsFiles: Map<string, string>; | ||
| 35 | - | ||
| 36 | - /** Set of file paths that failed during stylesheet bundling or compilation. */ | ||
| 37 | - readonly failedFiles?: ReadonlySet<string>; | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | 23 | /** | |
| 41 | 24 | * Output of the unified library compilation step. | |
| 42 | 25 | */ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments