前言
随着现在市面上端的形态多种多样,Web、H5、微信小程序等,大家肯定都遇到业务要求同时在不同的端上线。
然而大多数产品,不同端页面 UI 展示差异性比较大,团队大多数会选择不同端拆分成不同的项目 。但是也会有种情况,不同端页面 UI 差异比较小,那这种情况下编写一套代码 能够适配到多端就能极大的提高开发效率。
背景
最近遇到一个项目,需要适配 PC,H5 和微信小程序 ,并且项目属于中后台管理系统,UI 差异性小,且 PC 端需要支持一些复杂的功能。
本人 React 框架比较熟练,仔各个社区搜了一波,目前大多的前端框架虽然适配多端,但是由于框架本身为了保证不同端的统一性以及稳定性,都不太符合项目的诉求。具体有以下几个问题:
- UI 组件库对于中后台管理系统,组件功能少;
- 框架更加侧重 C 端适配,对于中后台需要复杂的权限管理不太支持;
技术选型
在框架上选择了 Taro,但是针对以上两个问题,决定再引入两个 UI 库
💡 建议使用antd5,全面使用css-in-js 减少了公共样式的引入,可以按需加载,减少了打包项目体积。
问题汇总
页面路由配置
诉求:不同端入口不同,页面或者组件不同端定制化
不同端入口不同
tsx
// app.config.ts
// PC端 移动端
if (process.env.TARO_ENV === 'h5') {
CustomConfig = {
// 入口文件
entryPagePath: 'pages/main/home/index',
pages: [
'pages/main/home/index',
'pages/main/login/index',
'pages/main/signIn/index',
],
};
} else {
// 小程序
CustomConfig = {
// 入口文件
entryPagePath: 'pages/index/index',
pages: ['pages/index/index', 'pages/notice/index', 'pages/account/index'],
// 小程序拆包
subPackages: [
{
root: 'pages/main',
pages: ['login/index', 'signIn/index'],
},
],
tabBar: {
color: '#000000',
selectedColor: '#0B4F4A',
backgroundColor: '#ffffff',
list: [
{
pagePath: 'pages/listing/index',
text: '首页',
},
{
pagePath: 'pages/dataCenter/index',
text: '消息中心',
},
{
pagePath: 'pages/account/index',
text: '个人中心',
},
],
},
};
}
页面或者组件不同端定制化
markdown
├── src # 代码源文件,可以使用别名 `@` 引用该目录下的文件,如:
│ ├── components # 可复用组件
│ │ ├── Header # 页面组件 Header
│ │ │ └── index.tsx # 小程序组件
│ │ │ └── index.h5.tsx # H5 和 PC 端组件
│ │ └── Side
│ │ └── index.tsx
│ │ └── index.h5.tsx
│ ├── pages
│ │ ├── Login # 登陆页
│ │ │ └── index.tsx # 小程序
│ │ └── index.h5.tsx # H5 和 PC 端组件
PC 端 H5 小程序 样式适配
诉求:不同端统一的尺寸换算方式
统一 Root Size
jsx
{
mini: {
postcss: {
pxtransform: {
enable: true,
config: {
selectorBlackList: ['nut-'],
baseFontSize: 14,
maxRootSize: 14,
},
},
},
},
h5: {
postcss: {
pxtransform: {
enable: true,
config: {
selectorBlackList: ['nut-'],
baseFontSize: 14,
maxRootSize: 14,
},
}
}
}
}
PC 端 H5 响应式布局
tsx
<Row justify='center' gutter={24}>
<Col xs={24} md={10} lg={10} xl={10}>
<Row>
媒体查询
scss
@media (min-width: 756px) {
// PC 端
}
💡 踩坑: 媒体查询在微信小程序上不生效,所以默认 UI 以 H 5为标准,再对 PC 端进行特殊处理
打包体积优化
诉求:两个 UI 库,避免包体积过大,按需加载
webpack-bundle-analyzer
jsx
h5: {
webpackChain(chain, webpack) {
chain
.plugin('analyzer')
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, []);
}
}
通过分析图得知,@nutui/icons-react-taro
被多次引入,即使页面中没有使用到 icon。
因此可以通过配置 webpack,进行拆包
jsx
webpackChain(chain, webpack) {
chain
.plugin('analyzer')
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, []);
chain.merge({
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 3, // 最少被引入 3 次
automaticNameDelimiter: '.',
cacheGroups: {
vendor: {
test: /[\/]node_modules[\/]/, // 分析 node_modules
name: 'vendors',
minSize: 30000,
minChunks: 1,
chunks: 'initial',
priority: 1,
},
},
},
},
});
}
从图片可以看到,每个页面的体积都得到了有效的减少,项目体积也大大的减小
最后的最后,附上 项目地址