feat(cli): support init in current directory#19273
Conversation
WalkthroughProject 构造函数添加了 Changes项目初始化路径规范化
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed: dependency version conflict. Check your lock file or package.json. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/taro-cli/src/create/project.ts`:
- Around line 59-68: The existence check in askProjectName is inconsistent with
resolveProjectConf for inputs like "." or "./" — resolveProjectConf rewrites
projectDir/projectName based on cwd but askProjectName currently calls
fs.existsSync(conf.projectName!), which effectively checks the wrong nested
path; update askProjectName to test the actual target directory by using
fs.existsSync(path.join(conf.projectDir, conf.projectName)) (or special-case
conf.projectName === '.'/'./' to check conf.projectDir) so the existence
validation matches the resolved creation target used by resolveProjectConf.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1a1fb00b-57b5-4626-85b4-955bb30271da
📒 Files selected for processing (2)
packages/taro-cli/src/__tests__/project.spec.tspackages/taro-cli/src/create/project.ts
| function resolveProjectConf (conf: IProjectConfOptions): IProjectConfOptions { | ||
| if (!conf.projectName || !/^\.(?:[\\/])?$/.test(conf.projectName)) return conf | ||
|
|
||
| const projectDir = conf.projectDir || process.cwd() | ||
| return { | ||
| ...conf, | ||
| projectDir: path.dirname(projectDir), | ||
| projectName: path.basename(projectDir) | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 描述:检查 askProjectName 方法的实现,确认其存在性检查逻辑
# 查找 askProjectName 方法的完整实现,包括上下文
rg -nP -A 20 'askProjectName.*function' --type=ts
# 查找 create() 和 ask() 方法的调用链,确认 cwd 上下文
rg -nP -B 5 -A 10 'async (ask|create)\s*\(' packages/taro-cli/src/create/project.tsRepository: NervJS/taro
Length of output: 2553
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/taro-cli/src/create/project.ts"
echo "---- file stats ----"
wc -l "$file"
echo "---- resolveProjectConf + constructor integration (lines 1-140) ----"
sed -n '1,220p' "$file" | nl -ba | sed -n '1,220p'
echo "---- askProjectName full block (lines around 130-220) ----"
sed -n '130,230p' "$file" | nl -ba
echo "---- look for resolveProjectConf usage ----"
rg -n "resolveProjectConf" "$file"Repository: NervJS/taro
Length of output: 250
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/taro-cli/src/create/project.ts"
echo "---- file stats ----"
wc -l "$file"
echo "---- resolveProjectConf + constructor integration (lines 1-140) ----"
sed -n '1,220p' "$file" | nl -ba | sed -n '1,220p'
echo "---- askProjectName full block (lines around 130-220) ----"
sed -n '130,230p' "$file" | nl -ba
echo "---- look for resolveProjectConf usage ----"
rg -n "resolveProjectConf" "$file"Repository: NervJS/taro
Length of output: 250
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/taro-cli/src/create/project.ts"
echo "---- resolveProjectConf definition ----"
rg -n "function resolveProjectConf" "$file"
sed -n '40,110p' "$file" | cat -n
echo "---- constructor / call site around integration ----"
rg -n "resolveProjectConf" "$file"
# show region around matches
rg -n "resolveProjectConf" "$file" | cut -d: -f1 | head -n 5 | while read -r ln; do
start=$((ln-40)); end=$((ln+40));
echo "---- context around line $ln ----"
sed -n "${start},${end}p" "$file" | cat -n
done
echo "---- askProjectName block (160-210) ----"
sed -n '140,220p' "$file" | cat -nRepository: NervJS/taro
Length of output: 11182
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/taro-cli/src/create/project.ts"
echo "---- usages of projectDir/projectName in this file ----"
rg -n "projectDir|projectName" "$file"
echo "---- locate write() in file ----"
rg -n "async write|write\s*\(" "$file"
echo "---- print surrounding of write usage ----"
# show region around 'write(' call inside create/creator if any
rg -n "this\.write" "$file" -nRepository: NervJS/taro
Length of output: 1100
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/taro-cli/src/create/project.ts"
echo "---- write() implementation around 460-520 ----"
sed -n '440,520p' "$file" | cat -n
echo "---- around where projectRoot/projectName are derived (470-510) ----"
sed -n '470,510p' "$file" | cat -nRepository: NervJS/taro
Length of output: 5065
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "new Project\\(" -S packages/taro-cli/src | head -n 50
rg -n "projectName:\\s*\\w+|projectName\\s*:" packages/taro-cli/src/create -S | head -n 50Repository: NervJS/taro
Length of output: 890
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "new Project\\(" packages/taro-cli/src -S | head -n 50
rg -n "projectName" packages/taro-cli/src/init packages/taro-cli/src -S | head -n 80Repository: NervJS/taro
Length of output: 3572
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) locate createProject implementation and how it uses projectRoot/projectName
rg -n "function createProject\\b|createProject\\s*\\(" packages/taro-cli/src/create -S
rg -n "createProject\\s*\\(" packages/taro-cli/src -S
# 2) inspect init command construction of Project
sed -n '1,140p' packages/taro-cli/src/presets/commands/init.ts | cat -n
# 3) inspect cli argument parsing around init [projectName]
rg -n "init \\[projectName\\]|case 'init'|program\\.command\\('init'\\)|taro init" packages/taro-cli/src/cli.ts -S
sed -n '150,270p' packages/taro-cli/src/cli.ts | cat -n
# 4) inspect existing unit tests for projectName '.' conversion
sed -n '1,140p' packages/taro-cli/src/__tests__/project.spec.ts | cat -nRepository: NervJS/taro
Length of output: 9312
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "appPath" packages/taro-cli/src -S | head -n 200Repository: NervJS/taro
Length of output: 7327
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# inspect cli.ts to see how appPath is computed for init command
sed -n '1,140p' packages/taro-cli/src/cli.ts | cat -n
rg -n "class .*Kernel|customCommand\\(|new Kernel|paths\\b|this\\.paths|ctx\\.paths" packages/taro-cli/src/cli.ts -S
# inspect utils/run* helper to see how appPath is passed in tests/exec
sed -n '1,120p' packages/taro-cli/src/__tests__/utils/index.ts | cat -nRepository: NervJS/taro
Length of output: 8133
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# inspect cli.ts to see how appPath is computed for init command
sed -n '1,140p' packages/taro-cli/src/cli.ts | cat -n
rg -n "customCommand\\(|paths\\b|this\\.paths|ctx\\.paths" packages/taro-cli/src/cli.ts -S
# inspect utils/run* helper to see how appPath is passed in tests/exec
sed -n '1,120p' packages/taro-cli/src/__tests__/utils/index.ts | cat -nRepository: NervJS/taro
Length of output: 8096
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "createProject\\b" packages/taro-cli/src -S
rg -n "function createProject\\b|export (async )?function createProject\\b|export const createProject\\b" . -SRepository: NervJS/taro
Length of output: 544
修正 taro init . 下 askProjectName 存在性校验的路径不一致问题
resolveProjectConf 在 projectName 为 ././ 时会把配置改成 projectDir: path.dirname(cwd)、projectName: path.basename(cwd)(packages/taro-cli/src/create/project.ts 第 59-68 行)。但 askProjectName 的存在性校验在 projectName 已是字符串时直接做 fs.existsSync(conf.projectName!)(第 158-190 行),这会导致 taro init . 时实际检查的是 <cwd>/<basename>(例如 /a/b/current-project/current-project),而目标目录其实是 <cwd>。只有当该“嵌套目录”恰好存在时才会误报“当前目录已经存在同名项目”。
建议让校验依据与实际创建目标路径一致:改为检查 fs.existsSync(path.join(conf.projectDir, conf.projectName)),或在 projectName 输入为 ././ 时跳过/使用匹配目标目录的验证逻辑。现有 packages/taro-cli/src/__tests__/project.spec.ts 只覆盖 ././ 转换结果,未覆盖 askProjectName 的校验行为。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/taro-cli/src/create/project.ts` around lines 59 - 68, The existence
check in askProjectName is inconsistent with resolveProjectConf for inputs like
"." or "./" — resolveProjectConf rewrites projectDir/projectName based on cwd
but askProjectName currently calls fs.existsSync(conf.projectName!), which
effectively checks the wrong nested path; update askProjectName to test the
actual target directory by using fs.existsSync(path.join(conf.projectDir,
conf.projectName)) (or special-case conf.projectName === '.'/'./' to check
conf.projectDir) so the existence validation matches the resolved creation
target used by resolveProjectConf.
Summary
taro init ./npx @tarojs/cli init .by resolving.to the current directory name while keeping the target path as the current directory..and./project names.Motivation
Closes #19249. This lets users initialize a Taro project directly in an existing current directory. Existing non-conflicting files are preserved by the existing template copy behavior, while same-name template files can still be overwritten.
Validation
pnpm --filter @tarojs/cli exec jest packages/taro-cli/src/__tests__/project.spec.ts --runInBandpnpm --filter @tarojs/cli exec eslint src/create/project.ts src/__tests__/project.spec.tsNote: I also tried running
cli.spec.ts, but this temporary worktree had unbuilt workspace package entries such as@tarojs/service, so that broader suite could not start in this local environment.Summary by CodeRabbit
Release Notes
Tests
Bug Fixes