我正在尝试创建一个 React 组件库。我们的目标是这样称呼他们:
<div id="testreact"></div>
<div id="testreact2"></div>
<script>
MyLib.ReactDOM.createRoot(document.getElementById('testreact')).render(
MyLib.ButtonShowdown(),
)
MyLib.ReactDOM.createRoot(document.getElementById('testreact2')).render(
MyLib.DrawerShowdown(),
)
</script>
ButtonShowdown 工作正常。
DrawerShowdown 使用 React.useState,但我在控制台中收到错误“无法读取 null 的属性(读取‘useState’)”。
使用以下配置在 Vite 中完成构建:`
import { defineConfig } from 'vite'
import { resolve } from 'path';
import react from '@vitejs/plugin-react-swc'
export default defineConfig({
define: {
'process.env': process.env
},
plugins: [react()],
build: {
lib: {
entry: resolve(__dirname, 'lib/main.js'),
name: 'MyLib',
fileName: 'my-lib',
formats: ['iife']
}
},
})
lib/main.js
import ReactDOM from 'react-dom/client'
import ButtonShowdown from "../src/ButtonShowdown";
import DrawerShowdown from "../src/DrawerShowdown"
export {
ReactDOM,
ButtonShowdown,
DrawerShowdown,
};
似乎许多人已经通过从库中排除 React 和 ReactDOM 来解决这个问题,但这样做也会导致 ButtonShowdown 停止工作。
虽然我认为这可能是多余的,但我将提供组件的代码:
import React from 'react'
import { Button } from "@mui/material";
import Base from "./Base";
function ButtonShowdown(){
return (
<Base>
<div>Showdown:</div>
<Button variant="text">Text</Button>
<Button variant="contained">Contained</Button>
<Button variant="outlined">Outlined</Button>
</Base>
)
}
export default ButtonShowdown;
import React from 'react';
import Box from '@mui/material/Box';
import Drawer from '@mui/material/Drawer';
import Button from '@mui/material/Button';
import List from '@mui/material/List';
import Divider from '@mui/material/Divider';
import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import InboxIcon from '@mui/icons-material/MoveToInbox';
import MailIcon from '@mui/icons-material/Mail';
import Base from './Base';
function DrawerShowdown() {
const [open, setOpen] = React.useState(false);
const toggleDrawer = (newOpen) => () => {
setOpen(newOpen);
};
const DrawerList = (
<Box sx={{ width: 250 }} role="presentation" onClick={toggleDrawer(false)}>
<List>
{['Inbox', 'Starred', 'Send email', 'Drafts'].map((text, index) => (
<ListItem key={text} disablePadding>
<ListItemButton>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItemButton>
</ListItem>
))}
</List>
<Divider />
<List>
{['All mail', 'Trash', 'Spam'].map((text, index) => (
<ListItem key={text} disablePadding>
<ListItemButton>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItemButton>
</ListItem>
))}
</List>
</Box>
);
return (
<Base>
<Button onClick={toggleDrawer(true)}>Open drawer</Button>
<Drawer open={open} onClose={toggleDrawer(false)}>
{DrawerList}
</Drawer>
</Base>
);
}
export default DrawerShowdown;
import React from 'react'
import { ScopedCssBaseline, ThemeProvider, createTheme } from "@mui/material";
import { red } from '@mui/material/colors';
function Base({children}){
const baseTheme = createTheme(window.WpeaUI?.customTheme ?? {
/*palette: {
primary: red
}*/
});
return (
<React.StrictMode>
<ScopedCssBaseline>
<ThemeProvider theme={baseTheme}>
{children}
</ThemeProvider>
</ScopedCssBaseline>
</React.StrictMode>
)
}
export default Base;
只要我执行 npm run dev ,一切就正常了。但是,当我尝试捆绑包时,对于 DrawerShowdown,我收到错误:“无法读取 null 的属性(读取“useState”)”。
这可能不是答案,但请尝试将您不想捆绑到库中的任何依赖项外部化,例如
react
和 react-dom
。
build: {
...,
rollupOptions: {
external: ['react', 'react-dom']
},
}
此外,在您的
package.json
中,确保 React 和 ReactDOM 被列为对等依赖项。