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

如何复用已打包进Webpack React库的React,避免消费者重复下载

实现独立React Webpack库内置React并供消费者直接使用的方案

要让消费者应用直接使用你库中打包的React/ReactDOM,无需单独引入,需按以下步骤调整配置和代码:


一、调整库的Webpack配置与入口导出

1. 修改入口文件(src/Components.tsx)

在组件入口文件中,额外导出React和ReactDOM,确保Webpack将它们打包进最终bundle:

import React from 'react';
import ReactDOM from 'react-dom/client';
import TestComponent from './TestComponent';
import AnotherTestComponent from './AnotherTestComponent';

// 同时导出React、ReactDOM和组件
export {
  React,
  ReactDOM,
  TestComponent,
  AnotherTestComponent
};

2. 更新webpack.config.js

添加expose-loader将库内的React/ReactDOM暴露为全局变量,同时确保UMD模块兼容不同环境:

const path = require('path');

module.exports = {
    mode: 'production',
    entry: './src/Components',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'webpack.bundle.js',
        library: {
            name: 'webpackLib',
            type: 'umd',
            // 确保UMD在浏览器/Node.js环境下都能正常运行
            globalObject: 'this'
        }
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                use: 'ts-loader',
            },
            // 将库内的React暴露为全局window.React
            {
                test: require.resolve('react'),
                loader: 'expose-loader',
                options: { exposes: { globalName: 'React', override: true } }
            },
            // 将库内的ReactDOM暴露为全局window.ReactDOM
            {
                test: require.resolve('react-dom/client'),
                loader: 'expose-loader',
                options: { exposes: { globalName: 'ReactDOM', override: true } }
            }
        ],
    },
    // 不要设置externals,确保React/ReactDOM被打包进bundle
};

注意:需先安装依赖包:

npm install expose-loader --save-dev

二、修改消费者应用代码

1. 更新index.html

移除CDN引入的React/ReactDOM,只加载你的库bundle:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML 5 Boilerplate</title>
    <!-- 仅引入你的库,不再单独引入React -->
    <script src="../lib/dist/webpack.bundle.js"></script>
  </head>
  <body>
    <div id="container"></div>
    <div id="another-container"></div>
    <script src="index.js"></script>
  </body>
</html>

2. 消费者index.js无需修改

原代码直接使用全局的React/ReactDOM变量即可,这两个变量已由你的库暴露:

function injectComponentFromLib(containerName, componentName) {
    const root = ReactDOM.createRoot(document.getElementById(containerName));
    var component = webpackLib[componentName];
    var element = React.createElement(component);
    root.render(element);
}

injectComponentFromLib('container', 'TestComponent');
injectComponentFromLib('another-container', 'AnotherTestComponent');

关键说明

  • 库的package.json中,需将react和react-dom放在dependencies而非devDependencies,确保安装库时能获取到依赖(但消费者无需单独安装,因为已打包进bundle)。
  • 打包后的bundle体积会增大,因为包含了React/ReactDOM代码,这是内置依赖的必然结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:34:55