Skip to content

Commit

Permalink
feat(core): add bun package manager
Browse files Browse the repository at this point in the history
Bun uses yarn lock for it's binary file. Running the binary will produce the content of a yarn lock file (v1)
  • Loading branch information
Jordan-Hall committed Apr 2, 2024
1 parent 120cde6 commit d0eb306
Show file tree
Hide file tree
Showing 17 changed files with 237 additions and 117 deletions.
2 changes: 1 addition & 1 deletion docs/generated/cli/create-nx-workspace.md
Expand Up @@ -129,7 +129,7 @@ Do you want Nx Cloud to make your CI fast?

Type: `string`

Choices: [npm, pnpm, yarn]
Choices: [bun, npm, pnpm, yarn]

Default: `npm`

Expand Down
2 changes: 1 addition & 1 deletion docs/generated/devkit/PackageManager.md
@@ -1,3 +1,3 @@
# Type alias: PackageManager

Ƭ **PackageManager**: `"yarn"` \| `"pnpm"` \| `"npm"`
Ƭ **PackageManager**: `"yarn"` \| `"pnpm"` \| `"npm"` \| `"bun"`
Expand Up @@ -129,7 +129,7 @@ Do you want Nx Cloud to make your CI fast?

Type: `string`

Choices: [npm, pnpm, yarn]
Choices: [bun, npm, pnpm, yarn]

Default: `npm`

Expand Down
61 changes: 33 additions & 28 deletions e2e/utils/create-project-utils.ts
Expand Up @@ -65,7 +65,7 @@ const nxPackages = [
`@nx/expo`,
] as const;

type NxPackage = typeof nxPackages[number];
type NxPackage = (typeof nxPackages)[number];

/**
* Sets up a new project in the temporary project path
Expand All @@ -78,7 +78,7 @@ export function newProject({
packages,
}: {
name?: string;
packageManager?: 'npm' | 'yarn' | 'pnpm';
packageManager?: 'npm' | 'yarn' | 'pnpm' | 'bun';
unsetProjectNameAndRootFormat?: boolean;
readonly packages?: Array<NxPackage>;
} = {}): string {
Expand All @@ -91,7 +91,7 @@ export function newProject({

if (!directoryExists(tmpBackupProjPath())) {
const createNxWorkspaceStart = performance.mark(
'create-nx-workspace:start'
'create-nx-workspace:start',
);
runCreateWorkspace(projScope, {
preset: 'apps',
Expand All @@ -101,12 +101,12 @@ export function newProject({
createNxWorkspaceMeasure = performance.measure(
'create-nx-workspace',
createNxWorkspaceStart.name,
createNxWorkspaceEnd.name
createNxWorkspaceEnd.name,
);

if (unsetProjectNameAndRootFormat) {
console.warn(
'ATTENTION: The workspace generated for this e2e test does not use the new as-provided project name/root format. Please update this test'
'ATTENTION: The workspace generated for this e2e test does not use the new as-provided project name/root format. Please update this test',
);
createFile('apps/.gitkeep');
createFile('libs/.gitkeep');
Expand All @@ -116,13 +116,13 @@ export function newProject({
if (isCI && packageManager === 'pnpm') {
updateFile(
'.npmrc',
'prefer-frozen-lockfile=false\nstrict-peer-dependencies=false\nauto-install-peers=true'
'prefer-frozen-lockfile=false\nstrict-peer-dependencies=false\nauto-install-peers=true',
);
}

if (!packages) {
console.warn(
'ATTENTION: All packages are installed into the new workspace. To make this test faster, please pass the subset of packages that this test needs by passing a packages array in the options'
'ATTENTION: All packages are installed into the new workspace. To make this test faster, please pass the subset of packages that this test needs by passing a packages array in the options',
);
}
const packageInstallStart = performance.mark('packageInstall:start');
Expand All @@ -131,7 +131,7 @@ export function newProject({
packageInstallMeasure = performance.measure(
'packageInstall',
packageInstallStart.name,
packageInstallEnd.name
packageInstallEnd.name,
);
// stop the daemon
execSync(`${getPackageManagerCommand().runNx} reset`, {
Expand All @@ -147,7 +147,7 @@ export function newProject({
copySync(`${tmpBackupProjPath()}`, `${projectDirectory}`);

const dependencies = readJsonFile(
`${projectDirectory}/package.json`
`${projectDirectory}/package.json`,
).devDependencies;
const missingPackages = (packages || []).filter((p) => !dependencies[p]);

Expand All @@ -168,7 +168,7 @@ export function newProject({
const perfMeasure = performance.measure(
'newProject',
newProjectStart.name,
newProjectEnd.name
newProjectEnd.name,
);

if (isVerbose()) {
Expand All @@ -189,7 +189,7 @@ ${
packageInstallMeasure.duration / 1000
} seconds\n`
: ''
}`
}`,
);
}

Expand All @@ -210,7 +210,7 @@ ${
export function addPnpmRc() {
updateFile(
'.npmrc',
'strict-peer-dependencies=false\nauto-install-peers=true'
'strict-peer-dependencies=false\nauto-install-peers=true',
);
}

Expand Down Expand Up @@ -240,7 +240,7 @@ export function runCreateWorkspace(
appName?: string;
style?: string;
base?: string;
packageManager?: 'npm' | 'yarn' | 'pnpm';
packageManager?: 'npm' | 'yarn' | 'pnpm' | 'bun';
extraArgs?: string;
useDetectedPm?: boolean;
cwd?: string;
Expand All @@ -254,7 +254,7 @@ export function runCreateWorkspace(
ssr?: boolean;
framework?: string;
prefix?: string;
}
},
) {
projName = name;

Expand Down Expand Up @@ -358,10 +358,10 @@ export function runCreatePlugin(
extraArgs,
useDetectedPm = false,
}: {
packageManager?: 'npm' | 'yarn' | 'pnpm';
packageManager?: 'npm' | 'yarn' | 'pnpm' | 'bun';
extraArgs?: string;
useDetectedPm?: boolean;
}
},
) {
projName = name;

Expand Down Expand Up @@ -406,7 +406,7 @@ export function packageInstall(
pkg: string,
projName?: string,
version = getPublishedVersion(),
mode: 'dev' | 'prod' = 'dev'
mode: 'dev' | 'prod' = 'dev',
) {
const cwd = projName ? `${e2eCwd}/${projName}` : tmpProjPath();
const pm = getPackageManagerCommand({ path: cwd });
Expand Down Expand Up @@ -448,13 +448,13 @@ export function packageInstall(
*/
export function runNgNew(
packageManager = getSelectedPackageManager(),
angularCliVersion = defaultAngularCliVersion
angularCliVersion = defaultAngularCliVersion,
): string {
const pmc = getPackageManagerCommand({ packageManager });

if (directoryExists(tmpBackupNgCliProjPath())) {
const angularJson = JSON.parse(
readFileSync(join(tmpBackupNgCliProjPath(), 'angular.json'), 'utf-8')
readFileSync(join(tmpBackupNgCliProjPath(), 'angular.json'), 'utf-8'),
);
// the name of the workspace matches the name of the generated default app,
// we need to reuse the same name that's cached in order to avoid issues
Expand All @@ -465,7 +465,7 @@ export function runNgNew(
if (isVerboseE2ERun()) {
logInfo(
`NX`,
`E2E restored an Angular CLI project from cache: ${tmpProjPath()}`
`E2E restored an Angular CLI project from cache: ${tmpProjPath()}`,
);
}

Expand Down Expand Up @@ -506,11 +506,11 @@ export function newLernaWorkspace({
'pnpm-workspace.yaml',
dump({
packages: ['packages/*'],
})
}),
);
updateFile(
'.npmrc',
'prefer-frozen-lockfile=false\nstrict-peer-dependencies=false\nauto-install-peers=true'
'prefer-frozen-lockfile=false\nstrict-peer-dependencies=false\nauto-install-peers=true',
);
}

Expand Down Expand Up @@ -543,6 +543,11 @@ export function newLernaWorkspace({
...json.resolutions,
...overrides,
};
} else if (packageManager === 'bun') {
json.overrides = {
...json.resolutions,
...overrides,
};
} else {
json.overrides = overrides;
}
Expand All @@ -558,15 +563,15 @@ export function newLernaWorkspace({
packageManager === 'pnpm'
? ' --workspace-root'
: packageManager === 'yarn'
? ' -W'
: ''
? ' -W'
: ''
}`,
{
cwd: tmpProjPath(),
stdio: isVerbose() ? 'inherit' : 'pipe',
env: { CI: 'true', ...process.env },
encoding: 'utf-8',
}
},
);

execSync(`${pm.runLerna} init`, {
Expand Down Expand Up @@ -611,7 +616,7 @@ export function newWrappedNxWorkspace({
projName = name;
ensureDirSync(tmpProjPath());
runCommand(
`${pmc.runUninstalledPackage} nx@latest init --use-dot-nx-installation`
`${pmc.runUninstalledPackage} nx@latest init --use-dot-nx-installation`,
);
return (command: string, opts: Partial<ExecSyncOptions> | undefined) => {
if (process.platform === 'win32') {
Expand All @@ -632,7 +637,7 @@ export function tmpProjPath(path?: string) {

export function createNonNxProjectDirectory(
name = uniq('proj'),
addWorkspaces = true
addWorkspaces = true,
) {
projName = name;
ensureDirSync(tmpProjPath());
Expand All @@ -641,7 +646,7 @@ export function createNonNxProjectDirectory(
JSON.stringify({
name,
workspaces: addWorkspaces ? ['packages/*'] : undefined,
})
}),
);
}

Expand Down
16 changes: 9 additions & 7 deletions e2e/utils/get-env-info.ts
Expand Up @@ -26,9 +26,11 @@ export function detectPackageManager(dir: string = ''): PackageManager {
return existsSync(join(dir, 'yarn.lock'))
? 'yarn'
: existsSync(join(dir, 'pnpm-lock.yaml')) ||
existsSync(join(dir, 'pnpm-workspace.yaml'))
? 'pnpm'
: 'npm';
existsSync(join(dir, 'pnpm-workspace.yaml'))
? 'pnpm'
: existsSync(join(dir, 'bun.lockb'))
? 'bun'
: 'npm';
}

export function isNotWindows() {
Expand Down Expand Up @@ -64,8 +66,8 @@ export function isVerboseE2ERun() {

export const e2eCwd = `${e2eRoot}/nx`;

export function getSelectedPackageManager(): 'npm' | 'yarn' | 'pnpm' {
return (process.env.SELECTED_PM as 'npm' | 'yarn' | 'pnpm') || 'npm';
export function getSelectedPackageManager(): 'npm' | 'yarn' | 'pnpm' | 'bun' {
return (process.env.SELECTED_PM as 'npm' | 'yarn' | 'pnpm' | 'bun') || 'npm';
}

export function getNpmMajorVersion(): string | undefined {
Expand Down Expand Up @@ -146,7 +148,7 @@ export function ensurePlaywrightBrowsersInstallation() {
e2eConsoleLogger(
`Playwright browsers ${execSync('npx playwright --version')
.toString()
.trim()} installed.`
.trim()} installed.`,
);
}

Expand All @@ -168,6 +170,6 @@ export function getStrippedEnvironmentVariables() {
}

return true;
})
}),
);
}
17 changes: 10 additions & 7 deletions e2e/workspace-create/src/create-nx-workspace.test.ts
Expand Up @@ -171,7 +171,7 @@ describe('create-nx-workspace', () => {
bundler: 'webpack',
ssr: false,
prefix: '1-one',
})
}),
).toThrow();
});

Expand Down Expand Up @@ -374,7 +374,7 @@ describe('create-nx-workspace', () => {
});

describe('Use detected package manager', () => {
function setupProject(envPm: 'npm' | 'yarn' | 'pnpm') {
function setupProject(envPm: 'npm' | 'yarn' | 'pnpm' | 'bun') {
process.env.SELECTED_PM = envPm;
runCreateWorkspace(uniq('pm'), {
preset: 'apps',
Expand All @@ -389,7 +389,8 @@ describe('create-nx-workspace', () => {
checkFilesExist(packageManagerLockFile['npm']);
checkFilesDoNotExist(
packageManagerLockFile['yarn'],
packageManagerLockFile['pnpm']
packageManagerLockFile['pnpm'],
packageManagerLockFile['bun'],
);
process.env.SELECTED_PM = packageManager;
}, 90000);
Expand All @@ -401,7 +402,8 @@ describe('create-nx-workspace', () => {
checkFilesExist(packageManagerLockFile['pnpm']);
checkFilesDoNotExist(
packageManagerLockFile['yarn'],
packageManagerLockFile['npm']
packageManagerLockFile['npm'],
packageManagerLockFile['bun'],
);
process.env.SELECTED_PM = packageManager;
}, 90000);
Expand All @@ -414,7 +416,8 @@ describe('create-nx-workspace', () => {
checkFilesExist(packageManagerLockFile['yarn']);
checkFilesDoNotExist(
packageManagerLockFile['pnpm'],
packageManagerLockFile['npm']
packageManagerLockFile['npm'],
packageManagerLockFile['bun'],
);
process.env.SELECTED_PM = packageManager;
}, 90000);
Expand Down Expand Up @@ -534,7 +537,7 @@ describe('create-nx-workspace yarn berry', () => {

expect(existsSync(`${tmpDir}/${wsName}/.yarnrc.yml`)).toBeTruthy();
expect(
readFileSync(`${tmpDir}/${wsName}/.yarnrc.yml`, { encoding: 'utf-8' })
readFileSync(`${tmpDir}/${wsName}/.yarnrc.yml`, { encoding: 'utf-8' }),
).toMatchInlineSnapshot(`
"nodeLinker: node-modules
Expand All @@ -554,7 +557,7 @@ describe('create-nx-workspace yarn berry', () => {

expect(existsSync(`${tmpDir}/${wsName}/.yarnrc.yml`)).toBeTruthy();
expect(
readFileSync(`${tmpDir}/${wsName}/.yarnrc.yml`, { encoding: 'utf-8' })
readFileSync(`${tmpDir}/${wsName}/.yarnrc.yml`, { encoding: 'utf-8' }),
).toMatchInlineSnapshot(`
"nodeLinker: node-modules
Expand Down

0 comments on commit d0eb306

Please sign in to comment.