Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI: Add pnpm support #19425

Merged
merged 4 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- [Docs modern inline rendering by default](#docs-modern-inline-rendering-by-default)
- [Babel mode v7 by default](#babel-mode-v7-by-default)
- [7.0 feature flags removed](#70-feature-flags-removed)
- [CLI option `--use-npm` deprecated](#cli-option---use-npm-deprecated)
- [Vite builder uses vite config automatically](#vite-builder-uses-vite-config-automatically)
- [Vite cache moved to node_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook)
- [Removed docs.getContainer and getPage parameters](#removed-docsgetcontainer-and-getpage-parameters)
Expand Down Expand Up @@ -522,6 +523,10 @@ In 7.0 we've removed the following feature flags:
| `emotionAlias` | This flag is no longer needed and should be deleted. |
| `breakingChangesV7` | This flag is no longer needed and should be deleted. |

#### CLI option `--use-npm` deprecated

With increased support for more package managers (pnpm), we have introduced the `--package-manager` CLI option. Please use `--package-manager=npm` to force NPM to be used to install dependencies when running Storybook CLI commands. Other valid options are `pnpm`, `yarn1`, and `yarn2` (`yarn2` is for versions 2 and higher).

#### Vite builder uses vite config automatically

When using a [Vite-based framework](#framework-field-mandatory), Storybook will automatically use your `vite.config.(ctm)js` config file starting in 7.0.
Expand Down
20 changes: 17 additions & 3 deletions code/lib/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,26 @@ See the command-line help with `-h` for details.

## [Yarn](https://github.com/yarnpkg/yarn) support

The CLI supports yarn. If you have installed yarn in your system and your project has `yarn.lock` file, it'll detect it and use `yarn` instead of `npm`.
The CLI supports yarn. If you have installed yarn in your system and your project has a `yarn.lock` file, it'll detect it and use `yarn` to install dependencies.

If you don't want to use `yarn` always you can use the `--use-npm` option like this:
If you don't want to use `yarn` always you can use the `--package-manager` option like this:

```sh
npx sb init --use-npm
npx sb init --package-manager=npm
```

If you would like to force a particular version of yarn, you can use the `--package-manager` flag with a value of `yarn1` or `yarn2`.

---

## [PNPM](https://pnpm.io/) support

The CLI supports pnpm. If you have installed pnpm in your system and your project has a `pnpm-lock.yaml` file, it'll detect it and use `pnpm` to install dependencies.

If you don't have a lock file and would like to force pnpm to be used, you can use the `--package-manager` option like this:

```sh
npx sb init --package-manager=pnpm
```

---
Expand Down
4 changes: 3 additions & 1 deletion code/lib/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
"shelljs": "^0.8.5",
"strip-json-comments": "^3.0.1",
"ts-dedent": "^2.0.0",
"update-notifier": "^5.0.1"
"update-notifier": "^5.0.1",
"util-deprecate": "^1.0.2"
},
"devDependencies": {
"@storybook/client-api": "7.0.0-alpha.38",
Expand All @@ -82,6 +83,7 @@
"@types/semver": "^7.3.4",
"@types/shelljs": "^0.8.7",
"@types/update-notifier": "^5.0.0",
"@types/util-deprecate": "^1.0.0",
"strip-json-comments": "^3.1.1",
"typescript": "~4.6.3",
"update-notifier": "^5.0.1"
Expand Down
17 changes: 14 additions & 3 deletions code/lib/cli/src/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { getStorybookInfo } from '@storybook/core-common';
import { readConfig, writeConfig } from '@storybook/csf-tools';

import { commandLog } from './helpers';
import { JsPackageManagerFactory } from './js-package-manager';
import {
JsPackageManagerFactory,
useNpmWarning,
type PackageManagerName,
} from './js-package-manager';

const logger = console;

Expand Down Expand Up @@ -66,8 +70,15 @@ const getVersionSpecifier = (addon: string) => {
* it will try to use the version specifier matching your current
* Storybook install version.
*/
export async function add(addon: string, options: { useNpm: boolean; skipPostinstall: boolean }) {
const packageManager = JsPackageManagerFactory.getPackageManager(options.useNpm);
export async function add(
addon: string,
options: { useNpm: boolean; packageManager: PackageManagerName; skipPostinstall: boolean }
) {
const { useNpm, packageManager: pkgMgr } = options;
if (useNpm) {
useNpmWarning();
}
const packageManager = JsPackageManagerFactory.getPackageManager({ useNpm, force: pkgMgr });
const packageJson = packageManager.retrievePackageJson();
const [addonName, versionSpecifier] = getVersionSpecifier(addon);

Expand Down
8 changes: 5 additions & 3 deletions code/lib/cli/src/automigrate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import prompts from 'prompts';
import chalk from 'chalk';
import boxen from 'boxen';
import { JsPackageManagerFactory } from '../js-package-manager';
import { JsPackageManagerFactory, type PackageManagerName } from '../js-package-manager';

import { fixes, Fix } from './fixes';

Expand All @@ -12,10 +12,12 @@ interface FixOptions {
fixId?: string;
yes?: boolean;
dryRun?: boolean;
useNpm?: boolean;
force?: PackageManagerName;
}

export const automigrate = async ({ fixId, dryRun, yes }: FixOptions = {}) => {
const packageManager = JsPackageManagerFactory.getPackageManager();
export const automigrate = async ({ fixId, dryRun, yes, useNpm, force }: FixOptions = {}) => {
const packageManager = JsPackageManagerFactory.getPackageManager({ useNpm, force });
const filtered = fixId ? fixes.filter((f) => f.id === fixId) : fixes;

logger.info('🔎 checking possible migrations..');
Expand Down
30 changes: 21 additions & 9 deletions code/lib/cli/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { sync as readUpSync } from 'read-pkg-up';

import { logger } from '@storybook/node-logger';

import { CommandOptions } from './generators/types';
import { initiate } from './initiate';
import { add } from './add';
import { migrate } from './migrate';
import { extract } from './extract';
import { upgrade } from './upgrade';
import { upgrade, type UpgradeOptions } from './upgrade';
import { repro } from './repro';
import { reproNext } from './repro-next';
import { link } from './link';
Expand All @@ -38,14 +39,15 @@ program
.description('Initialize Storybook into your project.')
.option('-f --force', 'Force add Storybook')
.option('-s --skip-install', 'Skip installing deps')
.option('-N --use-npm', 'Use npm to install deps')
.option('--use-pnp', 'Enable pnp mode')
.option('--package-manager <npm|pnpm|yarn1|yarn2>', 'Force package manager for installing deps')
.option('-N --use-npm', 'Use npm to install deps (deprecated)')
.option('--use-pnp', 'Enable pnp mode for Yarn 2+')
.option('-p --parser <babel | babylon | flow | ts | tsx>', 'jscodeshift parser')
.option('-t --type <type>', 'Add Storybook for a specific project type')
.option('-y --yes', 'Answer yes to all prompts')
.option('-b --builder <builder>', 'Builder library')
.option('-b --builder <webpack5 | vite>', 'Builder library')
.option('-l --linkable', 'Prepare installation for link (contributor helper)')
.action((options) =>
.action((options: CommandOptions) =>
initiate(options, pkg).catch((err) => {
logger.error(err);
process.exit(1);
Expand All @@ -55,9 +57,13 @@ program
program
.command('add <addon>')
.description('Add an addon to your Storybook')
.option('-N --use-npm', 'Use NPM to build the Storybook server')
.option(
'--package-manager <npm|pnpm|yarn1|yarn2>',
'Force package manager for installing dependencies'
)
.option('-N --use-npm', 'Use NPM to install dependencies (deprecated)')
.option('-s --skip-postinstall', 'Skip package specific postinstall config modifications')
.action((addonName, options) => add(addonName, options));
.action((addonName: string, options: any) => add(addonName, options));

program
.command('babelrc')
Expand All @@ -67,12 +73,16 @@ program
program
.command('upgrade')
.description('Upgrade your Storybook packages to the latest')
.option('-N --use-npm', 'Use NPM to build the Storybook server')
.option(
'--package-manager <npm|pnpm|yarn1|yarn2>',
'Force package manager for installing dependencies'
)
.option('-N --use-npm', 'Use NPM to install dependencies (deprecated)')
.option('-y --yes', 'Skip prompting the user')
.option('-n --dry-run', 'Only check for upgrades, do not install')
.option('-p --prerelease', 'Upgrade to the pre-release packages')
.option('-s --skip-check', 'Skip postinstall version and automigration checks')
.action((options) => upgrade(options));
.action((options: UpgradeOptions) => upgrade(options));

program
.command('info')
Expand Down Expand Up @@ -177,6 +187,8 @@ program
.description('Check storybook for known problems or migrations and apply fixes')
.option('-y --yes', 'Skip prompting the user')
.option('-n --dry-run', 'Only check for fixes, do not actually run them')
.option('--package-manager <npm|pnpm|yarn1|yarn2>', 'Force package manager')
.option('-N --use-npm', 'Use npm as package manager (deprecated)')
.action((fixId, options) =>
automigrate({ fixId, ...options }).catch((e) => {
logger.error(e);
Expand Down
3 changes: 2 additions & 1 deletion code/lib/cli/src/generators/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NpmOptions } from '../NpmOptions';
import { SupportedLanguage, Builder, ProjectType } from '../project_types';
import { JsPackageManager } from '../js-package-manager/JsPackageManager';
import { JsPackageManager, type PackageManagerName } from '../js-package-manager/JsPackageManager';

export type GeneratorOptions = {
language: SupportedLanguage;
Expand Down Expand Up @@ -31,6 +31,7 @@ export type Generator = (
) => Promise<void>;

export type CommandOptions = {
packageManager: PackageManagerName;
useNpm?: boolean;
usePnp?: boolean;
type?: ProjectType;
Expand Down
12 changes: 8 additions & 4 deletions code/lib/cli/src/initiate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import preactGenerator from './generators/PREACT';
import svelteGenerator from './generators/SVELTE';
import raxGenerator from './generators/RAX';
import serverGenerator from './generators/SERVER';
import { JsPackageManagerFactory, JsPackageManager } from './js-package-manager';
import { JsPackageManagerFactory, JsPackageManager, useNpmWarning } from './js-package-manager';
import { NpmOptions } from './NpmOptions';
import { automigrate } from './automigrate';
import { CommandOptions } from './generators/types';
Expand Down Expand Up @@ -220,7 +220,7 @@ const installStorybook = (
};

const projectTypeInquirer = async (
options: { yes?: boolean },
options: CommandOptions & { yes?: boolean },
packageManager: JsPackageManager
) => {
const manualAnswer = options.yes
Expand Down Expand Up @@ -251,7 +251,11 @@ const projectTypeInquirer = async (
};

export async function initiate(options: CommandOptions, pkg: Package): Promise<void> {
const packageManager = JsPackageManagerFactory.getPackageManager(options.useNpm);
const { useNpm, packageManager: pkgMgr } = options;
if (useNpm) {
useNpmWarning();
}
const packageManager = JsPackageManagerFactory.getPackageManager({ useNpm, force: pkgMgr });
const welcomeMessage = 'storybook init - the simplest way to add a Storybook to your project.';
logger.log(chalk.inverse(`\n ${welcomeMessage} \n`));

Expand Down Expand Up @@ -307,7 +311,7 @@ export async function initiate(options: CommandOptions, pkg: Package): Promise<v
packageManager.installDependencies();
}

await automigrate({ yes: options.yes || process.env.CI === 'true' });
await automigrate({ yes: options.yes || process.env.CI === 'true', useNpm, force: pkgMgr });

logger.log('\nTo run your Storybook, type:\n');
codeLog([packageManager.getRunStorybookCommand()]);
Expand Down
4 changes: 3 additions & 1 deletion code/lib/cli/src/js-package-manager/JsPackageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import storybookPackagesVersions from '../versions';

const logger = console;

export type PackageManagerName = 'npm' | 'yarn1' | 'yarn2' | 'pnpm';

/**
* Extract package name and version from input
*
Expand All @@ -31,7 +33,7 @@ interface JsPackageManagerOptions {
cwd?: string;
}
export abstract class JsPackageManager {
public abstract readonly type: 'npm' | 'yarn1' | 'yarn2';
public abstract readonly type: PackageManagerName;

public abstract initPackageJson(): void;

Expand Down
Loading