diff --git a/docs/generated/devkit/PackageManager.md b/docs/generated/devkit/PackageManager.md index e633d8c96104f..0bcc0a1292158 100644 --- a/docs/generated/devkit/PackageManager.md +++ b/docs/generated/devkit/PackageManager.md @@ -1,3 +1,3 @@ # Type alias: PackageManager -Ƭ **PackageManager**: `"yarn"` \| `"pnpm"` \| `"npm"` +Ƭ **PackageManager**: `"yarn"` \| `"pnpm"` \| `"npm"` \| `"bun"` diff --git a/package.json b/package.json index 2a24a1580be27..49d81bc0c0898 100644 --- a/package.json +++ b/package.json @@ -253,7 +253,6 @@ "react-refresh": "^0.10.0", "react-router-dom": "^6.21.2", "react-textarea-autosize": "^8.5.3", - "regenerator-runtime": "0.13.7", "resolve.exports": "1.1.0", "rollup": "^2.56.2", "rollup-plugin-copy": "^3.4.0", @@ -373,4 +372,4 @@ "documentation" ] } -} +} \ No newline at end of file diff --git a/packages/expo/src/generators/application/lib/create-application-files.ts b/packages/expo/src/generators/application/lib/create-application-files.ts index 4efeee3201053..a8fed6092bf9c 100644 --- a/packages/expo/src/generators/application/lib/create-application-files.ts +++ b/packages/expo/src/generators/application/lib/create-application-files.ts @@ -14,6 +14,7 @@ export function createApplicationFiles(host: Tree, options: NormalizedSchema) { npm: 'package-lock.json', yarn: 'yarn.lock', pnpm: 'pnpm-lock.yaml', + bun: 'bun.lockb', }; const packageManager = detectPackageManager(host.root); const packageLockFile = packageManagerLockFile[packageManager]; diff --git a/packages/expo/src/migrations/update-16-1-4/update-eas-scripts.ts b/packages/expo/src/migrations/update-16-1-4/update-eas-scripts.ts index 77db80bcee71f..61f473936a099 100644 --- a/packages/expo/src/migrations/update-16-1-4/update-eas-scripts.ts +++ b/packages/expo/src/migrations/update-16-1-4/update-eas-scripts.ts @@ -19,6 +19,7 @@ export default function update(tree: Tree) { npm: 'package-lock.json', yarn: 'yarn.lock', pnpm: 'pnpm-lock.yaml', + bun: 'bun.lockb', }; for (const [name, config] of projects.entries()) { diff --git a/packages/nx/src/command-line/nx-commands.ts b/packages/nx/src/command-line/nx-commands.ts index 2fec55f99b9ed..ee4a89368346f 100644 --- a/packages/nx/src/command-line/nx-commands.ts +++ b/packages/nx/src/command-line/nx-commands.ts @@ -53,7 +53,7 @@ export const parserConfiguration: Partial = { * from the `.argv` call, so the object and it's relative scripts can * le executed correctly. */ -export const commandsObject = yargs +export const commandsObject: any = yargs .parserConfiguration(parserConfiguration) .usage(chalk.bold('Smart Monorepos · Fast CI')) .demandCommand(1, '') diff --git a/packages/nx/src/command-line/release/command-object.ts b/packages/nx/src/command-line/release/command-object.ts index 6302d7543b458..790b9b67f8a5f 100644 --- a/packages/nx/src/command-line/release/command-object.ts +++ b/packages/nx/src/command-line/release/command-object.ts @@ -115,8 +115,8 @@ export const yargsReleaseCommand: CommandModule< ); } const nxJson = readNxJson(); - if (argv.groups?.length) { - for (const group of argv.groups) { + if ((argv.groups as string[] | string)?.length) { + for (const group of argv.groups as string[] | string) { if (!nxJson.release?.groups?.[group]) { throw new Error( `The specified release group "${group}" was not found in nx.json` diff --git a/packages/nx/src/command-line/release/publish.ts b/packages/nx/src/command-line/release/publish.ts index c12e3ae9fddc5..47811009b8cd0 100644 --- a/packages/nx/src/command-line/release/publish.ts +++ b/packages/nx/src/command-line/release/publish.ts @@ -136,7 +136,7 @@ async function runPublishOnProjects( (projectName) => projectGraph.nodes[projectName] ); - const overrides = createOverrides(args.__overrides_unparsed__); + const overrides: any = createOverrides(args.__overrides_unparsed__); if (args.registry) { overrides.registry = args.registry; diff --git a/packages/nx/src/utils/command-line-utils.ts b/packages/nx/src/utils/command-line-utils.ts index 1208c6c51b1d5..341bbe6e4f4af 100644 --- a/packages/nx/src/utils/command-line-utils.ts +++ b/packages/nx/src/utils/command-line-utils.ts @@ -39,7 +39,7 @@ export interface NxArgs { } export function createOverrides(__overrides_unparsed__: string[] = []) { - let overrides = + let overrides: any = yargsParser(__overrides_unparsed__, { configuration: { 'camel-case-expansion': false, diff --git a/packages/nx/src/utils/package-manager.spec.ts b/packages/nx/src/utils/package-manager.spec.ts index 3ba3c7d8acfe1..c198e749bc99a 100644 --- a/packages/nx/src/utils/package-manager.spec.ts +++ b/packages/nx/src/utils/package-manager.spec.ts @@ -16,57 +16,87 @@ describe('package-manager', () => { packageManager: 'pnpm', }, }); + jest.spyOn(fs, 'existsSync').mockImplementation((p) => { + switch (p) { + case 'pnpm-lock.yaml': + return true; + case 'yarn.lock': + return false; + case 'package-lock.json': + return false; + case 'bun.lockb': + return false; + default: + return jest.requireActual('fs').existsSync(p); + } + }); const packageManager = detectPackageManager(); expect(packageManager).toEqual('pnpm'); }); it('should detect yarn package manager from yarn.lock', () => { - jest.spyOn(configModule, 'readNxJson').mockReturnValueOnce({}); + jest.spyOn(configModule, 'readNxJson').mockReturnValueOnce({ + cli: { + packageManager: 'yarn', + }, + }); jest.spyOn(fs, 'existsSync').mockImplementation((p) => { switch (p) { - case 'yarn.lock': - return true; case 'pnpm-lock.yaml': return false; + case 'yarn.lock': + return true; case 'package-lock.json': return false; + case 'bun.lockb': + return false; default: return jest.requireActual('fs').existsSync(p); } }); const packageManager = detectPackageManager(); expect(packageManager).toEqual('yarn'); - expect(fs.existsSync).toHaveBeenNthCalledWith(1, 'yarn.lock'); }); - it('should detect pnpm package manager from pnpm-lock.yaml', () => { - jest.spyOn(configModule, 'readNxJson').mockReturnValueOnce({}); + it('should detect package manager in nxJson', () => { + jest.spyOn(configModule, 'readNxJson').mockReturnValueOnce({ + cli: { + packageManager: 'bun', + }, + }); jest.spyOn(fs, 'existsSync').mockImplementation((p) => { switch (p) { + case 'pnpm-lock.yaml': + return false; case 'yarn.lock': return false; - case 'pnpm-lock.yaml': - return true; case 'package-lock.json': return false; + case 'bun.lockb': + return true; default: return jest.requireActual('fs').existsSync(p); } }); const packageManager = detectPackageManager(); - expect(packageManager).toEqual('pnpm'); - expect(fs.existsSync).toHaveBeenCalledTimes(3); + expect(packageManager).toEqual('bun'); }); it('should use npm package manager as default', () => { - jest.spyOn(configModule, 'readNxJson').mockReturnValueOnce({}); + jest.spyOn(configModule, 'readNxJson').mockReturnValueOnce({ + cli: { + packageManager: 'npm', + }, + }); jest.spyOn(fs, 'existsSync').mockImplementation((p) => { switch (p) { - case 'yarn.lock': - return false; case 'pnpm-lock.yaml': return false; + case 'yarn.lock': + return false; case 'package-lock.json': + return true; + case 'bun.lockb': return false; default: return jest.requireActual('fs').existsSync(p); @@ -74,7 +104,6 @@ describe('package-manager', () => { }); const packageManager = detectPackageManager(); expect(packageManager).toEqual('npm'); - expect(fs.existsSync).toHaveBeenCalledTimes(5); }); }); diff --git a/packages/nx/src/utils/package-manager.ts b/packages/nx/src/utils/package-manager.ts index eebfc8d33fedf..fd2c94eeeb0b1 100644 --- a/packages/nx/src/utils/package-manager.ts +++ b/packages/nx/src/utils/package-manager.ts @@ -13,7 +13,7 @@ import { workspaceRoot } from './workspace-root'; const execAsync = promisify(exec); -export type PackageManager = 'yarn' | 'pnpm' | 'npm'; +export type PackageManager = 'yarn' | 'pnpm' | 'npm' | 'bun'; export interface PackageManagerCommands { preInstall?: string; @@ -29,19 +29,26 @@ export interface PackageManagerCommands { run: (script: string, args: string) => string; } +/** + * Detects which package manager is used in the workspace based on the lock file. + */ +function getPackageManager(dir: string = '') { + return existsSync(join(dir, 'yarn.lock')) + ? 'yarn' + : existsSync(join(dir, 'bun.lockb')) + ? 'bun' + : existsSync(join(dir, 'pnpm-lock.yaml')) || + existsSync(join(dir, 'pnpm-workspace.yaml')) + ? 'pnpm' + : 'npm'; +} + /** * Detects which package manager is used in the workspace based on the lock file. */ export function detectPackageManager(dir: string = ''): PackageManager { const nxJson = readNxJson(); - return ( - nxJson.cli?.packageManager ?? - (existsSync(join(dir, 'yarn.lock')) - ? 'yarn' - : existsSync(join(dir, 'pnpm-lock.yaml')) - ? 'pnpm' - : 'npm') - ); + return nxJson.cli?.packageManager ?? getPackageManager(dir); } /** @@ -126,7 +133,6 @@ export function getPackageManagerCommand( }; }, npm: () => { - // TODO: Remove this process.env.npm_config_legacy_peer_deps ??= 'true'; return { @@ -142,6 +148,20 @@ export function getPackageManagerCommand( list: 'npm ls', }; }, + bun: () => { + return { + install: 'bun install', + ciInstall: 'bun install --no-cache', + updateLockFile: 'bun install --frozen-lockfile', + add: 'bun install', + addDev: 'bun install -D', + rm: 'bun rm', + exec: 'bun', + dlx: 'bunx', + run: (script: string, args: string) => `bun run ${script} -- ${args}`, + list: 'bun pm ls', + }; + }, }; return commands[packageManager](); @@ -230,7 +250,12 @@ export function copyPackageManagerConfigurationFiles( root: string, destination: string ) { - for (const packageManagerConfigFile of ['.npmrc', '.yarnrc', '.yarnrc.yml']) { + for (const packageManagerConfigFile of [ + '.npmrc', + '.yarnrc', + '.yarnrc.yml', + 'bunfig.toml', + ]) { // f is an absolute path, including the {workspaceRoot}. const f = findFileInPackageJsonDirectory(packageManagerConfigFile, root); if (f) { @@ -243,6 +268,10 @@ export function copyPackageManagerConfigurationFiles( copyFileSync(f, destinationPath); break; } + case 'bunfig.toml': { + copyFileSync(f, destinationPath); + break; + } case '.yarnrc': { const updated = modifyYarnRcToFitNewDirectory(readFileIfExisting(f)); writeFileSync(destinationPath, updated); @@ -343,7 +372,7 @@ export async function packageRegistryView( args: string ): Promise { let pm = detectPackageManager(); - if (pm === 'yarn') { + if (pm === 'yarn' || pm === 'bun') { /** * yarn has `yarn info` but it behaves differently than (p)npm, * which makes it's usage unreliable @@ -363,7 +392,7 @@ export async function packageRegistryPack( version: string ): Promise<{ tarballPath: string }> { let pm = detectPackageManager(); - if (pm === 'yarn') { + if (pm === 'yarn' || pm === 'bun') { /** * `(p)npm pack` will download a tarball of the specified version, * whereas `yarn` pack creates a tarball of the active workspace, so it