Skip to content

Conversation

@sifthedog
Copy link

@sifthedog sifthedog commented Dec 13, 2025

After a discussion on ant-design/ant-design#56145, I believe the code change should be in this repository, so we can properly export consume it in antd

reproducible example

Summary by CodeRabbit

发布说明

  • 杂务
    • 优化发布流程以自动更新浏览器环境兼容性配置
    • 改进了包构建和发布流程中的预处理步骤

✏️ Tip: You can customize this high-level summary in your review settings.

Summary by CodeRabbit

发布说明

  • Chores
    • 强化了发布流程,通过引入自动化脚本优化了包的编译和配置管理,提升了发布效率。

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 13, 2025

@sifthedog is attempting to deploy a commit to the React Component Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Dec 13, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

向构建流程中添加了自动化功能,新增 npm 脚本与 Node.js 脚本以动态生成并更新 package.json 中的 browser 字段映射,支持库文件在浏览器环境中的正确解析。

Changes

Cohort / 文件(s) 变更摘要
构建脚本配置
package.json
scripts 中添加 "browser-field" 脚本用于执行更新脚本;修改 prepublishOnly 脚本,将编译后更新浏览器字段的步骤链入发布流程(从 npm run compile && rc-np 改为 npm run compile && npm run browser-field && rc-np)。
浏览器字段更新工具
scripts/update-browser-field.js
新增 Node.js 脚本:读取项目根目录的 package.json,保留 main/ES 构建映射,扫描 es/localees/generate(如存在)下的 .js 文件,生成浏览器路径到 es 路径的映射(包括无后缀与 .js 变体),将映射按键字典序写入 pkg.browser 并持久化到磁盘,输出新增条目数量;包含目录存在性检查以避免错误。

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • 主要改动集中在 2 个文件,逻辑以文件读写与路径映射为主,复审重点:
    • scripts/update-browser-field.js 的路径扫描与映射规则(是否覆盖预期文件、后缀处理)
    • 对已有 pkg.browser 字段的合并/覆盖逻辑及格式化输出是否符合项目约定

Poem

🐰 新映射跳一跳,package 中路更俏,
脚本轻敲键盘响,发布前夜把家扫,
映射有序排整齐,浏览器里也欢笑!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 标题准确反映了主要变更,即在预发布时更新 package.json 的 browser 字段以支持 webpack 4。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @sifthedog, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a critical enhancement to the package's build process by introducing an automated mechanism to populate the browser field in package.json. This ensures that when the package is consumed by bundlers such as Webpack 4, it correctly resolves and utilizes the optimized ES module versions of its components, leading to more efficient and smaller browser bundles. The change streamlines the publishing workflow by integrating this update into the pre-publish script.

Highlights

  • Dynamic Browser Field Generation: A new Node.js script, scripts/update-browser-field.js, has been introduced to dynamically generate and update the browser field in package.json.
  • Pre-publish Hook Integration: The newly created script is now executed as part of the prepublishOnly lifecycle hook, ensuring the browser field is correctly configured before the package is published.
  • Webpack 4 Compatibility: This change specifically addresses compatibility with bundlers like Webpack 4 by providing explicit mappings for CommonJS and ES module paths, directing them to their ES module equivalents for browser environments.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a script to dynamically generate the browser field in package.json before publishing. This is a good approach to ensure compatibility with older bundlers like webpack 4 that may not fully support the exports field. The script correctly maps library entry points to their ES module equivalents. The changes in package.json to integrate this script into the prepublishOnly lifecycle are also correct. I have one suggestion to make the script more robust.

Comment on lines 24 to 33
fs.readdirSync(dirPath)
.filter((file) => file.endsWith('.js'))
.sort()
.forEach((file) => {
const name = path.basename(file, '.js');
const target = `${targetPrefix}/${file}`;

addEntry(`${browserPrefix}/${name}`, target);
addEntry(`${browserPrefix}/${name}.js`, target);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The current implementation of addDirMappings doesn't check if a directory entry is a file. If a directory name happens to end with .js, it would be processed, leading to incorrect entries in the browser field.

To make this more robust, you can use the withFileTypes: true option in fs.readdirSync and filter for files only. This is more efficient than using fs.statSync in a loop and ensures only files are processed.

  fs.readdirSync(dirPath, { withFileTypes: true })
    .filter((dirent) => dirent.isFile() && dirent.name.endsWith('.js'))
    .map((dirent) => dirent.name)
    .sort()
    .forEach((file) => {
      const name = path.basename(file, '.js');
      const target = `${targetPrefix}/${file}`;

      addEntry(`${browserPrefix}/${name}`, target);
      addEntry(`${browserPrefix}/${name}.js`, target);
    });

Copy link

@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: 0

🧹 Nitpick comments (3)
scripts/update-browser-field.js (3)

8-8: 添加错误处理以提供更清晰的错误消息。

如果 package.json 不存在或格式错误,脚本会崩溃并显示不清晰的错误消息。由于此脚本在 prepublishOnly 钩子中运行,添加 try-catch 块以提供更有用的错误消息会改善开发者体验。

应用此差异以添加错误处理:

-const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
+let pkg;
+try {
+  pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
+} catch (error) {
+  console.error('Failed to read or parse package.json:', error.message);
+  process.exit(1);
+}

43-43: 为文件写入操作添加错误处理。

fs.writeFileSync 可能因权限问题或磁盘空间不足而失败。由于这在发布前运行,添加错误处理以提供清晰的错误消息会很有帮助。

应用此差异以添加错误处理:

-fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
+try {
+  fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
+} catch (error) {
+  console.error('Failed to write package.json:', error.message);
+  process.exit(1);
+}

41-41: 浏览器字段的完全覆盖是预期的设计行为。

该脚本作为构建工具在 prepublishOnly 钩子中运行,用于在每次发布前自动重新生成 browser 字段。因此,browser 字段不应手动编辑,而是由脚本根据 es/localees/generate 目录中的文件自动生成。这个设计是有意的,不存在问题。

可选建议:在脚本顶部添加注释说明其目的是自动生成 browser 字段映射,以便后续维护者理解这个字段是自动生成的,不应手动修改。

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b987f8c and 236db42.

📒 Files selected for processing (2)
  • package.json (1 hunks)
  • scripts/update-browser-field.js (1 hunks)
🔇 Additional comments (5)
package.json (2)

100-100: 确认新脚本的执行顺序正确。

新增的 browser-field 脚本在发布流程中的位置合理,但需要确保 scripts/update-browser-field.js 具有适当的错误处理机制,以避免在发布前阻塞。


102-102: 验证浏览器字段更新不会破坏现有发布流程。

prepublishOnly 脚本的执行顺序正确:

  1. compile 步骤先执行,生成构建产物
  2. browser-field 脚本随后运行,更新 package.json 的浏览器入口
  3. rc-np 最后执行,发布到 npm

脚本间使用 && 链接,任何步骤失败都会中止后续执行,确保发布流程的原子性。无其他代码依赖旧的 prepublishOnly 行为,CI/CD 配置中也无相关影响。

scripts/update-browser-field.js (3)

20-22: 良好的防御性编程实践。

目录存在性检查可防止在编译输出尚未生成时脚本崩溃,这是一个很好的实践。


24-33: 此评论不适用于当前代码库。

es/localees/generate 目录在此仓库中不存在,因此关于单层目录扫描的假设不成立。脚本已通过 fs.existsSync() 进行了防御性检查,可以安全地处理这些目录缺失的情况。如果将来这些目录被添加到项目中,且需要支持嵌套子目录,再考虑实现递归扫描逻辑。

Likely an incorrect or invalid review comment.


36-37: 当前的浏览器字段映射策略对于 webpack 4 是正确完整的。

webpack 4 不支持 package.json 的 exports 字段,仅依赖 browsermodulemain 字段进行解析。lines 36-37 创建的映射 ./locale/*./es/locale/*./generate/*./es/generate/* 已足以处理主要使用场景。如果用户明确引入 ./lib/* 路径,说明其意图是使用 lib 版本而非浏览器版本,因此不应在浏览器字段中重写这些路径。

Copy link

@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: 0

🧹 Nitpick comments (2)
scripts/update-browser-field.js (2)

37-44: 请确认覆盖写 pkg.browser(而非合并)是预期行为
当前会完全替换现有 browser 字段;如果项目/下游依赖曾手工维护额外映射,这里会被抹掉。若希望保留额外条目,建议“基于现有对象合并 + 覆盖冲突键”。


44-46: 写回 package.json 建议用“临时文件 + rename”提高原子性
writeFileSync 直接覆盖在异常中断时可能留下半文件;发布链路里这类失败会比较难排查。

- fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
+ const tmpPath = `${pkgPath}.tmp`;
+ fs.writeFileSync(tmpPath, `${JSON.stringify(pkg, null, 2)}\n`);
+ fs.renameSync(tmpPath, pkgPath);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 236db42 and c875a58.

📒 Files selected for processing (1)
  • scripts/update-browser-field.js (1 hunks)
🔇 Additional comments (3)
scripts/update-browser-field.js (3)

1-9: 确认 Node 版本兼容性(withFileTypes / Object.fromEntries
脚本依赖较新的 Node 特性;建议对照仓库 engines.node / CI / 发布机 Node 版本,避免 prepublishOnly 在旧环境直接炸。


10-18: 主入口映射固定为 ./lib/index.js -> ./es/index.js 很清晰
逻辑直接、可预测,符合“主入口优先走 ES build”的意图。


19-35: addDirMappings 实现稳健:只处理文件且按名称排序
withFileTypes: true + dirent.isFile() 能避免把目录误当成 .js 文件;排序后输出稳定,利于可重复发布。

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.

1 participant