CLI: Detect free port when running dev during initiate#33532
Conversation
…er starts without asking
|
View your CI Pipeline Execution ↗ for commit 7781dea
☁️ Nx Cloud last updated this comment at |
Package BenchmarksCommit: No significant changes detected, all good. 👏 |
📝 WalkthroughWalkthroughA new Changes
Sequence DiagramsequenceDiagram
participant Init as create-storybook init
participant PortUtil as getServerPort utility
participant DevServer as Storybook dev server
Init->>PortUtil: Check if port 6006 available
PortUtil-->>Init: Port status (available/unavailable)
alt Port 6006 unavailable
Init->>Init: Compute alternative port
Init->>DevServer: await executeCommand with --port=<alt>
else Port 6006 available
Init->>DevServer: await executeCommand with default port
end
DevServer-->>Init: Server started
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🧰 Additional context used📓 Path-based instructions (5)**/*.{js,jsx,ts,tsx,json,md,html,css,scss}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.{js,jsx,json,html,ts,tsx,mjs}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
code/{core,lib,addons,builders,frameworks,presets}/**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
🧠 Learnings (4)📓 Common learnings📚 Learning: 2025-12-22T22:03:40.123ZApplied to files:
📚 Learning: 2025-11-05T09:38:47.712ZApplied to files:
📚 Learning: 2025-12-22T22:03:40.123ZApplied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
🔇 Additional comments (3)
✏️ Tip: You can disable this entire section by setting Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
code/lib/create-storybook/src/initiate.ts (1)
179-209: Avoid adding a second--portwhenstorybookCommandalready specifies one
IfstorybookCommandever contains--port …,--port=…, or-p …, this will append a conflicting--port=...and create ambiguous CLI behavior.Proposed patch
- const flags = []; + const flags: string[] = []; if (packageManager.type === 'npm') { flags.push('--silent'); } @@ if (supportsOnboarding && shouldOnboard) { flags.push('--initial-path=/onboarding'); } - // Check if default port 6006 is available - const defaultPort = 6006; - const availablePort = await getServerPort(defaultPort); - const useAlternativePort = availablePort !== defaultPort; - - if (useAlternativePort) { - flags.push(`--port=${availablePort}`); - } + const commandParts = storybookCommand.split(' '); + const commandAlreadyHasPort = + commandParts.some((a) => a === '--port' || a === '-p' || a.startsWith('--port=')) || + commandParts.some((a, i) => (a === '--port' || a === '-p') && Boolean(commandParts[i + 1])); + + if (!commandAlreadyHasPort) { + // Check if default port 6006 is available + const defaultPort = 6006; + const availablePort = await getServerPort(defaultPort); + const useAlternativePort = availablePort !== defaultPort; + + if (useAlternativePort) { + flags.push(`--port=${availablePort}`); + } + } flags.push('--quiet');Also, given the PR description notes QA found this, please add at least explicit manual test steps in the PR description (or a small unit/integration test if there’s a suitable harness).
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
code/core/src/core-server/index.tscode/lib/create-storybook/src/initiate.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,jsx,ts,tsx,json,md,html,css,scss}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Format code using Prettier with
yarn prettier --write <file>
Files:
code/lib/create-storybook/src/initiate.tscode/core/src/core-server/index.ts
**/*.{js,jsx,json,html,ts,tsx,mjs}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Run ESLint checks using
yarn lint:js:cmd <file>or the full commandcross-env NODE_ENV=production eslint --cache --cache-location=../.cache/eslint --ext .js,.jsx,.json,.html,.ts,.tsx,.mjs --report-unused-disable-directivesto fix linting errors before committing
Files:
code/lib/create-storybook/src/initiate.tscode/core/src/core-server/index.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Enable TypeScript strict mode across all packages
Files:
code/lib/create-storybook/src/initiate.tscode/core/src/core-server/index.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx,js,jsx}: Export functions from modules if they need to be tested
Do not useconsole.log,console.warn, orconsole.errordirectly unless in isolated files where importing loggers would significantly increase bundle size
Files:
code/lib/create-storybook/src/initiate.tscode/core/src/core-server/index.ts
code/{core,lib,addons,builders,frameworks,presets}/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use
loggerfromstorybook/internal/node-loggerfor server-side logging in Node.js code
Files:
code/lib/create-storybook/src/initiate.tscode/core/src/core-server/index.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-22T22:03:40.123Z
Learning: Applies to code/{core,lib,addons,builders,frameworks,presets}/**/*.{ts,tsx,js,jsx} : Use `logger` from `storybook/internal/node-logger` for server-side logging in Node.js code
📚 Learning: 2025-12-22T22:03:40.123Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-22T22:03:40.123Z
Learning: Applies to code/{core,lib,addons,builders,frameworks,presets}/**/*.{ts,tsx,js,jsx} : Use `logger` from `storybook/internal/node-logger` for server-side logging in Node.js code
Applied to files:
code/lib/create-storybook/src/initiate.ts
📚 Learning: 2025-11-05T09:38:47.712Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/Select/Select.tsx:200-204
Timestamp: 2025-11-05T09:38:47.712Z
Learning: Repo: storybookjs/storybook — Guidance: Until Storybook 11 is released, do not suggest using React.useId anywhere (e.g., in code/core/src/components/components/Select/Select.tsx) to maintain compatibility with React 17 runtimes. Prefer advising: accept a caller-provided props.id and, if needed, generate a client-only fallback id to minimize SSR hydration issues — but avoid useId. Resume prompting for useId after Storybook 11.
Applied to files:
code/lib/create-storybook/src/initiate.ts
📚 Learning: 2025-12-22T22:03:40.123Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-22T22:03:40.123Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Export functions from modules if they need to be tested
Applied to files:
code/core/src/core-server/index.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: normal
- GitHub Check: Core Unit Tests, windows-latest
- GitHub Check: nx
🔇 Additional comments (3)
code/lib/create-storybook/src/initiate.ts (2)
7-8: Import change looks fine; keep “node-logger” usage (no console)
You’re usingloggerfromstorybook/internal/node-loggerin this Node path, which aligns with repo guidance.
210-221: AwaitingexecuteCommandis good; verify desired exit-code semantics
Awaiting the subprocess makes the parentinitiateprocess behave more like “run dev now” (likely intended). One thing to confirm: the surroundingtry/catchswallows failures, so the parent may exit0even if the child fails immediately. If you expectstorybook initiate --devto reflect child failure, propagate the error / exit code instead of swallowing.code/core/src/core-server/index.ts (1)
33-34: ThegetServerPortexport is already actively imported from the barrel incode/lib/create-storybook/src/initiate.ts, confirming this addition formalizes an existing expected API surface. No import-time side effects or circular dependencies detected. Implementation is clean, well-tested, and production-ready.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
What I did
Discovered during QA: when runnign storybook initiate whilst another storybook is running on the default port, the user is asked if another port should be used.
This hinders the ease of onboarding, so it's better to detect if the port is open beforehand and set an alternative one (that's free) if that's the case.
Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Manual testing
Caution
This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!
Documentation
MIGRATION.MD
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.🦋 Canary release
This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the
@storybookjs/coreteam here.core team members can create a canary release here or locally with
gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.