前言
随着现在市面上端的形态多种多样,Web、H5、微信小程序等,大家肯定都遇到业务要求同时在不同的端上线。
然而大多数产品,不同端页面 UI 展示差异性比较大,团队大多数会选择不同端拆分成不同的项目。但是也会有种情况,不同端页面 UI 差异比较小,那这种情况下编写一套代码能够适配到多端就能极大的提高开发效率。
背景
最近遇到一个项目,需要适配 PC,H5 和微信小程序,并且项目属于中后台管理系统,UI 差异性小,且 PC 端需要支持一些复杂的功能。
本人 React 框架比较熟练,在各个社区搜了一波,目前大多的前端框架虽然适配多端,但是由于框架本身为了保证不同端的统一性以及稳定性,都不太符合项目的诉求。具体有以下几个问题:
- UI 组件库对于中后台管理系统,组件功能少;
- 框架更加侧重 C 端适配,对于中后台需要复杂的权限管理不太支持;
技术选型
在框架上选择了 Taro,但是针对以上两个问题,决定再引入两个 UI 库
💡 建议使用antd5,全面使用css-in-js 减少了公共样式的引入,可以按需加载,减少了打包项目体积。
问题汇总
页面路由配置
诉求:不同端入口不同,页面或者组件不同端定制化
不同端入口不同
// 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: '个人中心',
},
],
},
};
}
页面或者组件不同端定制化
├── 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
{
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 响应式布局
Row justify='center' gutter={24}>
媒体查询
@media (min-width: 756px) {
// PC 端
}
💡 踩坑: 媒体查询在微信小程序上不生效,所以默认 UI 以 H 5为标准,再对 PC 端进行特殊处理
打包体积优化
诉求:两个 UI 库,避免包体积过大,按需加载
webpack-bundle-analyzer
h5: {
webpackChain(chain, webpack) {
chain
.plugin('analyzer')
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, []);
}
}
通过分析图得知,@nutui/icons-react-taro
被多次引入,即使页面中没有使用到 icon。
因此可以通过配置 webpack,进行拆包
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,
},
},
},
},
});
}
从图片可以看到,每个页面的体积都得到了有效的减少,项目体积也大大的减小
最后的最后,附上 项目地址
文章来源于互联网:一框架三端:基于Taro 探索PC、H5与小程序前端开发解决方案