Skip to content

Conversation

Gagandeep1310
Copy link

@Gagandeep1310 Gagandeep1310 commented Aug 17, 2025

Tailwind CSS Integration: Adds Tailwind CSS and its configuration files (.github/tailwind.config.js, site/site/tailwind.css) to enable utility-first styling.
PostCSS Setup: Integrates PostCSS with "autoprefixer" and "tailwindcss" plugins via .github/postcss.config.js and updates webpack.config.js to process CSS with PostCSS.
UI Component Refactoring: The site/edit/template/layout.jsx file has been substantially refactored, removing Ant Design components and styling in favor of custom HTML elements styled entirely with Tailwind CSS utility classes, particularly for the login and main application layout.
Build System Updates: package.json is updated with new dependencies, and site/theme/index.js and webpack.config.js are modified to ensure proper bundling and processing of Tailwind CSS.

Summary by CodeRabbit

  • 新功能

    • 全新登录卡片式界面,支持按钮加载态与内联错误提示
    • 初始数据未就绪时提供居中“Loading…”提示
  • 样式

    • 引入 Tailwind 实用类与自定义主题色(主色、标题色、正文色)
    • 编辑器布局与左右侧栏样式全面改版,视觉与间距更一致
  • 杂务

    • 构建流程集成 Tailwind/PostCSS/Autoprefixer,并自动注入全局样式
    • 新增相关开发依赖

Copy link

coderabbitai bot commented Aug 17, 2025

📝 Walkthrough

Walkthrough

本次变更新增并集成 Tailwind CSS/PostCSS(配置、依赖、构建管线注入),并在编辑器模板中重写登录与布局渲染逻辑;同时通过主题 webpack 钩子与全局 postcss-loader 统一加载 Tailwind 样式。

Changes

Cohort / File(s) Summary
Tailwind/PostCSS 集成
/.github/postcss.config.js, /.github/tailwind.config.js, /package.json, /site/site/tailwind.css, /site/theme/index.js, /webpack.config.js
新增 PostCSS 与 Tailwind 配置与依赖;加入 Tailwind 指令样式文件;通过主题的 webpackConfig 注入 tailwind.css 至入口;在 webpack 配置中为所有 CSS 规则追加 postcss-loader(含 tailwindcss、autoprefixer)。
编辑器登录与布局更新
/site/edit/template/layout.jsx
登录流程改为本地状态驱动的自定义表单与错误显示;加载态与按钮状态重构;移除 Ant Design 表单/通知依赖;主编辑布局的结构与样式标记调整为类 Tailwind 的工具类写法。

Sequence Diagram(s)

sequenceDiagram
  participant U as User
  participant L as Layout(Component)
  participant S as Store
  participant A as Auth API

  U->>L: 输入密码并提交
  L->>L: 阻止默认提交/校验长度
  L->>A: logIn(userId, password)
  A-->>L: 成功/失败
  alt 成功
    L->>S: dispatch(setUserData(true))
    L-->>U: 切换到编辑器布局
  else 失败
    L-->>U: 显示错误消息(本地状态)
  end
Loading
sequenceDiagram
  participant Dev as Dev Server
  participant W as Webpack
  participant T as theme webpackConfig
  participant E as Entry index
  participant L as Loaders
  participant P as postcss-loader(tailwind+autoprefixer)

  Dev->>W: 启动构建
  W->>T: 读取主题配置
  T->>E: 将 tailwind.css 置于入口前部
  W->>L: 解析 CSS 规则
  L->>P: 处理 CSS
  P-->>W: 产出带前缀与 Tailwind 的样式
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

小兔点点耳朵轻,
新风裁样入炼晶。
尾风拂过样式林,
登录一跃更安宁。
齿间咔嗒敲键轻,
布局如云随风行。 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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.

Summary of Changes

Hello @Gagandeep1310, 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 introduces Tailwind CSS into the project, initiating a significant refactoring effort to transition the user interface from Ant Design to a utility-first CSS approach. The changes involve setting up Tailwind and PostCSS configurations, updating build processes, and completely restyling the "layout.jsx" component using Tailwind's utility classes.

Highlights

  • Tailwind CSS Integration: Adds Tailwind CSS and its configuration files (.github/tailwind.config.js, site/site/tailwind.css) to enable utility-first styling.
  • PostCSS Setup: Integrates PostCSS with "autoprefixer" and "tailwindcss" plugins via .github/postcss.config.js and updates webpack.config.js to process CSS with PostCSS.
  • UI Component Refactoring: The site/edit/template/layout.jsx file has been substantially refactored, removing Ant Design components and styling in favor of custom HTML elements styled entirely with Tailwind CSS utility classes, particularly for the login and main application layout.
  • Build System Updates: package.json is updated with new dependencies, and site/theme/index.js and webpack.config.js are modified to ensure proper bundling and processing of Tailwind CSS.
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 in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

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 issue 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

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedautoprefixer@​10.4.211001009178100

View full report

Copy link

@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 Tailwind CSS to the project and refactors the login page to use it. The changes include adding new dependencies, setting up PostCSS and Tailwind configurations, and updating the webpack build process.

My review focuses on improving maintainability, accessibility, and internationalization in the new login component, as well as ensuring the new build configurations are set up according to best practices. I've identified a couple of high-severity issues related to configuration and hardcoded text, and several medium-severity suggestions to improve accessibility and code structure. Overall, this is a great step towards modernizing the UI stack.

Comment on lines +12 to +22
rule.use.push({
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
});

Choose a reason for hiding this comment

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

high

The postcss-loader options are hardcoded within the webpack configuration. This duplicates the configuration from .github/postcss.config.js which was added in this same pull request. To adhere to the Don't Repeat Yourself (DRY) principle and keep configurations centralized, you should let postcss-loader automatically pick up its configuration.

To make this work, you'll likely need to:

  1. Move .github/postcss.config.js to the project root as postcss.config.js (where the loader will find it by default).
  2. Simplify the postcss-loader configuration in webpack.config.js as suggested.
      rule.use.push({
        loader: 'postcss-loader',
      });

errors: ['Password error.'],
},
]);
this.setState({ error: 'Password error.' });

Choose a reason for hiding this comment

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

high

The error message 'Password error.' is hardcoded. Since the application is already set up with react-intl for internationalization, this string should also be translated. This ensures a consistent user experience across different languages and keeps all user-facing text in your locale files.

          this.setState({ error: this.props.intl.formatMessage({ id: 'app.login.password.error' }) });

Comment on lines 42 to +48
if (succeeded) {
dispatch(actions.setUserData(true));
message.success('登入成功。');
// Replace message.success with custom notification
} else {
this.formRef.current.setFields([
{
name: 'password',
value: values.password,
errors: ['Password error.'],
},
]);
this.setState({ error: 'Password error.' });
}
this.setState({
loading: false,
});
this.setState({ loading: false });

Choose a reason for hiding this comment

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

medium

The state updates within the logIn callback can be structured more efficiently. In the failure case, you have two separate setState calls which can lead to an unnecessary re-render if not batched by React. You can combine these into a single call. Moving the loading: false update into each branch of the conditional also makes the logic for each case more self-contained.

        if (succeeded) {
          dispatch(actions.setUserData(true));
          this.setState({ loading: false });
          // Replace message.success with custom notification
        } else {
          this.setState({ error: 'Password error.', loading: false });
        }

Comment on lines +85 to +87
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 text-yellow-500 mr-2" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
</svg>

Choose a reason for hiding this comment

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

medium

This inline SVG icon appears to be decorative, as its meaning is conveyed by the adjacent text. To improve accessibility for screen reader users, you should hide it from the accessibility tree by adding the aria-hidden="true" attribute.

                <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 text-yellow-500 mr-2" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
                  <path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
                </svg>

Comment on lines +93 to +111
<div className="mb-4">
<div className="relative">
<input
type="password"
placeholder={intl.formatMessage({ id: 'app.login.password' })}
value={this.state.password}
onChange={(e) => this.setState({
password: e.target.value,
error: ''
})}
className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
this.state.error ? 'border-red-500' : 'border-gray-300'
}`}
/>
{this.state.error && (
<p className="text-red-500 text-sm mt-1">{this.state.error}</p>
)}
</div>
</div>

Choose a reason for hiding this comment

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

medium

The password input field is missing an associated <label> element. While a placeholder is present, it is not a substitute for a proper label in terms of accessibility. Screen readers rely on labels to announce the purpose of form controls. You can add a visually hidden label using the sr-only Tailwind class to improve accessibility without altering the visual design.

              <div className="mb-4">
                <label htmlFor="login-password" className="sr-only">
                  {intl.formatMessage({ id: 'app.login.password' })}
                </label>
                <div className="relative">
                  <input
                    id="login-password"
                    type="password"
                    placeholder={intl.formatMessage({ id: 'app.login.password' })}
                    value={this.state.password}
                    onChange={(e) => this.setState({ 
                      password: e.target.value,
                      error: ''
                    })}
                    className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
                      this.state.error ? 'border-red-500' : 'border-gray-300'
                    }`}
                  />
                  {this.state.error && (
                    <p className="text-red-500 text-sm mt-1">{this.state.error}</p>
                  )}
                </div>
              </div>

Comment on lines +132 to +134
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 text-red-500 mr-2" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>

Choose a reason for hiding this comment

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

medium

Similar to the other icon, this inline SVG appears to be decorative. To improve accessibility, you should hide it from screen readers by adding the aria-hidden="true" attribute.

                <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 text-red-500 mr-2" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
                  <path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
                </svg>

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

🧹 Nitpick comments (8)
site/theme/index.js (1)

57-70: 清理临时注释并修复 ESLint 报错(尾随空格、缺失尾随逗号、文件末尾换行)

静态分析已提示:多处尾随空格(行 62、63、66)、缺失尾随逗号(行 64-65)以及缺少 EOF 换行(行 70)。另外,“ADD THIS SECTION/=====” 属于一次性提示,建议移除。

如果暂不采用上面的重构,至少进行如下最小修复:

-  // ========== ADD THIS SECTION ==========
   webpackConfig(config) {
     // Add Tailwind CSS to global styles
     config.entry.index = [
-      path.join(__dirname, 'tailwind.css'), // Add this line
-      ...(Array.isArray(config.entry.index) 
-        ? config.entry.index 
-        : [config.entry.index])
-    ];
-    
+      path.join(__dirname, 'tailwind.css'),
+      ...(Array.isArray(config.entry.index)
+        ? config.entry.index
+        : [config.entry.index]),
+    ];
+
     return config;
   },
-  // ======================================
-};
+};
site/edit/template/layout.jsx (7)

64-66: 按 ESLint 规则调整换行:将 && 放到行首、提高可读性

当前因 operator-linebreak 报错。顺便提升可读性,避免长行。

-    if (templateData.data.user && templateData.data.user.userId && 
-        !templateData.data.user.delete && !userIsLogin) {
+    if (
+      templateData.data.user
+      && templateData.data.user.userId
+      && !templateData.data.user.delete
+      && !userIsLogin
+    ) {

68-71: 修正 JSX 右括号对齐问题或改用数组拼接 className 以规避格式陷阱

当前命中 react/jsx-closing-bracket-location。可以简单对齐右括号,也可以改成更可读的数组拼接,规避模板字符串换行细节。

方案 A(仅修正对齐):

-          <div className={`bg-white p-8 rounded-lg shadow-md w-full max-w-md ${
-            this.state.error ? 'border border-red-500' : ''
-          }`}>
+          <div
+            className={`bg-white p-8 rounded-lg shadow-md w-full max-w-md ${
+              this.state.error ? 'border border-red-500' : ''
+            }`}
+          >

方案 B(推荐,便于条件拼接与对齐):

-          <div className={`bg-white p-8 rounded-lg shadow-md w-full max-w-md ${
-            this.state.error ? 'border border-red-500' : ''
-          }`}>
+          <div
+            className={[
+              'bg-white p-8 rounded-lg shadow-md w-full max-w-md',
+              this.state.error ? 'border border-red-500' : '',
+            ].filter(Boolean).join(' ')}
+          >

95-106: 修复 ESLint:为多行对象字面量添加拖尾逗号;顺便补充密码字段的自动填充与可访问性

  • 消除 comma-dangle 报错。
  • 增强表单体验与可访问性:为密码输入补充 autoComplete、在有错误时添加 aria-invalidaria-describedby
                   <input
                     type="password"
                     placeholder={intl.formatMessage({ id: 'app.login.password' })}
                     value={this.state.password}
-                    onChange={(e) => this.setState({ 
+                    onChange={(e) => this.setState({
                       password: e.target.value,
-                      error: ''
+                      error: '',
                     })}
+                    autoComplete="current-password"
+                    aria-invalid={Boolean(this.state.error)}
+                    aria-describedby={this.state.error ? 'password-error' : undefined}
                     className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
                       this.state.error ? 'border-red-500' : 'border-gray-300'
                     }`}
                   />
-                  {this.state.error && (
-                    <p className="text-red-500 text-sm mt-1">{this.state.error}</p>
+                  {this.state.error && (
+                    <p id="password-error" className="text-red-500 text-sm mt-1">{this.state.error}</p>
                   )}

46-46: 错误信息建议走国际化,保持 UI 一致性

硬编码 'Password error.' 不利于多语言与一致性。可复用现有 intl

-          this.setState({ error: 'Password error.' });
+          const { intl } = this.props;
+          this.setState({
+            error: intl.formatMessage({ id: 'app.login.passwordError', defaultMessage: 'Password error.' }),
+          });

如需,我可以顺带在语言包中补充 app.login.passwordError


138-140: 为按钮补充明确的 type,避免潜在的表单提交副作用

ESLint 报 react/button-has-type。建议显式 type="button",避免在有表单上下文时意外提交。

-                <button className="w-full py-2 px-4 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50">
+                <button type="button" className="w-full py-2 px-4 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50">

34-51: 登录处理对依赖数据的健壮性校验建议补充(可选)

onLogin 依赖 templateData.data.user.userId。在当前渲染逻辑下不会渲染登录页则不会触发,但从防御式编程看,建议在方法内兜底校验并做早返回(或错误提示),避免后续改动触发 NPE。

   onLogin = (e) => {
     e.preventDefault();
-    const { templateData, dispatch } = this.props;
-    const id = templateData.data.user.userId;
+    const { templateData, dispatch } = this.props;
+    const id = templateData?.data?.user?.userId;
+    if (!id) {
+      this.setState({ error: 'Missing user id.' });
+      return;
+    }

如需,也可将 'Missing user id.' 改为 intl 文案。


39-39: 清理零散格式问题以通过 ESLint(trailing spaces、eol-last 等)

多处 no-trailing-spaces 与文件末尾缺少换行(eol-last)会阻断 CI。建议一次性 eslint --fix 或通过编辑器保存时自动格式化。

Also applies to: 63-63, 71-73, 82-82, 92-92, 99-99, 112-112, 129-129, 147-147, 153-153, 156-156, 159-159, 163-163, 168-168, 178-178

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 54f4360 and e0f6930.

📒 Files selected for processing (7)
  • .github/postcss.config.js (1 hunks)
  • .github/tailwind.config.js (1 hunks)
  • package.json (1 hunks)
  • site/edit/template/layout.jsx (2 hunks)
  • site/site/tailwind.css (1 hunks)
  • site/theme/index.js (1 hunks)
  • webpack.config.js (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
site/edit/template/layout.jsx (2)
site/shared/utils.js (3)
  • logIn (174-184)
  • password (67-67)
  • mapStateToProps (170-172)
site/utils.jsx (3)
  • getNewHref (85-110)
  • path (104-104)
  • p (228-228)
🪛 ESLint
site/edit/template/layout.jsx

[error] 39-39: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 63-63: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 64-64: '&&' should be placed at the beginning of the line.

(operator-linebreak)


[error] 64-64: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 70-70: The closing bracket must be aligned with the line containing the opening tag (expected column 11 on the next line)

(react/jsx-closing-bracket-location)


[error] 71-71: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 72-72: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 73-73: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 82-82: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 92-92: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 99-99: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 101-102: Missing trailing comma.

(comma-dangle)


[error] 112-112: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 129-129: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 138-140: Missing an explicit type attribute for button

(react/button-has-type)


[error] 147-147: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 153-153: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 156-156: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 159-159: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 163-163: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 168-168: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 178-178: Newline required at end of file but not found.

(eol-last)

site/theme/index.js

[error] 62-62: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 63-63: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 64-65: Missing trailing comma.

(comma-dangle)


[error] 66-66: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 70-70: Newline required at end of file but not found.

(eol-last)

webpack.config.js

[error] 9-9: Expected parentheses around arrow function argument.

(arrow-parens)


[error] 17-17: Unexpected require().

(global-require)


[error] 18-18: Unexpected require().

(global-require)

🔇 Additional comments (4)
site/site/tailwind.css (1)

1-3: Tailwind 基础指令引入方式正确

全局样式入口内容合理,便于通过 PostCSS/JIT 生成所需样式。

site/theme/index.js (1)

59-66: 注意 Tailwind Preflight 与 Ant Design 的样式可能互相影响

Tailwind 的 base(含 Preflight 重置)被全局置前注入,可能对 AntD 组件默认样式产生影响(如按钮、标题、表单元素)。若观察到样式回归,考虑:

  • 在 Tailwind 配置中 corePlugins: { preflight: false }
  • 或对受影响模块明确覆盖/隔离样式范围

建议在本地快速验证关键页面/组件的渲染是否受影响(按钮、表单、Typography、Modal 等)。

webpack.config.js (2)

6-26: Tailwind 配置文件位于 .github 下,建议显式指定 config 路径(否则可能未被自动发现)

Tailwind 默认通过 cosmiconfig 在项目根查找 tailwind.config.*。若配置文件位于 .github/tailwind.config.js,默认搜索可能找不到,会退回默认配置,导致 content 未生效、生成的样式膨胀或缺失。

如需强制使用该路径,可在上面 diff 的基础上,补充如下变更(需在文件顶部引入 path):

+const path = require('path');
@@
-    const postcss = {
+    const postcss = {
       loader: 'postcss-loader',
       options: {
         postcssOptions: {
-          plugins: [tailwindcss, autoprefixer],
+          plugins: [
+            tailwindcss({ config: path.resolve(__dirname, '.github/tailwind.config.js') }),
+            autoprefixer,
+          ],
         },
       },
     };

建议本地执行一次构建并检查 Tailwind 是否正确裁剪(如类名是否按 content 覆盖范围生效)。若已有根目录 tailwind.config.js,则无需此修改。


51-53: 全局应用 PostCSS/Tailwind 注入时机合理,但请确保幂等性

在生产分支下先执行 ignoreMomentLocale/externalMoment,然后再对全部配置执行 addPostCssLoader 是合理的。若使用上条建议的幂等实现(包含去重逻辑),可避免重复注入。否则请确认构建管线不会多次加载该文件。

Comment on lines +1 to +6
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

PostCSS 配置文件位于 .github 目录,Tailwind 未显式指向配置文件,可能导致找不到 tailwind.config.js

在非标准位置(.github)放置配置文件时,需显式为 tailwindcss 插件传入 config 路径;否则 Tailwind 可能无法加载到 .github/tailwind.config.js(导致 content 扫描与主题扩展失效)。

建议修改如下:

+const path = require('path');
 module.exports = {
   plugins: {
-    tailwindcss: {},
+    tailwindcss: { config: path.resolve(__dirname, 'tailwind.config.js') },
     autoprefixer: {},
   }
 }

同时请确认 webpack 的 postcss-loader 能发现该 postcss.config.js(见下条核实脚本)。

使用脚本快速核实 postcss-loader 是否会加载此配置文件,以及是否显式配置了 config 路径:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 查找 postcss-loader 配置与是否显式指定 config =="
rg -nC3 -tjs -g '!**/node_modules/**' -P 'postcss-loader|postcssOptions|config:.*postcss|postcss\.config\.js'

Length of output: 840


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 查找仓库中的 tailwind.config.js 文件 =="
find . -type f -name 'tailwind.config.js'

Length of output: 259


确保 postcss-loader 能正确加载配置文件并显式传入 Tailwind 配置路径

经验证:

  • webpack.config.js 中已通过 inline postcssOptions.plugins 配置了 Tailwind,但未指定 config,此时会完全忽略 .github/postcss.config.js,也无法加载位于 .github/tailwind.config.js 的 Tailwind 配置。
  • 仅读修改 .github/postcss.config.js 并不能解决 webpack loader 的配置加载问题。

请在以下两个位置做出调整:

  1. 修改 webpack.config.js,让 loader 指定 PostCSS 配置文件或在插件层显式传入 Tailwind 配置路径:
    方案 A – 指定整个 PostCSS config 文件:

    + const path = require('path');
    rule.use.push({
      loader: 'postcss-loader',
      options: {
    -   postcssOptions: {
    -     plugins: [
    -       require('tailwindcss'),
    -       require('autoprefixer'),
    -     ],
    -   },
    +   postcssOptions: {
    +     config: path.resolve(__dirname, '.github/postcss.config.js'),
    +   },
      },
    });

    方案 B – 在 inline plugins 中传入 Tailwind 配置:

    + const path = require('path');
    rule.use.push({
      loader: 'postcss-loader',
      options: {
        postcssOptions: {
          plugins: [
    -       require('tailwindcss'),
    +       require('tailwindcss')({ config: path.resolve(__dirname, '.github/tailwind.config.js') }),
            require('autoprefixer'),
          ],
        },
      },
    });
  2. 同时在 .github/postcss.config.js 中为 Tailwind 插件添加 config 路径(如你原先建议):

    + const path = require('path');
    module.exports = {
      plugins: {
    -   tailwindcss: {},
    +   tailwindcss: { config: path.resolve(__dirname, 'tailwind.config.js') },
        autoprefixer: {},
      }
    }

请根据项目实际需求,任选以上方案,并确保无论通过文件还是 inline,都能正确加载到 .github/tailwind.config.js

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
.github/postcss.config.js lines 1-6: postcss-loader may be ignoring this file
because webpack is using inline postcssOptions without a config path and
therefore Tailwind's config in .github/tailwind.config.js isn't loaded; fix by
either (A) updating webpack.config.js to point postcss-loader to the file (set
postcssOptions.config to the absolute/relative path of
.github/postcss.config.js) or (B) keep inline postcssOptions but pass Tailwind
the config explicitly (use tailwindcss({ config: path.resolve(__dirname,
'.github/tailwind.config.js') }) in the plugins array); additionally, update
.github/postcss.config.js to explicitly pass the Tailwind config path
(tailwindcss({ config: path.resolve(__dirname, 'tailwind.config.js') })) so the
file itself is self-contained if the loader reads it.

Comment on lines +1 to +18
module.exports = {
content: [
"./site/**/*.{js,jsx}",
"./edit/**/*.js",
"./docs/**/*.md",
"./guide/**/*.md"
],
theme: {
extend: {
colors: {
primary: '#1890ff',
heading: '#0d1a26',
text: '#314659'
}
},
},
plugins: [],
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

content 路径相对性错误:配置文件在 .github 目录,当前相对路径将扫描不到任何源码文件

Tailwind v3 的 JIT 会基于 content 扫描类名。该文件位于 .github 下,但 content 使用了以 ./ 开头的相对路径,实际会指向 .github/site、.github/edit 等目录(通常不存在),从而导致生成样式缺失或不完整。

建议显式将内容路径指向仓库根目录下的实际路径(使用绝对路径更稳健):

+const path = require('path');
+const root = path.resolve(__dirname, '..');
 module.exports = {
-  content: [
-    "./site/**/*.{js,jsx}",
-    "./edit/**/*.js",
-    "./docs/**/*.md",
-    "./guide/**/*.md"
-  ],
+  content: [
+    path.join(root, "site/**/*.{js,jsx}"),
+    path.join(root, "edit/**/*.js"),
+    path.join(root, "docs/**/*.md"),
+    path.join(root, "guide/**/*.md"),
+  ],
   theme: {
     extend: {
       colors: {
         primary: '#1890ff',
         heading: '#0d1a26',
         text: '#314659'
       }
     },
   },
   plugins: [],
 }

可选项:若与 Ant Design 的样式存在 Preflight 冲突,可考虑在此处关闭预设重置以降低风险:

  • 在导出对象中新增:corePlugins: { preflight: false }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
module.exports = {
content: [
"./site/**/*.{js,jsx}",
"./edit/**/*.js",
"./docs/**/*.md",
"./guide/**/*.md"
],
theme: {
extend: {
colors: {
primary: '#1890ff',
heading: '#0d1a26',
text: '#314659'
}
},
},
plugins: [],
}
const path = require('path');
const root = path.resolve(__dirname, '..');
module.exports = {
content: [
path.join(root, "site/**/*.{js,jsx}"),
path.join(root, "edit/**/*.js"),
path.join(root, "docs/**/*.md"),
path.join(root, "guide/**/*.md"),
],
theme: {
extend: {
colors: {
primary: '#1890ff',
heading: '#0d1a26',
text: '#314659'
}
},
},
plugins: [],
}
🤖 Prompt for AI Agents
.github/tailwind.config.js lines 1-18: the content globs are relative to the
config file in .github so "./site/**" will resolve to .github/site and miss real
source files; update the content globs to point at the repo root (e.g. use
"../site/**/*.{js,jsx}", "../edit/**/*.js", "../docs/**/*.md",
"../guide/**/*.md" or use path.resolve(__dirname, '..', 'site', '**',
'*.{js,jsx}') to build absolute paths) so Tailwind v3 scans actual source files,
and optionally add corePlugins: { preflight: false } to the exported config if
you need to disable Tailwind’s base reset due to Ant Design conflicts.

Comment on lines +76 to +79
"stylelint-config-standard": "^20.0.0",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.3"
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

确认是否已添加 postcss-loader 依赖,否则 Webpack 无法解析 PostCSS

PR 文案/总结中提到已在 webpack 中加入 postcss-loader,但 package.json 未新增该依赖。请确认它是否通过上游依赖间接提供;若没有,请补充 devDependencies 中的 postcss-loader(版本需与使用的 webpack 兼容)。

建议运行以下脚本核实依赖与配置(检查是否声明 postcss-loader、webpack 版本、以及仓库中是否存在 postcss-loader 配置):


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 查找 webpack 中对 postcss-loader 的使用 =="
rg -nC2 -tjs -g '!**/node_modules/**' -P 'postcss-loader|postcssOptions|TAILWIND_CONFIG|postcss\.config\.js|tailwindcss'

echo
echo "== 检查 package.json 是否声明 postcss-loader =="
jq -r '.devDependencies["postcss-loader"] // .dependencies["postcss-loader"] // "MISSING"' package.json

echo
echo "== 粗略查看 webpack 版本线索(若未直接声明,可能由 bisheng 间接提供) =="
jq -r '.devDependencies["webpack"] // .dependencies["webpack"] // "UNKNOWN (possibly transitive via bisheng/antd-tools)"' package.json

Length of output: 1350


缺少 postcss-loader 依赖,Webpack 配置无法解析 PostCSS

在 webpack.config.js (11–19 行) 已经使用了 postcss-loader,但 package.json 中未声明该依赖,可能导致构建失败。请在 devDependencies 中添加与当前 webpack 版本兼容的 postcss-loader。

• webpack.config.js (11–19 行):使用了 postcss-loader
• package.json:在 devDependencies 中新增 "postcss-loader": "^7.0.2"(请根据项目中实际使用的 webpack 版本调整)

示例 diff:

--- a/package.json
+++ b/package.json
@@ -76,6 +76,7 @@
     "stylelint-config-standard": "^20.0.0",
+    "postcss-loader": "^7.0.2",
     "autoprefixer": "^10.4.16",
     "postcss": "^8.4.31",
     "tailwindcss": "^3.3.3"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"stylelint-config-standard": "^20.0.0",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.3"
"stylelint-config-standard": "^20.0.0",
"postcss-loader": "^7.0.2",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.3"
🤖 Prompt for AI Agents
In package.json around lines 76 to 79, webpack config (lines 11–19) uses
postcss-loader but package.json lacks that dependency; add postcss-loader to
devDependencies (suggested "^7.0.2" or a version compatible with the project's
webpack), update package.json accordingly and run your package manager
(npm/yarn/pnpm install) to install it; verify webpack build succeeds and adjust
postcss-loader version if your webpack major requires a different compatible
release.

Comment on lines +71 to +75
<a
href={getNewHref('7111', null, true)}
target="_blank"
className="flex items-center justify-center mb-6"
>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

修复安全问题:target="_blank" 需配合 rel="noopener noreferrer"

避免反向标签劫持(reverse tabnabbing)与窗口对象泄漏。

-            <a 
-              href={getNewHref('7111', null, true)} 
-              target="_blank" 
-              className="flex items-center justify-center mb-6"
-            >
+            <a
+              href={getNewHref('7111', null, true)}
+              target="_blank"
+              rel="noopener noreferrer"
+              className="flex items-center justify-center mb-6"
+            >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<a
href={getNewHref('7111', null, true)}
target="_blank"
className="flex items-center justify-center mb-6"
>
<a
href={getNewHref('7111', null, true)}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-center mb-6"
>
🧰 Tools
🪛 ESLint

[error] 71-71: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 72-72: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 73-73: Trailing spaces not allowed.

(no-trailing-spaces)

🤖 Prompt for AI Agents
In site/edit/template/layout.jsx around lines 71 to 75, the anchor uses
target="_blank" without rel attributes which allows reverse tabnabbing and
window object leakage; add rel="noopener noreferrer" to the <a> element (or
compute and merge it if a rel already exists) so external opens are safe,
ensuring you preserve any existing rel values while preventing opener access.

Comment on lines +60 to +65
config.entry.index = [
path.join(__dirname, 'tailwind.css'), // Add this line
...(Array.isArray(config.entry.index)
? config.entry.index
: [config.entry.index])
];
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

引用的 Tailwind 样式路径错误,导致样式文件无法被注入

当前使用 path.join(__dirname, 'tailwind.css') 会在 site/theme/ 下寻找文件,但文件实际位于 site/site/tailwind.css。应修正为指向正确路径,并避免重复注入。

建议重构如下,同时修复数组展开的逗号尾随等问题并提高幂等性:

-  webpackConfig(config) {
-    // Add Tailwind CSS to global styles
-    config.entry.index = [
-      path.join(__dirname, 'tailwind.css'), // Add this line
-      ...(Array.isArray(config.entry.index) 
-        ? config.entry.index 
-        : [config.entry.index])
-    ];
-    
-    return config;
-  },
+  webpackConfig(config) {
+    const tailwindEntry = path.resolve(__dirname, '../site/tailwind.css');
+    // 将 Tailwind 全局样式放到最前,且避免重复注入
+    const toArray = (v) => (Array.isArray(v) ? v : [v].filter(Boolean));
+    const current = toArray(config.entry && config.entry.index);
+    config.entry.index = current.includes(tailwindEntry)
+      ? current
+      : [tailwindEntry, ...current];
+    return config;
+  },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
config.entry.index = [
path.join(__dirname, 'tailwind.css'), // Add this line
...(Array.isArray(config.entry.index)
? config.entry.index
: [config.entry.index])
];
webpackConfig(config) {
const tailwindEntry = path.resolve(__dirname, '../site/tailwind.css');
// 将 Tailwind 全局样式放到最前,且避免重复注入
const toArray = (v) => (Array.isArray(v) ? v : [v].filter(Boolean));
const current = toArray(config.entry && config.entry.index);
config.entry.index = current.includes(tailwindEntry)
? current
: [tailwindEntry, ...current];
return config;
},
🧰 Tools
🪛 ESLint

[error] 62-62: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 63-63: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 64-65: Missing trailing comma.

(comma-dangle)

🤖 Prompt for AI Agents
In site/theme/index.js around lines 60 to 65, the injected Tailwind path is
wrong and may be duplicated: change the insertion to point to the actual file at
path.join(__dirname, '..', 'site', 'tailwind.css') (or an absolute resolve
equivalent) and make the operation idempotent by first normalizing
config.entry.index to an array (handle missing value), checking whether that
resolved Tailwind path is already present, and only unshifting/prepending it
when absent; also ensure you don't leave stray trailing commas when rebuilding
the array.

Comment on lines +6 to +26
// Add PostCSS support
const addPostCssLoader = (config) => {
// Find CSS rule and modify it
config.module.rules.forEach(rule => {
if (rule.test && rule.test.toString().includes('css')) {
// Add postcss-loader to existing CSS loaders
rule.use.push({
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
});
}
});
};

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

改造 addPostCssLoader:提升健壮性与加载顺序,避免破坏 less/sass 规则

当前实现存在几个潜在问题:

  • 直接 rule.use.push(...) 假定 use 一定是数组;但在 webpack 中 use 可能是对象、字符串或函数,甚至存在 loader/options 形式或嵌套 oneOf
  • 仅通过 rule.test.toString().includes('css') 判断,可能命中同时处理 css|less 的规则;若把 postcss-loader追加到末尾,会导致“postcss 在 less/sass 之前执行”,加工的将是 .less/.sass 源文件而非 CSS,构建会出错。
  • 没有去重,若后续重复执行或已有 postcss-loader,会导致重复插入。
  • 触发 ESLint(arrow-parens、global-require)。

建议将注入逻辑改为:

  • 递归地处理 oneOf
  • 规范化 use 为数组后再处理。
  • 已存在 postcss-loader 时跳过。
  • 如存在 less/sass/stylus 预处理器,则将 postcss-loader 插入到预处理器之前(数组顺序上),以保证执行顺序为:preprocessor -> postcss -> css -> style。
  • tailwindcssautoprefixer 的 require 提至顶层,消除 global-require 与保证可读性。

可按以下 diff 一次性修复(同时满足 ESLint 提示):

-// Add PostCSS support
-const addPostCssLoader = (config) => {
-  // Find CSS rule and modify it
-  config.module.rules.forEach(rule => {
-    if (rule.test && rule.test.toString().includes('css')) {
-      // Add postcss-loader to existing CSS loaders
-      rule.use.push({
-        loader: 'postcss-loader',
-        options: {
-          postcssOptions: {
-            plugins: [
-              require('tailwindcss'),
-              require('autoprefixer'),
-            ],
-          },
-        },
-      });
-    }
-  });
-};
+// Add PostCSS support
+const tailwindcss = require('tailwindcss');
+const autoprefixer = require('autoprefixer');
+
+const addPostCssLoader = (config) => {
+  const ensureArray = (use) => (Array.isArray(use) ? use : (use ? [use] : []));
+
+  const injectIntoRule = (rule) => {
+    if (!rule) return;
+    // 递归处理 oneOf
+    if (Array.isArray(rule.oneOf)) {
+      rule.oneOf.forEach(injectIntoRule);
+      return;
+    }
+    if (!rule.test) return;
+
+    const testStr = rule.test.toString();
+    // 仅对包含 css 的规则生效
+    if (!testStr.includes('css')) return;
+
+    // 规范化 use
+    let useArr = ensureArray(rule.use || (rule.loader && { loader: rule.loader, options: rule.options }));
+
+    // 去重:若已包含 postcss-loader 则跳过
+    if (useArr.some((u) => (u && (u.loader || u)).toString().includes('postcss-loader'))) return;
+
+    const postcss = {
+      loader: 'postcss-loader',
+      options: {
+        postcssOptions: {
+          plugins: [tailwindcss, autoprefixer],
+        },
+      },
+    };
+
+    // 若存在 less/sass/stylus 预处理器,则将 postcss 插在其“之前”的位置(数组顺序),
+    // 确保执行顺序为:preprocessor -> postcss -> css -> style
+    const preprocessorIdx = useArr.findIndex((u) =>
+      /less-loader|sass-loader|stylus-loader/.test((u && (u.loader || u)) || ''),
+    );
+    if (preprocessorIdx !== -1) {
+      useArr.splice(preprocessorIdx, 0, postcss);
+    } else {
+      // 纯 CSS 则直接追加到末尾(典型链:style-loader, css-loader, postcss-loader)
+      useArr.push(postcss);
+    }
+
+    // 将 loader/options 形式规范回 use 数组
+    if (rule.loader) {
+      delete rule.loader;
+      delete rule.options;
+    }
+    // 回写
+    rule.use = useArr;
+  };
+
+  (config.module.rules || []).forEach(injectIntoRule);
+};

如项目将 Tailwind 配置文件放在非默认路径(本 PR 描述为 .github/tailwind.config.js),建议显式传入 config 路径(见下一条评论)。
此改造后,也可避免重复执行本函数时二次注入。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Add PostCSS support
const addPostCssLoader = (config) => {
// Find CSS rule and modify it
config.module.rules.forEach(rule => {
if (rule.test && rule.test.toString().includes('css')) {
// Add postcss-loader to existing CSS loaders
rule.use.push({
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
});
}
});
};
// Add PostCSS support
const tailwindcss = require('tailwindcss');
const autoprefixer = require('autoprefixer');
const addPostCssLoader = (config) => {
const ensureArray = (use) => (Array.isArray(use) ? use : (use ? [use] : []));
const injectIntoRule = (rule) => {
if (!rule) return;
// 递归处理 oneOf
if (Array.isArray(rule.oneOf)) {
rule.oneOf.forEach(injectIntoRule);
return;
}
if (!rule.test) return;
const testStr = rule.test.toString();
// 仅对包含 css 的规则生效
if (!testStr.includes('css')) return;
// 规范化 use
let useArr = ensureArray(rule.use || (rule.loader && { loader: rule.loader, options: rule.options }));
// 去重:若已包含 postcss-loader 则跳过
if (useArr.some((u) => (u && (u.loader || u)).toString().includes('postcss-loader'))) return;
const postcss = {
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [tailwindcss, autoprefixer],
},
},
};
// 若存在 less/sass/stylus 预处理器,则将 postcss 插在其“之前”的位置(数组顺序),
// 确保执行顺序为:preprocessor -> postcss -> css -> style
const preprocessorIdx = useArr.findIndex((u) =>
/less-loader|sass-loader|stylus-loader/.test((u && (u.loader || u)) || '')
);
if (preprocessorIdx !== -1) {
useArr.splice(preprocessorIdx, 0, postcss);
} else {
// 纯 CSS 则直接追加到末尾(典型链:style-loader, css-loader, postcss-loader)
useArr.push(postcss);
}
// 将 loader/options 形式规范回 use 数组
if (rule.loader) {
delete rule.loader;
delete rule.options;
}
// 回写
rule.use = useArr;
};
(config.module.rules || []).forEach(injectIntoRule);
};
🧰 Tools
🪛 ESLint

[error] 9-9: Expected parentheses around arrow function argument.

(arrow-parens)


[error] 17-17: Unexpected require().

(global-require)


[error] 18-18: Unexpected require().

(global-require)

🤖 Prompt for AI Agents
In webpack.config.js around lines 6 to 26, the addPostCssLoader helper is
brittle: it assumes rule.use is an array, only checks rule.test string for
'css', appends postcss-loader which can run in the wrong order for
less/sass/stylus, may insert duplicates, and triggers ESLint
global-require/arrow-parens issues; fix by moving require('tailwindcss') and
require('autoprefixer') to top-level constants, make addPostCssLoader
recursively traverse rule.oneOf arrays, normalize rule.use into an array form
before modifying, detect and skip if a postcss-loader is already present, and
insert the postcss-loader just before any preprocessor loader (less/sass/stylus)
so order becomes preprocessor -> postcss -> css -> style; ensure you handle
cases where use is a string/object/function and preserve existing loader options
while avoiding duplicate insertion.

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