React+Vite+Material UI中ResponsiveAppBar报Unexpected token错误求助
React+Vite+Material UI中ResponsiveAppBar示例报错解决
- 技术栈:React + Vite + Material UI
- 问题:运行Material UI官网的ResponsiveAppBar示例时出现语法错误,同站点的ButtonAppBar示例可正常运行(后者未使用TypeScript类型注解)
我的ResponsiveAppBar代码(与官网示例一致)
import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import Menu from '@mui/material/Menu'; import MenuIcon from '@mui/icons-material/Menu'; import Container from '@mui/material/Container'; import Avatar from '@mui/material/Avatar'; import Button from '@mui/material/Button'; import Tooltip from '@mui/material/Tooltip'; import MenuItem from '@mui/material/MenuItem'; import AdbIcon from '@mui/icons-material/Adb'; const pages = ['Products', 'Pricing', 'Blog']; const settings = ['Profile', 'Account', 'Dashboard', 'Logout']; function ResponsiveAppBar() { const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null); const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null); const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorElNav(event.currentTarget); }; const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorElUser(event.currentTarget); }; const handleCloseNavMenu = () => { setAnchorElNav(null); }; const handleCloseUserMenu = () => { setAnchorElUser(null); }; return ( <AppBar position="static"> <Container maxWidth="xl"> <Toolbar disableGutters> <AdbIcon sx={{ display: { xs: 'none', md: 'flex' }, mr: 1 }} /> <Typography variant="h6" noWrap component="a" href="/" sx={{ mr: 2, display: { xs: 'none', md: 'flex' }, fontFamily: 'monospace', fontWeight: 700, letterSpacing: '.3rem', color: 'inherit', textDecoration: 'none', }} > LOGO </Typography> <Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}> <IconButton size="large" aria-label="account of current user" aria-controls="menu-appbar" aria-haspopup="true" onClick={handleOpenNavMenu} color="inherit" > <MenuIcon /> </IconButton> <Menu id="menu-appbar" anchorEl={anchorElNav} anchorOrigin={{ vertical: 'bottom', horizontal: 'left', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'left', }} open={Boolean(anchorElNav)} onClose={handleCloseNavMenu} sx={{ display: { xs: 'block', md: 'none' }, }} > {pages.map((page) => ( <MenuItem key={page} onClick={handleCloseNavMenu}> <Typography textAlign="center">{page}</Typography> </MenuItem> ))} </Menu> </Box> <AdbIcon sx={{ display: { xs: 'flex', md: 'none' }, mr: 1 }} /> <Typography variant="h5" noWrap component="a" href="" sx={{ mr: 2, display: { xs: 'flex', md: 'none' }, flexGrow: 1, fontFamily: 'monospace', fontWeight: 700, letterSpacing: '.3rem', color: 'inherit', textDecoration: 'none', }} > LOGO </Typography> <Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}> {pages.map((page) => ( <Button key={page} onClick={handleCloseNavMenu} sx={{ my: 2, color: 'white', display: 'block' }} > {page} </Button> ))} </Box> <Box sx={{ flexGrow: 0 }}> <Tooltip title="Open settings"> <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}> <Avatar alt="Remy Sharp" src="/static/images/avatar/2.jpg" /> </IconButton> </Tooltip> <Menu sx={{ mt: '45px' }} id="menu-appbar" anchorEl={anchorElUser} anchorOrigin={{ vertical: 'top', horizontal: 'right', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'right', }} open={Boolean(anchorElUser)} onClose={handleCloseUserMenu} > {settings.map((setting) => ( <MenuItem key={setting} onClick={handleCloseUserMenu}> <Typography textAlign="center">{setting}</Typography> </MenuItem> ))} </Menu> </Box> </Toolbar> </Container> </AppBar> ); } export default ResponsiveAppBar;
执行npm run dev时的报错信息
[plugin:vite:react-babel] /var/www/html/lnavarroa.cl/public_html/vite-app-lnavarroa/src/components/ResponsiveAppBar.jsx: Unexpected token (23:65) 26 | const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => { /var/www/html/lnavarroa.cl/public_html/vite-app-lnavarroa/src/components/ResponsiveAppBar.jsx:23:65 21 | const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null); 22 | 23 | const handleOpenNavMenu = (event, React.MouseEvent<HTMLElement>) => { | ^ 24 | setAnchorElNav(event.currentTarget); 25 | };
问题原因
- 代码中使用了TypeScript类型注解(比如
React.useState<null | HTMLElement>、event: React.MouseEvent<HTMLElement>),但文件后缀是.jsx,Vite默认的JavaScript环境不支持TS语法,导致babel编译报错。 - 报错信息显示第23行存在语法误写(逗号代替了冒号),这是复制代码时的格式问题,但核心矛盾还是TS语法在JS文件中的兼容性问题。
解决方案
方案1:切换到TypeScript环境
- 将文件后缀从
.jsx改为.tsx - 若项目未配置TypeScript,执行以下命令安装依赖:
npm install typescript @types/react @types/react-dom --save-dev - Vite会自动生成
tsconfig.json基础配置,无需额外手动修改(需自定义规则可调整该文件)
方案2:移除所有TypeScript类型注解
修改代码中的类型相关语法,转为纯JavaScript:
// 原代码: const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null); const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { ... } // 修改后: const [anchorElNav, setAnchorElNav] = React.useState(null); const handleOpenNavMenu = (event) => { ... }
对所有带类型注解的代码块做同样修改即可。
为什么ButtonAppBar能正常运行?
ButtonAppBar示例代码是纯JavaScript语法,未使用TypeScript类型注解,符合Vite默认JS环境的编译规则,因此不会报错。
内容的提问来源于stack exchange,提问作者luis
相关产品推荐
相关产品推荐

