能否将Material-UI Switch组件编译为可在普通ES5项目中使用的格式?
核心结论
- 可以将Material-UI Switch组件编译为兼容普通ES5项目的格式,不需要依赖完整的React项目脚手架即可调用
- 复杂度等级:3/10(仅需完成基础的组件打包、依赖导出配置,你有CRA使用经验的前提下基本不会遇到障碍)
具体实现步骤
步骤1:初始化临时打包项目
- 用你熟悉的CRA创建临时项目:
npx create-react-app mui-switch-build - 进入项目目录安装依赖:
npm install @mui/material @emotion/react @emotion/styled @mui/icons-material
步骤2:封装Switch组件并暴露全局调用方法
在src目录下新建MuiSwitchWrapper.js文件,写入以下代码:
import React from 'react'; import ReactDOM from 'react-dom/client'; import Switch from '@mui/material/Switch'; // 暴露到全局window对象,供ES5项目直接调用 window.renderMuiSwitch = function (mountDom, props = {}, onChangeCallback) { const root = ReactDOM.createRoot(mountDom); root.render( <Switch {...props} onChange={(e) => { if (typeof onChangeCallback === 'function') { onChangeCallback(e.target.checked); } }} /> ); // 返回卸载方法,避免页面内存泄漏 return { destroy: () => root.unmount() } };
修改src目录下的index.js,直接引入封装文件即可:import './MuiSwitchWrapper'
步骤3:修改打包配置输出ES5兼容格式
- 安装打包工具依赖:
npm install --save-dev react-app-rewired customize-cra autoprefixer - 项目根目录新建
config-overrides.js,写入以下配置:
const { override, adjustStyleLoaders } = require('customize-cra'); module.exports = override( // 配置输出UMD通用格式,兼容ES5环境调用 (config) => { config.output.library = 'MuiSwitch'; config.output.libraryTarget = 'umd'; config.output.globalObject = 'this'; // 如果你不想在ES5项目中单独引入React、ReactDOM,直接删除下面的externals配置即可 config.externals = { react: 'React', 'react-dom': 'ReactDOM' }; return config; }, // 适配样式兼容低版本浏览器 adjustStyleLoaders(({ use: [, , postcss] }) => { const postcssOptions = postcss.options; postcssOptions.postcssOptions = { plugins: [require('autoprefixer')] }; }) );
- 修改package.json中的scripts配置,把
"build": "react-scripts build"替换为"build": "react-app-rewired build"
步骤4:执行打包获取产物
- 运行打包命令:
npm run build - 打包完成后,从
build/static/js目录拿到主js产物(前缀为main的js文件),从build/static/css目录拿到对应css产物
步骤5:在普通ES5项目中引入使用
把打包得到的js、css文件放到你的ES5项目静态资源目录,页面中按以下方式调用即可:
<!-- 如果你没有把React打包进产物,需要先引入ES5兼容版的React和ReactDOM文件 --> <!-- <script src="你的静态资源路径/react.production.min.js"></script> <script src="你的静态资源路径/react-dom.production.min.js"></script> --> <link rel="stylesheet" href="你的静态资源路径/mui-switch.css"> <script src="你的静态资源路径/mui-switch.js"></script> <!-- 渲染Switch的容器 --> <div id="my-switch"></div> <script> // 调用全局方法渲染Switch const switchInstance = window.renderMuiSwitch( document.getElementById('my-switch'), // 组件配置参数,支持所有MUI Switch原生属性 { defaultChecked: true, disabled: false, color: 'primary' }, // 状态变更回调 function(checked) { console.log('开关当前状态:', checked) } ); // 需要卸载组件时调用 // switchInstance.destroy() </script>
注意事项
- 打包时如果把React、ReactDOM一起打包进产物,单个js文件体积会增加约40KB(gzip压缩后),优点是不需要在ES5项目中额外引入React相关依赖
- 所有MUI Switch原生支持的属性、样式配置都可以在封装时直接传入,编译后依然生效
内容的提问来源于stack exchange,提问作者Jorgs
相关产品推荐
相关产品推荐

