You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为RSC与Next.js App Router打包组件库的方案咨询

解决方案

Vite 环境下的最优方案

方案1:修复 rollup-plugin-preserve-directives 在 Vite 中的配置

Vite 默认会封装 Rollup 插件的执行逻辑,得确保插件在正确阶段生效:

  1. 安装最新版 rollup-plugin-preserve-directives
  2. 在 vite.config.ts 里显式配置插件,同时开启 build.preserveModules:
import { defineConfig } from 'vite';
import preserveDirectives from 'rollup-plugin-preserve-directives';
import react from '@vitejs/plugin-react';

export default defineConfig({
  build: {
    preserveModules: true,
    lib: {
      entry: 'src/index.ts',
      formats: ['es'],
      fileName: 'index',
    },
  },
  plugins: [
    react(),
    {
      ...preserveDirectives(),
      enforce: 'post', // 让插件在最后处理代码,避免指令被其他插件清掉
    },
  ],
});

这样配置后,Vite 会保留单个文件中的 "use client" 指令,不会全局添加,同时维持组件库的模块化输出。

方案2:修复源码分发时的 TypeScript 路径冲突

如果想继续用源码分发 + transpilePackages 的方案,可以通过统一路径映射解决冲突:

  1. 在组件库的 tsconfig.json 里,把绝对路径配置为基于包根的别名:
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
  1. 在使用组件库的 Next.js 项目的 next.config.js 中,添加对应的别名映射,同时保留 transpilePackages:
const path = require('path');

const nextConfig = {
  transpilePackages: ['ui-library'],
  webpack: (config) => {
    config.resolve.alias['@'] = path.resolve(__dirname, 'node_modules/ui-library/src');
    return config;
  },
};

module.exports = nextConfig;

这样 Next.js 就能正确解析组件库的绝对路径,不会和项目自身的路径配置冲突。

其他打包工具替代方案

Rollup 直接打包

既然你已经验证纯 Rollup 环境下 rollup-plugin-preserve-directives + preserveModules: true 能正常保留指令,直接用 Rollup 作为组件库的打包工具是最稳妥的选择:

  • 创建 rollup.config.js:
import preserveDirectives from 'rollup-plugin-preserve-directives';
import typescript from '@rollup/plugin-typescript';

export default {
  input: 'src/index.ts',
  output: {
    dir: 'dist',
    format: 'es',
    preserveModules: true,
  },
  plugins: [
    typescript(),
    preserveDirectives(),
  ],
};
  • 在 package.json 里配置打包脚本:"build": "rollup -c"

Parcel 2

Parcel 2 对 React Server Components 的 "use client" 指令有原生支持,不需要额外插件:

  • 在组件库的 package.json 里配置入口:
{
  "source": "src/index.ts",
  "main": "dist/index.js",
  "module": "dist/index.esm.js",
  "scripts": {
    "build": "parcel build"
  }
}

Parcel 会自动保留单个文件中的指令,同时处理 TypeScript 转译和模块化输出,配置成本极低。

Webpack 方案

Webpack 5 也能实现,但配置复杂度更高,不是首选:

  • 使用 babel-plugin-transform-react-server-components 确保 Babel 不会移除 "use client" 注释;
  • 在配置中开启 output.preserveModules: true,配合 babel-loader 处理 TypeScript/JSX 文件。

内容的提问来源于stack exchange,提问作者eliasondrej

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:50:35