Skip to content

feat: add removeConsole feature for console stripping in builds#27

Merged
xierenyuan merged 4 commits intomainfrom
feat/add-remove-console-feature
Jul 21, 2025
Merged

feat: add removeConsole feature for console stripping in builds#27
xierenyuan merged 4 commits intomainfrom
feat/add-remove-console-feature

Conversation

@xierenyuan
Copy link
Contributor

@xierenyuan xierenyuan commented Jul 21, 2025

Close #26

Summary by CodeRabbit

  • New Features

    • Introduced a configuration option to remove specific console statements (e.g., error, warn, info, log) during the build process, with support for multiple minifiers and bundlers.
  • Documentation

    • Updated documentation examples to simplify import statements and clarify configuration usage.
    • Added messages in both English and Chinese READMEs encouraging users to star the project if they find it helpful.

Copilot AI review requested due to automatic review settings July 21, 2025 02:24
@coderabbitai
Copy link

coderabbitai bot commented Jul 21, 2025

Warning

Rate limit exceeded

@xierenyuan has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 4 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 318b14e and 4b5df27.

📒 Files selected for processing (1)
  • packages/preset-bundler/src/features/removeConsole/removeConsole.ts (1 hunks)

Walkthrough

A new removeConsole feature was implemented in the bundler preset, allowing users to configure removal of specific console methods during the build process. Documentation examples were updated to simplify or correct import statements, and both English and Chinese READMEs received a new line encouraging users to star the project.

Changes

Files/Paths Change Summary
packages/preset-bundler/src/features/removeConsole/removeConsole.ts Introduced removeConsole feature plugin for configurable console statement removal in builds.
packages/preset-bundler/src/index.ts Registered the new removeConsole feature in the bundler preset plugin list.
docs/docs/config/config.md Updated import source in examples from @kmi/kmijs/plugin-utils to umi/plugin-utils.
docs/docs/config/html-config.md, docs/docs/guide/rspack.md Removed redundant defineConfig import statements from documentation examples.
README.md, README.zh-CN.md Added a line encouraging users to star the project after build instructions.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Bundler
    participant RemoveConsolePlugin

    User->>Bundler: Configure build with removeConsole option
    Bundler->>RemoveConsolePlugin: Register and validate removeConsole config
    RemoveConsolePlugin-->>Bundler: Modify minifier options to remove console methods
    Bundler-->>User: Produce build output with specified console methods removed
Loading

Poem

🐇✨
A hop, a skip, a console gone,
Our builds are cleaner, moving on!
Docs now shine with simpler code,
And stars are wished upon this road.
With every tweak, this project grows—
Thanks for the help, the bunny knows!
⭐⭐⭐

✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements a new removeConsole feature that allows stripping console statements from production builds to reduce bundle size and improve performance. The feature supports different JavaScript minifiers (esbuild, terser, swc) and bundlers (webpack, rspack) with appropriate configuration validation.

  • Adds a new removeConsole plugin with schema validation and minifier-specific configuration
  • Integrates the plugin into the preset-bundler package
  • Updates documentation to remove redundant import statements and adds promotional content

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/preset-bundler/src/index.ts Registers the new removeConsole feature plugin
packages/preset-bundler/src/features/removeConsole/removeConsole.ts Core implementation of console removal feature with multi-minifier support
docs/docs/guide/rspack.md Removes redundant import statement from code example
docs/docs/config/html-config.md Removes redundant import statements from multiple code examples
docs/docs/config/config.md Updates import path references in code examples
README.zh-CN.md Adds promotional star request message
README.md Adds promotional star request message

throw new Error('removeConsole 不支持 uglifyJs')
}
if (api.appData.bundler === 'webpack' && userConfig.jsMinifier === 'swc') {
throw new Error('removeConsole 在 webpack 模式下不支持使用 swc 压缩')
Copy link

Copilot AI Jul 21, 2025

Choose a reason for hiding this comment

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

Error message is in Chinese. Consider using English for consistency with the codebase, or provide internationalization support.

Suggested change
throw new Error('removeConsole 在 webpack 模式下不支持使用 swc 压缩')
throw new Error('removeConsole does not support using swc compression in webpack mode')

Copilot uses AI. Check for mistakes.
? api.userConfig.jsMinifier || 'swc'
: api.userConfig.jsMinifier || 'esbuild'

const compressOptions = Array.isArray(removeConsole)
Copy link

Copilot AI Jul 21, 2025

Choose a reason for hiding this comment

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

The variable name 'compressOptions' is used twice with different structures (lines 35 and 55). Consider using more specific names like 'swcCompressOptions' and 'esbuildCompressOptions' to avoid confusion.

Suggested change
const compressOptions = Array.isArray(removeConsole)
const swcCompressOptions = Array.isArray(removeConsole)

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +60
const compressOptions = Array.isArray(removeConsole)
? { pure: removeConsole.map((method) => `console.${method}`) }
: { drop: ['console'] }
memo.jsMinifierOptions = {
...memo.jsMinifierOptions,
...compressOptions,
Copy link

Copilot AI Jul 21, 2025

Choose a reason for hiding this comment

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

This variable shadows the 'compressOptions' variable declared on line 35. Consider using a different name like 'esbuildOptions' to improve code clarity.

Suggested change
const compressOptions = Array.isArray(removeConsole)
? { pure: removeConsole.map((method) => `console.${method}`) }
: { drop: ['console'] }
memo.jsMinifierOptions = {
...memo.jsMinifierOptions,
...compressOptions,
const esbuildOptions = Array.isArray(removeConsole)
? { pure: removeConsole.map((method) => `console.${method}`) }
: { drop: ['console'] }
memo.jsMinifierOptions = {
...memo.jsMinifierOptions,
...esbuildOptions,

Copilot uses AI. Check for mistakes.
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: 3

🧹 Nitpick comments (5)
README.zh-CN.md (1)

154-155: Hyper-link the call-to-action & tweak wording for clarity

Adding a star reminder is great, but readers can’t click directly. Consider linking to the repo and polishing the copy slightly.

-如果您觉得这个项目有帮助,欢迎给我们点个 star ⭐️⭐️⭐️
+如果您觉得这个项目对您有所帮助,请在 GitHub 上给我们点个 ⭐️ [Star](https://github.com/kmijs/kmi)
README.md (1)

155-156: Add link & tighten phrasing

Same comment as the Chinese README—make the CTA actionable and slightly crisper.

-If you find this helpful, welcome to give us a star ⭐️⭐️⭐️
+If you find this project helpful, please consider giving it a ⭐️ [Star](https://github.com/kmijs/kmi) on GitHub
packages/preset-bundler/src/features/removeConsole/removeConsole.ts (3)

18-23: Consider using English for error messages to maintain consistency.

The error messages are currently in Chinese. For better maintainability and consistency with typical JavaScript/TypeScript codebases, consider using English error messages.

-      throw new Error('removeConsole 不支持 uglifyJs')
+      throw new Error('removeConsole does not support uglifyJs minifier')
-      throw new Error('removeConsole 在 webpack 模式下不支持使用 swc 压缩')
+      throw new Error('removeConsole does not support swc minifier in webpack mode')

30-33: Clarify the default minifier logic.

The default minifier selection logic appears inconsistent. Both branches check for rspack but assign different defaults. Consider clarifying this logic.

-    const jsMinifier =
-      api.appData.bundler === 'rspack'
-        ? api.userConfig.jsMinifier || 'swc'
-        : api.userConfig.jsMinifier || 'esbuild'
+    const defaultMinifier = api.appData.bundler === 'rspack' ? 'swc' : 'esbuild'
+    const jsMinifier = api.userConfig.jsMinifier || defaultMinifier

26-77: Consider extracting configuration logic into helper functions.

The main function is quite long and handles multiple minifier configurations. Consider extracting the configuration logic for better maintainability.

// Helper functions
function createSwcConfig(removeConsole: boolean | string[], existingOptions: any) {
  const compressOptions = Array.isArray(removeConsole)
    ? { pure_funcs: removeConsole.map((method) => `console.${method}`) }
    : { drop_console: true }
    
  const existingMinifierOptions = existingOptions || {}
  const existingMinimizerOptions = existingMinifierOptions.minimizerOptions || {}
  const existingCompress = existingMinimizerOptions.compress || {}
  
  return {
    ...existingMinifierOptions,
    minimizerOptions: {
      ...existingMinimizerOptions,
      compress: {
        ...existingCompress,
        ...compressOptions,
      },
    },
  }
}

function createEsbuildConfig(removeConsole: boolean | string[], existingOptions: any) {
  const esbuildOptions = Array.isArray(removeConsole)
    ? { pure: removeConsole.map((method) => `console.${method}`) }
    : { drop: ['console'] }
    
  return {
    ...existingOptions,
    ...esbuildOptions,
  }
}

function createTerserConfig(removeConsole: boolean | string[], existingOptions: any) {
  const compressOptions = Array.isArray(removeConsole)
    ? { pure_funcs: removeConsole.map((method) => `console.${method}`) }
    : { drop_console: true }
    
  const existingCompress = existingOptions?.compress || {}
  
  return {
    ...existingOptions,
    compress: {
      ...existingCompress,
      ...compressOptions,
    },
  }
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9317464 and c721251.

📒 Files selected for processing (7)
  • README.md (1 hunks)
  • README.zh-CN.md (1 hunks)
  • docs/docs/config/config.md (2 hunks)
  • docs/docs/config/html-config.md (0 hunks)
  • docs/docs/guide/rspack.md (0 hunks)
  • packages/preset-bundler/src/features/removeConsole/removeConsole.ts (1 hunks)
  • packages/preset-bundler/src/index.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • docs/docs/guide/rspack.md
  • docs/docs/config/html-config.md
⏰ 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). (4)
  • GitHub Check: Cursor BugBot
  • GitHub Check: build-and-test (22.x, windows-latest)
  • GitHub Check: lint
  • GitHub Check: build-and-test (22.x, ubuntu-latest)
🔇 Additional comments (1)
packages/preset-bundler/src/index.ts (1)

19-19: LGTM! Feature plugin registration follows established pattern.

The removeConsole feature plugin is correctly registered following the same pattern as other feature plugins in the preset.


```ts [config/config.ts]
import { createDependenciesRegExp } from '@kmi/kmijs/plugin-utils'
import { createDependenciesRegExp } from 'umi/plugin-utils'
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

Verify the correctness of the updated import paths.

The import statements have been updated from @kmi/kmijs/plugin-utils to umi/plugin-utils. Please confirm that this is the correct import path and that the createDependenciesRegExp function is available from umi/plugin-utils.

Also applies to: 321-321


🏁 Script executed:

#!/bin/bash
# Description: Verify the existence and availability of createDependenciesRegExp from umi/plugin-utils

# Search for createDependenciesRegExp in the codebase
echo "Searching for createDependenciesRegExp function..."
rg -A 3 "createDependenciesRegExp" --type ts --type js

echo -e "\n=== Checking umi/plugin-utils exports ==="
# Look for umi/plugin-utils in package.json or similar files
fd "package\.json" --exec grep -l "umi" {} \;

echo -e "\n=== Checking for plugin-utils imports ==="
# Search for other uses of plugin-utils imports
rg "plugin-utils" --type ts --type js -A 2 -B 2

Length of output: 281114


Update documentation import source for createDependenciesRegExp

The docs currently import createDependenciesRegExp from umi/plugin-utils, but that helper is defined and exported by @kmijs/shared, not umi/plugin-utils.

Please update both occurrences in docs/docs/config/config.md:

• Line 299
• Line 321

Suggested change:

- import { createDependenciesRegExp } from 'umi/plugin-utils'
+ import { createDependenciesRegExp } from '@kmijs/shared'
📝 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
import { createDependenciesRegExp } from 'umi/plugin-utils'
-import { createDependenciesRegExp } from 'umi/plugin-utils'
+import { createDependenciesRegExp } from '@kmijs/shared'
🤖 Prompt for AI Agents
In docs/docs/config/config.md at lines 299 and 321, the import source for
createDependenciesRegExp is incorrectly set to umi/plugin-utils. Change both
import statements to import createDependenciesRegExp from @kmijs/shared instead
to reflect the correct module source.

Comment on lines +35 to +37
const compressOptions = Array.isArray(removeConsole)
? { pure_funcs: removeConsole.map((method) => `console.${method}`) }
: { drop_console: true }
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Eliminate duplicate options creation logic.

The compressOptions creation is duplicated for different minifiers. This can lead to confusion and maintenance issues.

Consider restructuring the logic to avoid duplication:

-    const compressOptions = Array.isArray(removeConsole)
-      ? { pure_funcs: removeConsole.map((method) => `console.${method}`) }
-      : { drop_console: true }
-
     if (isRspack && jsMinifier === 'swc') {
+      const compressOptions = Array.isArray(removeConsole)
+        ? { pure_funcs: removeConsole.map((method) => `console.${method}`) }
+        : { drop_console: true }
       memo.jsMinifierOptions = {
         ...memo.jsMinifierOptions,
         minimizerOptions: {
           ...memo.jsMinifierOptions?.minimizerOptions,
           compress: {
             ...memo.jsMinifierOptions?.minimizerOptions?.compress,
             ...compressOptions,
           },
         },
       }
       return memo
     }

     // esbuild
     if (jsMinifier === 'esbuild') {
-      const compressOptions = Array.isArray(removeConsole)
-        ? { pure: removeConsole.map((method) => `console.${method}`) }
-        : { drop: ['console'] }
+      const esbuildOptions = Array.isArray(removeConsole)
+        ? { pure: removeConsole.map((method) => `console.${method}`) }
+        : { drop: ['console'] }
       memo.jsMinifierOptions = {
         ...memo.jsMinifierOptions,
-        ...compressOptions,
+        ...esbuildOptions,
       }
       return memo
     }

     // terser
     if (jsMinifier === 'terser') {
+      const terserOptions = Array.isArray(removeConsole)
+        ? { pure_funcs: removeConsole.map((method) => `console.${method}`) }
+        : { drop_console: true }
       memo.jsMinifierOptions = {
         ...memo.jsMinifierOptions,
         compress: {
           ...memo.jsMinifierOptions?.compress,
-          ...compressOptions,
+          ...terserOptions,
         },
       }
       return memo
     }

Also applies to: 55-57

🤖 Prompt for AI Agents
In packages/preset-bundler/src/features/removeConsole/removeConsole.ts around
lines 35-37 and 55-57, the logic for creating compressOptions is duplicated for
different minifiers, which can cause confusion and maintenance problems.
Refactor the code to centralize the creation of compressOptions by extracting
the shared logic into a single function or variable that can be reused for both
minifiers, eliminating the repeated code blocks.

Comment on lines +40 to +49
memo.jsMinifierOptions = {
...memo.jsMinifierOptions,
minimizerOptions: {
...memo.jsMinifierOptions?.minimizerOptions,
compress: {
...memo.jsMinifierOptions?.minimizerOptions?.compress,
...compressOptions,
},
},
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve type safety for minifier options.

The code accesses nested properties without proper type checking, which could lead to runtime errors.

Consider adding type guards or using optional chaining more defensively:

     if (isRspack && jsMinifier === 'swc') {
+      const existingMinifierOptions = memo.jsMinifierOptions || {}
+      const existingMinimizerOptions = existingMinifierOptions.minimizerOptions || {}
+      const existingCompress = existingMinimizerOptions.compress || {}
+      
       memo.jsMinifierOptions = {
-        ...memo.jsMinifierOptions,
+        ...existingMinifierOptions,
         minimizerOptions: {
-          ...memo.jsMinifierOptions?.minimizerOptions,
+          ...existingMinimizerOptions,
           compress: {
-            ...memo.jsMinifierOptions?.minimizerOptions?.compress,
+            ...existingCompress,
             ...compressOptions,
           },
         },
       }
       return memo
     }

Similar improvements should be applied to the terser configuration block.

Also applies to: 67-74

🤖 Prompt for AI Agents
In packages/preset-bundler/src/features/removeConsole/removeConsole.ts around
lines 40 to 49 and 67 to 74, the code accesses nested properties of
jsMinifierOptions without sufficient type safety, risking runtime errors. Add
type guards to verify the existence and correct type of each nested property
before spreading or accessing them, or enhance optional chaining usage to safely
handle undefined values. This ensures that the minifier options and terser
configuration blocks are accessed and merged only when valid, preventing
potential crashes.

xierenyuan and others added 2 commits July 21, 2025 10:44
…le.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…le.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@xierenyuan xierenyuan merged commit 77d5ca7 into main Jul 21, 2025
5 checks passed
@xierenyuan xierenyuan deleted the feat/add-remove-console-feature branch July 21, 2025 02:58
@coderabbitai coderabbitai bot mentioned this pull request Sep 4, 2025
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.

removeConsole是不是还没实现

2 participants