> For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt.

# 配置变更

本篇文档主要介绍从 Modern.js 2.0 升级到 3.0 时，配置项层面的不兼容变更以及推荐的迁移方式。

## dev

### dev.port

**变更内容**：该配置已被移除，改为 `server.port`。

**迁移示例**：

```typescript
// 改动前
dev: {
  port: 8080;
}

// 改动后
server: {
  port: process.env.NODE_ENV === 'development' ? 8080 : undefined;
}
```

### dev.lazyCompilation

**变更内容**：开发环境下的默认值变化。纯 CSR 与流式 SSR 应用默认开启按需编译，默认值为 `{ imports: true, entries: false }`；使用 string SSR、RSC 或 SSG 的应用仍默认关闭。该变更只影响开发环境，不影响生产构建产物。

**迁移示例**：如需保持 2.0 的行为，可以显式关闭：

```typescript
dev: {
  lazyCompilation: false;
}
```

## html

### html.appIcon

**变更内容**：不再支持字符串形式，必须使用对象格式。

**V2 类型**:

```typescript
type AppIconItem = {
  src: string;
  size: number;
  target?: 'apple-touch-icon' | 'web-app-manifest';
};

type AppIcon =
  | string
  | {
      name?: string;
      icons: AppIconItem[];
      filename?: string;
    };
```

**V3 类型**:

```typescript
type AppIconItem = {
  src: string;
  size: number;
  target?: 'apple-touch-icon' | 'web-app-manifest';
};

type AppIcon = {
  name?: string;
  icons: AppIconItem[];
  filename?: string;
};
```

**迁移示例**：

```typescript
// v2
export default {
  html: {
    appIcon: './src/assets/icon.png',
  },
};

// v3
export default {
  html: {
    appIcon: {
      icons: [
        {
          src: './src/assets/icon.png',
          size: 180,
        },
      ],
    },
  },
};
```

### html.xxxByEntries

**变更内容**：`metaByEntries`、`templateParametersByEntries`、`injectByEntries`、`tagsByEnties`、`faviconByEntries`、`templateByEnties`、`titleByEntries` 等配置已废弃，需要使用函数语法代替。

**处理步骤**:

1. 移除相关配置
2. 使用 `html.xxx` 的函数用法代替

**迁移示例**：

```typescript
// v2
export default {
  html: {
    metaByEntries: {
      foo: {
        description: 'TikTok',
      },
      // 其他配置...
    },
  },
};

// v3
export default {
  html: {
    meta({ entryName }) {
      switch (entryName) {
        case 'foo':
          return {
            description: 'TikTok',
          };
        // 其他配置...
      }
    },
  },
};
```

### html.disableHtmlFolder

**变更内容**：该配置已废弃，使用 `html.outputStructure` 代替。

**迁移示例**：

```typescript
// v2 - 等同于 html.outputStructure 配置为 nested
export default {
  html: {
    disableHtmlFolder: true,
  },
};

// v3
export default {
  html: {
    outputStructure: 'flat',
  },
};
```

## tools

### toos.postcss

**变更内容**：对象式配置会覆盖 Modern.js 内置的 PostCSS 配置。如果需要在内置配置基础上进行扩展，请使用函数式配置。

```typescript
// v2
export default {
  tools: {
    postcss: {
      postcssOptions: {
        plugins: [tailwindcssPlugin],
      },
    },
  },
};
```

```typescript
// v3
export default {
  tools: {
    postcss: (opts, { addPlugins }) => {
      addPlugins(tailwindcssPlugin);
    },
  },
};
```

### tools.esbuild

**变更内容**：该配置已废弃，需要手动切换到 esbuild 压缩。

```typescript
// 该配置已废弃，请参考 [切换压缩器](https://v2.rsbuild.rs/zh/config/output/minify#%E5%88%87%E6%8D%A2%E5%8E%8B%E7%BC%A9%E5%99%A8) 来手动切换到 esbuild 压缩
// tools: {
//   esbuild: { /* 配置 */ }
// },
```

### tools.terser

**变更内容**：该配置已废弃，需要手动切换到 Terser 压缩。

```typescript
// 该配置已废弃，请参考 [切换压缩器](https://v2.rsbuild.rs/zh/config/output/minify#%E5%88%87%E6%8D%A2%E5%8E%8B%E7%BC%A9%E5%99%A8) 来手动切换到 Terser 压缩
// tools: {
//   terser: { /* 配置 */ }
// },
```

### tools.devServer

**变更内容 1**: `after`、`before`、`devMiddleware` 配置已废弃，使用 `dev.setupDevMiddlewares` 配置代替。

**迁移示例**：

```typescript
// v2
export default {
  tools: {
    devServer: {
      before: [...],
      after: [...],
      devMiddleware: {
        writeToDisk: true
      }
    }
  }
};

// v3
export default {
  dev: {
    setupMiddlewares: [...],
    writeToDisk: true
  }
};
```

**变更内容 2**: `client`、`https`、`liveReload` 配置已废弃，使用对应的 `dev.client`、`dev.https`、`dev.liveReload` 配置代替。

**迁移示例**：

```typescript
// v2
export default {
  tools: {
    devServer: {
      client: {
        port: 8081,
      },
    },
  },
};

// v3
export default {
  dev: {
    client: {
      port: 8081,
    },
  },
};
```

**变更内容 3**: `hot` 配置已废弃，使用 `dev.hmr` 配置代替。

**迁移示例**：

```typescript
// v2
export default {
  tools: {
    devServer: {
      hot: false,
    },
  },
};

// v3
export default {
  dev: {
    hmr: false,
  },
};
```

**变更内容 4**: `compress`、`headers`、`historyApiFallback`、`watch` 配置已废弃，使用 `dev.server.compress`、`dev.server.headers`、`dev.server.historyApiFallback`、`dev.server.watch` 配置代替。

**迁移示例**：

```typescript
// v2
export default {
  tools: {
    devServer: {
      compress: true,
      headers: {
        'X-Custom-Header': 'custom-value',
      },
      historyApiFallback: true,
      watch: true,
    },
  },
};

// v3
export default {
  dev: {
    server: {
      compress: true,
      headers: {
        'X-Custom-Header': 'custom-value',
      },
      historyApiFallback: true,
      watch: true,
    },
  },
};
```

### tools.pug

**变更内容**：该配置已废弃，使用 Rsbuild 的 [Pug 插件](https://github.com/rstackjs/rsbuild-plugin-pug) 来启用支持。

**迁移示例**：

```typescript
// v2
tools: {
  pug: true,
},

// v3
import { pluginPug } from "@rsbuild/plugin-pug";

export default {
  builderPlugins: [pluginPug()],
};
```

### tools.rsdoctor

**变更内容**：该配置已废弃，请参考 [Rsdoctor 文档](/zh/guides/basic-features/debug/rsdoctor.md)，使用 Rspack 的 [Rsdoctor 插件](https://rsdoctor.dev/)来启用支持。

**迁移示例**：

```typescript
// v2
tools: {
  rsdoctor: {
    disableClientServer: true,
    features: ['bundle', 'loader', 'plugins', 'resolver'],
  },
},

// v3
import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin';

export default {
  // ...
  tools: {
    bundlerChain(chain) {
      // 仅在 RSDOCTOR 为 true 时注册插件，因为插件会增加构建耗时
      if (process.env.RSDOCTOR) {
        chain.plugin('rsdoctor').use(RsdoctorRspackPlugin, [
          {
            // 插件选项
            disableClientServer: true,
            features: ['bundle', 'loader', 'plugins', 'resolver'],
          },
        ]);
      }
    },
  },
};
```

### tools.babel

**变更内容**：该配置已废弃，框架不再内置 Babel，请使用 [Rsbuild 的 Babel 插件](https://v0.rsbuild.rs/plugins/list/plugin-babel) 来启用支持。

**迁移示例**：

```typescript
// v2
tools: {
  babel: {
    plugins: [
      [
        'babel-plugin-import',
        {
          libraryName: 'xxx-components',
          libraryDirectory: 'es',
          style: true,
        },
      ],
    ],
  },
}

// v3
import { pluginBabel } from '@rsbuild/plugin-babel';

export default {
  // ...
  builderPlugins: [
    pluginBabel({
      babelLoaderOptions: {
        plugins: [
          [
            'babel-plugin-import',
            {
              libraryName: 'my-components',
              libraryDirectory: 'es',
              style: true,
            },
          ],
        ],
      },
    })
  ];
}
```

### tools.tailwindcss

**变更内容**：该配置已废弃，请参考 [Tailwind 插件变更](/zh/guides/upgrade/tailwindcss.md)，使用 Rsbuild 的方式来接入 Tailwind CSS。

### tools.tsLoader

**变更内容**：由于 Rspack 不支持 `tsLoader` 因此该配置已废弃，[Rspack experiments.typeReexportsPresence 配置](https://rspack.rs/zh/config/experiments#experimentstypereexportspresence)，可以用于改进对 Typescript 类型导出的识别。可以辅助 ts-loader 迁移。

```typescript
// 该配置已废弃
// tools: {
//   tsLoader: { /* 配置 */ }
// },
```

### tools.webpackChain

**变更内容**：该配置已废弃，请迁移到 `tools.bundlerChain`。

```typescript
// v2
tools: {
  webpackChain: (chain, { env }) => {
    if (env === 'development') {
      chain.devtool('cheap-module-eval-source-map');
    }
  };
}

// v3
tools: {
  bundlerChain: (chain, { env }) => {
    if (env === 'development') {
      chain.devtool('cheap-module-eval-source-map');
    }
  };
}
```

### tools.webpack

**变更内容**：该配置已废弃，请将 webpack 配置迁移到 `tools.rspack`。

```typescript
// v2
tools: {
  webpack: (chain, { env }) => {
    {
      /* 配置 */
    }
  };
}

// v3
tools: {
  rspack: (chain, { env }) => {
    {
      /* 配置 */
    }
  };
}
```

## source

### source.resolveMainFields

**变更内容**：该配置已废弃，使用 `resolve.mainFields` 代替。

**迁移示例**：

```typescript
// v2
source: {
  resolveMainFields: ['custom', 'module', 'main'];
}

// v3
resolve: {
  mainFields: ['custom', 'module', 'main'];
}
```

### source.resolveExtensionPrefix

**变更内容**：该配置已废弃，使用 `resolve.extensions` 代替。

**迁移示例**：

```typescript
// v2
source: {
  resolveExtensionPrefix: ['.ts', '.tsx', '.js'];
}

// v3
resolve: {
  extensions: ['.ts', '.tsx', '.js'];
}
```

### source.moduleScopes

**变更内容**：该配置已废弃，直接移除。

### source.enableCustomEntry

**变更内容**：该配置已废弃，直接移除。

### source.disableEntryDirs

**变更内容**：该配置已废弃，直接移除。

### source.alias

**变更内容**：该配置不再作用于自定义 Server 和 BFF 中的代码，为服务端代码配置的 alias 需要迁移到 tsconfig.json 中。

**迁移示例**：

```typescript
// v2
source: {
  alias: {
    '@api/*': './api/*',
  },
},

// v3 tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@api/*": ["./api/*"]
    },
  },
}
```

### server.routes

**变更内容**：默认路由由 `main` 变更为 `index`，如果 `server.routes` 配置中存在 `index` 则按如下迁移。

**迁移示例**：

```typescript
// v2
server: {
  routes: {
    main: '/new',
  },
},

// v3
server: {
  routes: {
    index: '/new',
  },
},
```

## output

### output.overrideBrowserslist

**变更内容**：需要根据项目现有配置情况处理。

**处理步骤**:

1. 检查项目中是否有 `.browserslistrc` 文件
2. 检查 `modern.config.[ts|js]` 中是否配置了 `output.overrideBrowserslist`
3. 检查 package.json 中是否配置了 browserslist

如果都没有，则创建 `.browserslistrc` 文件，内容为支持 ES6 的浏览器：

```yaml title=".browserslistrc"
chrome >= 87
edge >= 88
firefox >= 78
safari >= 14
```

### output.enableAssetFallback

**变更内容**：该配置已废弃，注释掉并添加说明。

```typescript
// 该配置已废弃，如有问题请咨询 oncall 解决
// output: {
//   enableAssetFallback: true,
// },
```

### output.cssModuleLocalIdentName

**变更内容**：该配置已废弃，使用 `output.cssModules.localIdentName` 代替。

**迁移示例**：

```typescript
// v2
export default {
  output: {
    cssModuleLocalIdentName: '[path][name]__[local]-[hash:base64:6]',
  },
};

// v3
export default {
  output: {
    cssModules: {
      localIdentName: '[path][name]__[local]-[hash:base64:6]',
    },
  },
};
```

### output.disableCssExtract

**变更内容**：该配置已废弃，使用 `output.injectStyles` 代替。

**迁移示例**：

```typescript
// v2
export default {
  output: {
    disableCssExtract: true,
  },
};

// v3
export default {
  output: {
    injectStyles: true,
  },
};
```

### output.disableFilenameHash

**变更内容**：该配置已废弃，使用 `output.filenameHash` 代替。

**迁移示例**：

```typescript
// v2
export default {
  output: {
    disableFilenameHash: true,
  },
};

// v3
export default {
  output: {
    filenameHash: false,
  },
};
```

### output.disableMinimize

**变更内容**：该配置已废弃，使用 `output.minify` 代替。

**迁移示例**：

```typescript
// v2
export default {
  output: {
    disableMinimize: true,
  },
};

// v3
export default {
  output: {
    minify: false,
  },
};
```

### output.disableSourceMap

**变更内容**：该配置已废弃，使用 `output.sourceMap` 代替。

**迁移示例**：

```typescript
// v2
export default {
  output: {
    disableSourceMap: true,
  },
};

// v3
export default {
  output: {
    sourceMap: false,
  },
};
```

### output.enableInlineScripts

**变更内容**：该配置已废弃，使用 `output.inlineScripts` 代替。

**迁移示例**：

```typescript
// v2
export default {
  output: {
    enableInlineScripts: true,
  },
};

// v3
export default {
  output: {
    inlineScripts: true,
  },
};
```

### output.enableInlineStyles

**变更内容**：该配置已废弃，使用 `output.inlineStyles` 代替。

**迁移示例**：

```typescript
// v2
export default {
  output: {
    enableInlineStyles: true,
  },
};

// v3
export default {
  output: {
    inlineStyles: true,
  },
};
```

### output.enableLatestDecorators

**变更内容**：该配置已废弃，使用 `source.decorators` 代替。

**迁移示例**：

```typescript
// v2
export default {
  output: {
    enableLatestDecorators: true,
  },
};

// v3
export default {
  source: {
    decorators: {
      version: '2022-03',
    },
  },
};
```

### output.disableNodePolyfill

**变更内容**：该配置已废弃，通过注册 `pluginNodePolyfill` 代替。

**迁移示例**：

```typescript
// v2
export default {
  output: {
    disableNodePolyfill: false,
  },
};

// v3
import { pluginNodePolyfill } from '@rsbuild/plugin-node-polyfill';
export default {
  builderPlugins: [pluginNodePolyfill()],
};
```


## plugins

### app-tools 插件

**变更内容**：该插件不需要传入任何参数。

**迁移示例**：

```typescript
// v2
plugins: [
  appTools({
    bundler: 'rspack'
  })
],

// v3
plugins: [
  appTools()
],
```

## security

### security.sri

**变更内容**：`security.sri.hashLoading` 不再需要，可以直接移除。

## runtime

### runtime.router

**变更内容**：不再需要，可以直接移除。该配置移动到 modern.runtime.ts 中的 router 配置中。

**迁移示例**：

```typescript
// v2
// modern.config.ts
export default {
  runtime: {
    router: {
      // 路由配置
    },
  },
};

// v3
// modern.runtime.ts
import { defineRuntimeConfig } from '@modern-js/runtime';

export default defineRuntimeConfig({
  router: {
    // 路由配置
  },
});
```

### runtime.state

**变更内容**：该配置被废弃，建议使用第三方状态管理库。

### runtime.masterApp

**变更内容**：该配置被废弃，将该配置移动到 modern.runtime.ts 中的 masterApp 配置。

**迁移示例**：

```typescript
// v2
// modern.config.ts
export default {
  runtime: {
    masterApp: {
      apps: [
        {
          name: 'Table',
          entry: 'http://localhost:8081',
        },
        {
          name: 'Dashboard',
          entry: 'http://localhost:8082',
        },
      ],
    },
  },
};

// v3
// modern.runtime.ts
import { defineRuntimeConfig } from '@modern-js/runtime';

export default defineRuntimeConfig({
  masterApp: {
    apps: [
      {
        name: 'Table',
        entry: 'http://localhost:8081',
      },
      {
        name: 'Dashboard',
        entry: 'http://localhost:8082',
      },
    ],
  },
});
```

## performance

### performance.bundleAnalyze

**变更内容**：该配置已废弃，建议使用 [Rsdoctor](https://v2.rsbuild.rs/zh/guide/debug/rsdoctor) 来分析产物体积

### performance.transformLodash

**变更内容**：不再需要，可以直接移除。

**迁移示例**：

```typescript
// v2
export default {
  performance: {
    transformLodash: true,
  },
};

// v3 - 直接移除该配置
export default {
  // 配置...
};
```

## experiments

### experiments.lazyCompilation

**变更内容**：该配置已废弃，改为 `dev.lazyCompilation`。

**迁移示例**：

```typescript
// v2
experiments: {
  lazyCompilation: true;
}

// v3
dev: {
  lazyCompilation: true;
}
```
