Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ pnpm dev
pnpm build
```

If you find this helpful, welcome to give us a star ⭐️⭐️⭐️

## License

[MIT](./LICENSE)
2 changes: 2 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ pnpm dev
pnpm build
```

如果您觉得这个项目有帮助,欢迎给我们点个 star ⭐️⭐️⭐️

## 许可证

[MIT](./LICENSE)
4 changes: 2 additions & 2 deletions docs/docs/config/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export default defineConfig({
比如将 node_modules 下的 `@m-ui/react` 库拆分到 `m-ui.js` 中:

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


export default defineConfig({
codeSplitting: {
Expand All @@ -318,7 +318,7 @@ export default defineConfig({
可以通过 `codeSplitting.override` 配置项来自定义 Rspack(Webpack) 拆包配置, 此配置会和 Rspack(Webpack) 的 splitChunks 配置进行合并(cacheGroups 配置也会合并)。比如:

```ts [config/config.ts]
import { createDependenciesRegExp } from '@kmi/kmijs/plugin-utils'
import { createDependenciesRegExp } from 'umi/plugin-utils'

export default defineConfig({
codeSplitting: {
Expand Down
8 changes: 0 additions & 8 deletions docs/docs/config/html-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,6 @@ links: [{ href: '/foo.css', rel: 'preload' }]
```

```ts [config/config.ts]
import { defineConfig } from '@kmi/kmijs'

export default defineConfig({
links: [{ href: '/foo.css', rel: 'preload' }] // [!code ++]
})
Expand Down Expand Up @@ -175,8 +173,6 @@ type MetaOptions = {

比如设置 description:
```ts [config/config.ts]
import { defineConfig } from '@kmi/kmijs'

export default defineConfig({
metas: {
description: 'a description of the page', // [!code ++]
Expand All @@ -203,8 +199,6 @@ type MetaOptions = {
比如配置配置 X-UA-Compatible

```ts [config/config.ts]
import { defineConfig } from '@kmi/kmijs'

export default defineConfig({
metas: {
'X-UA-Compatible': { // [!code ++]
Expand Down Expand Up @@ -233,8 +227,6 @@ type Metas = Array<HTMLMetaElement>
示例:

```ts [config/config.ts]
import { defineConfig } from '@kmi/kmijs'

export default defineConfig({
metas: [
{ name: 'keywords', content: 'kmi, kmijs' }, // [!code ++]
Expand Down
2 changes: 0 additions & 2 deletions docs/docs/guide/rspack.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
从 Umi 的 `4.4.11` 版本起,在一个已有的 Umi 项目中,你仅需在 `config/config.ts` 中添加以下配置,即可启用 Rspack 构建:

```ts [config/config.ts]
import { defineConfig } from '@kmi/kmijs';

export default defineConfig({
// Configure Kmi preset
presets: ['@kmijs/preset-bundler'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import type { IApi } from '@kmijs/types'

export default (api: IApi) => {
api.describe({
key: 'removeConsole',
config: {
schema({ zod }) {
return zod.union([
zod.boolean(),
zod.array(zod.enum(['error', 'warn', 'info', 'log'])),
])
},
},
enableBy: api.EnableBy.config,
})

api.onCheckConfig(({ userConfig }) => {
if (userConfig.jsMinifier === 'uglifyJs') {
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.modifyConfig((memo) => {
const { removeConsole } = memo
const isRspack = api.appData.bundler === 'rspack'
// 默认是 esbuild
const jsMinifier =
api.appData.bundler === 'rspack'
? 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.
? { pure_funcs: removeConsole.map((method) => `console.${method}`) }
: { drop_console: true }
Comment on lines +35 to +37
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.


if (isRspack && jsMinifier === 'swc') {
memo.jsMinifierOptions = {
...memo.jsMinifierOptions,
minimizerOptions: {
...memo.jsMinifierOptions?.minimizerOptions,
compress: {
...memo.jsMinifierOptions?.minimizerOptions?.compress,
...compressOptions,
},
},
}
Comment on lines +40 to +49
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.

return memo
}

// esbuild
if (jsMinifier === 'esbuild') {
const compressOptions = Array.isArray(removeConsole)
? { pure: removeConsole.map((method) => `console.${method}`) }
: { drop: ['console'] }
memo.jsMinifierOptions = {
...memo.jsMinifierOptions,
...compressOptions,
Comment on lines +55 to +60
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.
}
return memo
}

// terser
if (jsMinifier === 'terser') {
memo.jsMinifierOptions = {
...memo.jsMinifierOptions,
compress: {
...memo.jsMinifierOptions?.compress,
...compressOptions,
},
}
return memo
}
return memo
})
}
1 change: 1 addition & 0 deletions packages/preset-bundler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default (api: IApi) => {
require.resolve('./features/transformConfig'),
require.resolve('./features/define/define'),
require.resolve('./features/codeSplitting/codeSplitting'),
require.resolve('./features/removeConsole/removeConsole'),
// plugins
require.resolve('@kmijs/plugin-svgr'),

Expand Down