From 37e6a3532489f08f1bbfe1c099113763f0dece6a Mon Sep 17 00:00:00 2001 From: Jeremy Milledge Date: Mon, 10 Jun 2024 17:59:32 +1000 Subject: [PATCH] feat(ui-devkit): Support pnpm to build UI extensions (#2877) --- .../ui-devkit/compile-ui-extensions.md | 2 +- .../ui-devkit/ui-extension-build-command.md | 20 +++++++++++++ .../ui-extension-compiler-options.md | 8 +++--- packages/ui-devkit/src/compiler/compile.ts | 28 +++++++++++-------- packages/ui-devkit/src/compiler/types.ts | 12 ++++++-- packages/ui-devkit/src/compiler/utils.ts | 8 +++--- 6 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-build-command.md diff --git a/docs/docs/reference/admin-ui-api/ui-devkit/compile-ui-extensions.md b/docs/docs/reference/admin-ui-api/ui-devkit/compile-ui-extensions.md index 4f0a578acf..cc1bb3dae6 100644 --- a/docs/docs/reference/admin-ui-api/ui-devkit/compile-ui-extensions.md +++ b/docs/docs/reference/admin-ui-api/ui-devkit/compile-ui-extensions.md @@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription'; ## compileUiExtensions - + Compiles the Admin UI app with the specified extensions. diff --git a/docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-build-command.md b/docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-build-command.md new file mode 100644 index 0000000000..ec0f42c04a --- /dev/null +++ b/docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-build-command.md @@ -0,0 +1,20 @@ +--- +title: "UiExtensionBuildCommand" +isDefaultIndex: false +generated: true +--- + +import MemberInfo from '@site/src/components/MemberInfo'; +import GenerationInfo from '@site/src/components/GenerationInfo'; +import MemberDescription from '@site/src/components/MemberDescription'; + + +## UiExtensionBuildCommand + + + +The package manager to use when invoking the Angular CLI to build UI extensions. + +```ts title="Signature" +type UiExtensionBuildCommand = 'npm' | 'yarn' | 'pnpm' +``` diff --git a/docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-options.md b/docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-options.md index 26fc9826b7..574a6c0d1b 100644 --- a/docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-options.md +++ b/docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-options.md @@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription'; ## UiExtensionCompilerOptions - + Options to configure how the Admin UI should be compiled. @@ -23,7 +23,7 @@ interface UiExtensionCompilerOptions { devMode?: boolean; baseHref?: string; watchPort?: number; - command?: 'yarn' | 'npm'; + command?: UiExtensionBuildCommand; additionalProcessArguments?: UiExtensionCompilerProcessArgument[]; } ``` @@ -102,11 +102,11 @@ In watch mode, allows the port of the dev server to be specified. Defaults to th of `4200`. ### command - +UiExtensionBuildCommand`} since="1.5.0" /> Internally, the Angular CLI will be invoked as an npm script. By default, the compiler will use Yarn to run the script if it is detected, otherwise it will use npm. This setting allows you to explicitly -set which command to use, rather than relying on the default behavior. +set which command to use, including pnpm, rather than relying on the default behavior. ### additionalProcessArguments UiExtensionCompilerProcessArgument[]`} default="undefined" since="1.5.0" /> diff --git a/packages/ui-devkit/src/compiler/compile.ts b/packages/ui-devkit/src/compiler/compile.ts index bd637a5f4c..09c0cf2269 100644 --- a/packages/ui-devkit/src/compiler/compile.ts +++ b/packages/ui-devkit/src/compiler/compile.ts @@ -11,19 +11,20 @@ import { copyGlobalStyleFile, setBaseHref, setupScaffold } from './scaffold'; import { getAllTranslationFiles, mergeExtensionTranslations } from './translations'; import { StaticAssetDefinition, + UiExtensionBuildCommand, UiExtensionCompilerOptions, UiExtensionCompilerProcessArgument, } from './types'; import { copyStaticAsset, copyUiDevkit, + determinePackageManager, getStaticAssetPath, isAdminUiExtension, isGlobalStylesExtension, isStaticAssetExtension, isTranslationExtension, normalizeExtensions, - shouldUseYarn, } from './utils'; /** @@ -35,18 +36,21 @@ import { export function compileUiExtensions( options: UiExtensionCompilerOptions, ): AdminUiAppConfig | AdminUiAppDevModeConfig { - const { devMode, watchPort, command } = options; - const usingYarn = command && command === 'npm' ? false : shouldUseYarn(); + const { devMode, watchPort } = options; + const command: UiExtensionBuildCommand = + options.command && ['npm', 'pnpm'].includes(options.command) + ? options.command + : determinePackageManager(); if (devMode) { return runWatchMode({ watchPort: watchPort || 4200, - usingYarn, ...options, + command, }); } else { return runCompileMode({ - usingYarn, ...options, + command, }); } } @@ -55,10 +59,10 @@ function runCompileMode({ outputPath, baseHref, extensions, - usingYarn, + command, additionalProcessArguments, ngCompilerPath, -}: UiExtensionCompilerOptions & { usingYarn: boolean }): AdminUiAppConfig { +}: UiExtensionCompilerOptions & { command: UiExtensionBuildCommand }): AdminUiAppConfig { const distPath = path.join(outputPath, 'dist'); const compile = () => @@ -66,13 +70,13 @@ function runCompileMode({ await setupScaffold(outputPath, extensions); await setBaseHref(outputPath, baseHref || DEFAULT_BASE_HREF); - let cmd = usingYarn ? 'yarn' : 'npm'; + let cmd: UiExtensionBuildCommand | 'node' = command; let commandArgs = ['run', 'build']; if (ngCompilerPath) { cmd = 'node'; commandArgs = [ngCompilerPath, 'build', '--configuration production']; } else { - if (!usingYarn) { + if (cmd === 'npm') { // npm requires `--` before any command line args being passed to a script commandArgs.splice(2, 0, '--'); } @@ -109,10 +113,10 @@ function runWatchMode({ baseHref, watchPort, extensions, - usingYarn, + command, additionalProcessArguments, ngCompilerPath, -}: UiExtensionCompilerOptions & { usingYarn: boolean }): AdminUiAppDevModeConfig { +}: UiExtensionCompilerOptions & { command: UiExtensionBuildCommand }): AdminUiAppDevModeConfig { const devkitPath = require.resolve('@vendure/ui-devkit'); let buildProcess: ChildProcess; let watcher: FSWatcher | undefined; @@ -128,7 +132,7 @@ function runWatchMode({ const globalStylesExtensions = extensions.filter(isGlobalStylesExtension); const staticAssetExtensions = extensions.filter(isStaticAssetExtension); const allTranslationFiles = getAllTranslationFiles(extensions.filter(isTranslationExtension)); - let cmd = usingYarn ? 'yarn' : 'npm'; + let cmd: UiExtensionBuildCommand | 'node' = command; let commandArgs = ['run', 'start']; if (ngCompilerPath) { cmd = 'node'; diff --git a/packages/ui-devkit/src/compiler/types.ts b/packages/ui-devkit/src/compiler/types.ts index 4d91d8bc6f..2e2c4d4b1e 100644 --- a/packages/ui-devkit/src/compiler/types.ts +++ b/packages/ui-devkit/src/compiler/types.ts @@ -347,6 +347,14 @@ export interface AdminUiExtensionLazyModule { */ export type UiExtensionCompilerProcessArgument = string | [string, any]; +/** + * @description + * The package manager to use when invoking the Angular CLI to build UI extensions. + * + * @docsCategory UiDevkit + */ +export type UiExtensionBuildCommand = 'npm' | 'yarn' | 'pnpm'; + /** * @description * Options to configure how the Admin UI should be compiled. @@ -435,11 +443,11 @@ export interface UiExtensionCompilerOptions { * @description * Internally, the Angular CLI will be invoked as an npm script. By default, the compiler will use Yarn * to run the script if it is detected, otherwise it will use npm. This setting allows you to explicitly - * set which command to use, rather than relying on the default behavior. + * set which command to use, including pnpm, rather than relying on the default behavior. * * @since 1.5.0 */ - command?: 'yarn' | 'npm'; + command?: UiExtensionBuildCommand; /** * @description diff --git a/packages/ui-devkit/src/compiler/utils.ts b/packages/ui-devkit/src/compiler/utils.ts index 59d8c33ecb..b65191e19e 100644 --- a/packages/ui-devkit/src/compiler/utils.ts +++ b/packages/ui-devkit/src/compiler/utils.ts @@ -23,14 +23,14 @@ export const logger = { }; /** - * Checks for the global yarn binary and returns true if found. + * Checks for the global yarn binary to determine whether to use yarn or npm. */ -export function shouldUseYarn(): boolean { +export function determinePackageManager(): 'yarn' | 'npm' { try { execSync('yarnpkg --version', { stdio: 'ignore' }); - return true; + return 'yarn'; } catch (e: any) { - return false; + return 'npm'; } }