Skip to content

Commit

Permalink
feature(create-expo): configure pnpm and yarn berry when creating a n…
Browse files Browse the repository at this point in the history
…ew project (#27699)

# Why

This should help users getting started easily when using pnpm or yarn
berry.

# How

I took a few considerations into account:
- Do NOT change existing projects, just like we don't assert/fix gradle
or cocoapods config
- Only configure the package manager once, when creating a new project
- Use the package manager itself to configure the project

# Test Plan

These commands should now start the project, without problems or
additional modifications.

- `$ pnpm create expo ./ --template tabs && pnpm expo start`

![image](https://github.com/expo/expo/assets/1203991/6cc1683d-cd58-4944-8b9f-8b1e90c11679)
- `$ yarn create expo ./ --template tabs && yarn expo start`
_Make sure you use yarn 2, 3, or 4. Yarn v1 won't configure anything and
should work as expected._

![image](https://github.com/expo/expo/assets/1203991/41864f17-959e-4cd8-87a4-7b0201b1962b)


# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
This is required for changes to Expo modules.
-->

- [ ] Documentation is up to date to reflect these changes (eg:
https://docs.expo.dev and README.md).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
  • Loading branch information
byCedric committed Mar 18, 2024
1 parent e906b3b commit 1090d14
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 9 deletions.
1 change: 1 addition & 0 deletions packages/create-expo/CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@
### 🎉 New features

- Add support for GitHub URLs in `--template` option. ([#26554](https://github.com/expo/expo/pull/26554) by [@byCedric](https://github.com/byCedric))
- Add auto-configuration for pnpm and yarn berry. ([#27699](https://github.com/expo/expo/pull/27699) by [@byCedric](https://github.com/byCedric))

### 🐛 Bug fixes

Expand Down
2 changes: 2 additions & 0 deletions packages/create-expo/src/createAsync.ts
Expand Up @@ -12,6 +12,7 @@ import * as Template from './Template';
import { promptTemplateAsync } from './legacyTemplates';
import { Log } from './log';
import {
configurePackageManager,
installDependenciesAsync,
PackageManagerName,
resolvePackageManager,
Expand Down Expand Up @@ -190,6 +191,7 @@ async function installNodeDependenciesAsync(
packageManager: PackageManagerName
): Promise<void> {
try {
await configurePackageManager(projectRoot, packageManager, { silent: false });
await installDependenciesAsync(projectRoot, packageManager, { silent: false });
} catch (error: any) {
debug(`Error installing node modules: %O`, error);
Expand Down
53 changes: 44 additions & 9 deletions packages/create-expo/src/resolvePackageManager.ts
Expand Up @@ -70,19 +70,54 @@ export function formatSelfCommand() {
}
}

function createPackageManager(
packageManager: PackageManagerName,
options?: PackageManager.PackageManagerOptions
) {
switch (packageManager) {
case 'yarn':
return new PackageManager.YarnPackageManager(options);
case 'pnpm':
return new PackageManager.PnpmPackageManager(options);
case 'bun':
return new PackageManager.BunPackageManager(options);
case 'npm':
default:
return new PackageManager.NpmPackageManager(options);
}
}

export async function installDependenciesAsync(
projectRoot: string,
packageManager: PackageManagerName,
flags: { silent: boolean } = { silent: false }
) {
const options = { cwd: projectRoot, silent: flags.silent };
if (packageManager === 'yarn') {
await new PackageManager.YarnPackageManager(options).installAsync();
} else if (packageManager === 'pnpm') {
await new PackageManager.PnpmPackageManager(options).installAsync();
} else if (packageManager === 'bun') {
await new PackageManager.BunPackageManager(options).installAsync();
} else {
await new PackageManager.NpmPackageManager(options).installAsync();
await createPackageManager(packageManager, {
cwd: projectRoot,
silent: flags.silent,
}).installAsync();
}

export async function configurePackageManager(
projectRoot: string,
packageManager: PackageManagerName,
flags: { silent: boolean } = { silent: false }
) {
const manager = createPackageManager(packageManager, { cwd: projectRoot, ...flags });
switch (manager.name) {
case 'pnpm':
await manager.runAsync(['config', '--location', 'project', 'set', 'node-linker', 'hoisted']);
break;

case 'yarn': {
const yarnVersion = await manager.versionAsync();
const majorVersion = parseInt(yarnVersion.split('.')[0], 10);

if (majorVersion >= 2) {
await manager.runAsync(['config', 'set', 'nodeLinker', 'node-modules']);
}

break;
}
}
}

0 comments on commit 1090d14

Please sign in to comment.