vite 使用 React 组件构建 lib iife

问题描述 投票:0回答:1

我正在尝试创建一个 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”)”。

reactjs material-ui vite rollup iife
1个回答
0
投票

这可能不是答案,但请尝试将您不想捆绑到库中的任何依赖项外部化,例如

react
react-dom

build: {
    ...,
    rollupOptions: {
        external: ['react', 'react-dom']
    },
}

此外,在您的

package.json
中,确保 React 和 ReactDOM 被列为对等依赖项。

© www.soinside.com 2019 - 2024. All rights reserved.