React发布包本地正常,引入其他React项目时出现运行时错误
React组件npm包引入外部应用报错问题
我用React开发了一个包含多组件的npm包,通过Webpack构建。本地执行npm start运行正常,但引入另一个React应用使用时出现运行时错误。
运行时错误截图
本地运行正常(npm start)

我已经尝试过这些方案:
- 在package.json中配置了两个主文件入口:
src/index.ts和build/dist/index.js,前者因Webpack打包问题无法生效,只能用后者 - 检查过Webpack配置
相关代码
Home.tsx
import { Navigationbar } from './Navigationbar'; import { RoutesView } from './Routes'; /** * 负责渲染首页 */ export const Home: React.FC = () => { return ( <div className="ckb-container"> <Navigationbar /> <RoutesView /> </div> ) };
index.ts
import { MarkdownContainer } from "./Components/MarkdownContainer"; import { Home } from "./Components/Home"; export { MarkdownContainer, Home };
package.json (v1)
{ "name": "sample", "version": "1.0.0", "main": "./src/index.ts", "publishConfig": { "registry": "https://npm.pkg.github.com/" }, "files": [ "build/dist" ] }
package.json (v2)
{ "name": "sample", "version": "1.0.0", "main": "./build/dist/index.js", "publishConfig": { "registry": "https://npm.pkg.github.com/" }, "files": [ "build/dist" ] }
Webpack配置
const path = require('path'); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { mode: "development", devtool: "source-map", entry: { index: path.join(path.join(path.resolve(process.cwd()), "/src/index.ts")), }, output: { filename: "[name].js", path: path.join(path.resolve(process.cwd()), "build/dist"), library: "sample", libraryTarget: 'umd', // 尝试过添加publicPath }, devServer: { historyApiFallback: true }, resolve: { extensions: ['.ts', '.tsx', '.js'], }, plugins: [ new HtmlWebpackPlugin({ template: "./public/index.html", filename: './index.html', favicon: './public/icon.png' }), ], module: { rules: [{ test: /\.(css|sass|scss)$/, use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'sass-loader' } ], }, { test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/, }, { test: /\.(png|svg|ico|jpg|jpeg|gif|bmp|md)$/, use: "file-loader" }, ], } }
消费端应用代码
import { Home } from "sample"; function App() { return ( <div className="App"> <header className="App-header"> <Home /> </header> </div> ); } export default App;
问题分析与解决方案
移除不必要的Webpack插件
当前配置中的HtmlWebpackPlugin用于生成调试用的HTML页面,组件库打包不需要这个插件,会导致输出冗余文件,直接删除该插件配置即可。处理React依赖冲突
组件库中React、ReactDOM不应被打包进产物,避免消费端出现多React实例冲突:- 在package.json中添加peerDependencies:
"peerDependencies": { "react": "^18.0.0", "react-dom": "^18.0.0" } - 在Webpack配置中添加externals排除依赖:
externals: { react: 'react', 'react-dom': 'react-dom' }
- 在package.json中添加peerDependencies:
优化UMD输出配置
为避免环境兼容问题,补充globalObject配置:output: { filename: "[name].js", path: path.join(path.resolve(process.cwd()), "build/dist"), library: "sample", libraryTarget: 'umd', globalObject: 'this' }样式打包优化
style-loader会将样式注入DOM,易引发样式污染,改用mini-css-extract-plugin单独打包CSS:const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 插件配置 plugins: [ new MiniCssExtractPlugin({ filename: '[name].css' }) ], // 样式loader替换 module: { rules: [ { test: /\.(css|sass|scss)$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader' ] } ] }完善package.json入口配置
同时配置多规范入口和类型声明,提升兼容性:"main": "./build/dist/index.js", "module": "./build/dist/index.esm.js", // 可选:打包ES模块版本 "types": "./build/dist/index.d.ts" // 需在tsconfig中开启declaration生成类型文件TypeScript配置补充
在tsconfig.json中开启类型声明生成:{ "compilerOptions": { "declaration": true, "declarationDir": "./build/dist" } }
内容的提问来源于stack exchange,提问作者Gopi
相关产品推荐
相关产品推荐


