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

如何在开发阶段为私有React组件库启用HMR热模块替换?

高效开发React组件库:实时同步变更到Next.js应用

问题背景

我正在开发一款基于Rollup构建、以私有npm包形式发布的React组件库,被多个应用使用。当前遇到的核心痛点:

  • 修改组件库后必须完整重建包+手动重装到各应用才能测试,耗时极长
  • 试过npm link但未解决问题
  • Rollup的--watch模式会从头重建整个包,效率低下
  • 组件库的主样式表被Next.js应用根布局导入,样式变更也需要实时同步

当前Rollup配置:

[
    {
        input: 'src/index.ts',
        treeshake: true,
        external: [...Object.keys(packageJson.peerDependencies || {})],
        output: [
            {
                file: packageJson.main,
                format: 'cjs',
                sourcemap: false,
            },
            {
                file: packageJson.module,
                format: 'esm',
                sourcemap: false,
            },
        ],
        plugins: [
            del({ targets: 'dist/*' }),
            peerDepsExternal(),
            resolve(),
            commonjs(),
            typescript({
                tsconfig: './tsconfig.json',
                exclude: [
                    // Exclude test files
                    /\.test.((js|jsx|ts|tsx))$/,
                    // Exclude story files
                    /\.stories.((js|jsx|ts|tsx|mdx))$/,
                    // Exclude story folder
                    '**/stories/**',
                ],
            }),
            postcss({
                include: ['./**/*.css'],
            }),
            copy({
                targets: [{ src: 'src/styles/_*.sass', dest: 'dist/sass' }],
            }),
            sass({ output: true, output: 'dist/styles.css', options: { outputStyle: 'compressed' } }),
            preserveDirectives(),
            terser({ compress: { directives: false } }),
        ],
    },
    {
        input: 'dist/esm/types/index.d.ts',
        output: [{ file: 'dist/index.d.ts', format: 'esm' }],
        plugins: [dts()],
        external: [/\.(css|less|scss|sass)$/],
    },
]

解决方案

1. 优化Rollup构建效率,实现增量编译

  • 移除全量清理的del插件逻辑:当前del({ targets: 'dist/*' })会每次清空整个dist目录,导致无法增量构建。改成只清理编译产物的核心文件,或者直接去掉这个插件(Rollup会自动覆盖旧文件)。
  • 启用sourcemap:将output中的sourcemap设为true或'inline',帮助Rollup追踪变更文件,实现增量编译。
  • 缩小watch监听范围:在Rollup配置中添加watch选项,排除无需监听的文件:
    watch: {
      exclude: ['node_modules/**', '**/*.test.*', '**/*.stories.*', '**/stories/**']
    }
    
  • 开发环境禁用生产插件:去掉开发时的terser压缩步骤,用环境变量区分配置:
    const isProduction = process.env.NODE_ENV === 'production';
    plugins: [
      // ...其他插件
      isProduction && terser({ compress: { directives: false } }),
    ].filter(Boolean)
    

2. 修复npm link的Next.js兼容问题

npm link失效通常是因为Next.js的模块解析导致双React实例,按以下步骤修复:

  1. 在组件库目录执行:npm link
  2. 在Next.js应用目录执行:npm link your-component-library-name
  3. 修改Next.js的next.config.js,添加别名强制使用应用内的React:
const path = require('path');
const nextConfig = {
  webpack: (config) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      react: path.resolve('./node_modules/react'),
      'react-dom': path.resolve('./node_modules/react-dom'),
    };
    return config;
  },
};

3. 实现样式实时同步

针对Next.js根布局导入的样式表,调整Rollup配置实现增量更新:

  • 开发时不压缩样式,保留源映射:
    sass({ 
      output: true, 
      output: 'dist/styles.css', 
      options: { 
        outputStyle: isProduction ? 'compressed' : 'expanded' 
      } 
    }),
    
  • Rollup watch模式下,样式变更会自动更新dist/styles.css,Next.js开发服务器会自动重新加载样式(默认热更新支持)。如果未生效,可以检查Next.js是否启用了fastRefresh(默认开启)。

4. 启用组件HMR(进阶)

在组件库中添加HMR支持,配合Next.js实现组件实时更新:

  • 在组件库的入口文件或单个组件中添加HMR代码(仅开发环境):
    if (process.env.NODE_ENV === 'development' && module.hot) {
      module.hot.accept();
    }
    
  • 安装rollup-plugin-hot并添加到开发配置:
    import hot from 'rollup-plugin-hot';
    plugins: [
      // ...其他插件
      process.env.NODE_ENV === 'development' && hot({
        client: true,
      }),
    ].filter(Boolean)
    

验证流程

  1. 在组件库目录配置开发构建脚本:"build:watch": "rollup -c -w --environment NODE_ENV:development",然后执行npm run build:watch
  2. 在Next.js应用目录执行npm run dev
  3. 修改组件库的组件或样式,查看Next.js应用是否实时同步变更

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 02:10:04