Skip to content

feat(cli): support init in current directory#19273

Open
Jarvis636431 wants to merge 2 commits into
NervJS:mainfrom
Jarvis636431:init-current-directory
Open

feat(cli): support init in current directory#19273
Jarvis636431 wants to merge 2 commits into
NervJS:mainfrom
Jarvis636431:init-current-directory

Conversation

@Jarvis636431
Copy link
Copy Markdown

@Jarvis636431 Jarvis636431 commented May 25, 2026

Summary

  • Support taro init . / npx @tarojs/cli init . by resolving . to the current directory name while keeping the target path as the current directory.
  • Add unit coverage for . 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 --runInBand
  • pnpm --filter @tarojs/cli exec eslint src/create/project.ts src/__tests__/project.spec.ts

Note: 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

    • 修复了当项目名称为"."或"./"时的路径和项目名称解析逻辑,确保正确识别当前目录信息

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Walkthrough

Project 构造函数添加了 resolveProjectConf 辅助函数,在初始化时检测 projectName../ 等相对路径标记的情况,并基于 projectDir 自动推导出规范化的项目目录和名称。新增的单元测试通过 Jest mock 隔离外部依赖,验证了这一路径解析逻辑的正确性。

Changes

项目初始化路径规范化

Layer / File(s) Summary
路径规范化函数实现
packages/taro-cli/src/create/project.ts
新增 resolveProjectConf 函数用于检测并处理 ././ 相对路径标记,从当前工作目录提取目录名和基名;修改 Project 构造函数将配置合并结果经过该函数处理,完成自动路径规范化。
规范化逻辑验证
packages/taro-cli/src/__tests__/project.spec.ts
配置 Jest mock 隔离 @tarojs/helper、@tarojs/shared、@tarojs/binding 等外部依赖;新增测试套件验证 ../ 两种相对路径标记下的 projectDir 和 projectName 解析结果符合预期。

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

小兔蹦跶向前行,
点点相对路径明,
../ 一声令,
当前目录建项城,
测试覆盖显虔诚! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题清晰准确地反映了主要变更:支持在当前目录初始化Taro项目。
Linked Issues check ✅ Passed 所有关键需求已实现:支持'taro init .'和'npx @tarojs/cli init .'初始化项目,添加了单元测试,现有文件保留逻辑由模板复制处理。
Out of Scope Changes check ✅ Passed 所有变更均在范围内:新增测试文件和修改Project构造函数以支持当前目录初始化,无无关变更。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Jarvis636431 Jarvis636431 marked this pull request as ready for review May 25, 2026 14:19
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between bd51e97 and 57b0a69.

📒 Files selected for processing (2)
  • packages/taro-cli/src/__tests__/project.spec.ts
  • packages/taro-cli/src/create/project.ts

Comment on lines +59 to +68
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)
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 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.ts

Repository: 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 -n

Repository: 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" -n

Repository: 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 -n

Repository: 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 50

Repository: 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 80

Repository: 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 -n

Repository: NervJS/taro

Length of output: 9312


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "appPath" packages/taro-cli/src -S | head -n 200

Repository: 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 -n

Repository: 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 -n

Repository: 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" . -S

Repository: NervJS/taro

Length of output: 544


修正 taro init .askProjectName 存在性校验的路径不一致问题

resolveProjectConfprojectName././ 时会把配置改成 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.

This was referenced May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@tarojs/cli 能不能支持 npx @tarojs/cli init . 在当前目录下直接创建项目

1 participant