背景:公司打造小程序矩阵化,以uni-app作为技术栈生成不同平台的小程序代码。小程序项目包含5个平台的代码,虽然是一份代码运行5个平台,但是各个平台又有差异,在代码里面需要做很多条件编译进行兼容处理。随着项目的壮大与页面的增多,控制路由的pages.json已经异常庞大且代码可读性差(想找一个页面需要找到上下文切换,浪费时间并且可能误删不同平台的页面),亟需优化。
"globalStyle": { // #ifndef MP-TOUTIAO "navigationStyle": "custom", // #endif // #ifdef MP-TOUTIAO "navigationStyle": "default", // #endif // #ifdef MP-WEIXIN "backgroundColor": "#F3F5F8", // #endif // #ifdef MP-TOUTIAO || MP-BAIDU "backgroundColor": "#fff", // #endif "enablePullDownRefresh": false, "navigationBarTextStyle": "black", // #ifndef MP-ALIPAY "navigationBarTitleText": "XXXX", // #endif // #ifdef MP-ALIPAY "navigationBarTitleText": "XXXXXX", // #endif "navigationBarBackgroundColor": "#fff", // #ifdef MP-WEIXIN // 华为P40Pro 设备 key "qbDebugKey": ["59fc8a158775abbe1fd9809abc887b31"], // #endif "backgroundTextStyle": "light" },
将pages.json拆分,共同配置放到pages.json,差异配置新建不同平台文件维护,构建时再进行合并。
// pages.js关键代码 const pagesJsonJsFileName = 'pages.js' function processPagesJson (pagesJson, loader = { addDependency: function () {} }) { const pagesJsonJsPath = path.resolve(process.env.UNI_INPUT_DIR, pagesJsonJsFileName) if (fs.existsSync(pagesJsonJsPath)) { delete require.cache[pagesJsonJsPath] const pagesJsonJsFn = require(pagesJsonJsPath) if (typeof pagesJsonJsFn === 'function') { pagesJson = pagesJsonJsFn(pagesJson, loader) if (!pagesJson) { console.error(`${pagesJsonJsFileName} ${uniI18n.__('cliShared.requireReturnJsonObject')}`) } } else { console.error(`${pagesJsonJsFileName} ${uniI18n.__('cliShared.requireExportFunction')}`) } } return pagesJson }
module.exports = { pages: [ { path: 'pages/index/index', style: { enablePullDownRefresh: false, } }, // ... ], subPackages: [ { root: 'servicePackage', pages: [ { path: 'xxx/xxxx/xxxx' } ] } // ... ] }
新建src/pages.js,根据process.env.UNI_PLATFORM加载不同配置文件
/** * 此文件为@dcloudio/webpack-uni-pages-loader的一个钩子入口,遵循CommonJs规范 * 源码路径:node_modules\@dcloudio\uni-cli-shared\lib\pages.js */ const platform = process.env.UNI_PLATFORM.substring(3) // 获取platform mp-weixin const path = require('path') const routerFilePath = path.join(__dirname, `router/${platform}.js`) const platformPageConfig = require(routerFilePath) // pagesJson参数是pages.json值 module.exports = (pagesJson, loader) => { return { ...platformPageConfig, ...pagesJson } }
由于不是webpack的标准运行依赖,所以需要手动添加依赖项(使用addDependency),并且需要每次清除模块的缓存,修改一下src/pages.js代码
/** * 此文件为@dcloudio/webpack-uni-pages-loader的一个钩子入口,遵循CommonJs规范 * 可以直接使用require引入其他依赖,但是不会有热重载的效果,需要加上addDependency */ const platform = process.env.UNI_PLATFORM.substring(3) // 获取platform mp-weixin const path = require('path') const routerFilePath = path.join(__dirname, `router/${platform}.js`) const platformPageConfig = require(routerFilePath) // pagesJson参数是pages.json值 module.exports = (pagesJson, loader) => { // 开发模式下才需要热重载 if (['test', 'development'].includes(process.env.NODE_ENV)) { console.warn(`-----${process.env.NODE_ENV}----\n`) // 动态添加依赖,告诉webpack改文件需要热重载 loader.addDependency(require.resolve(routerFilePath)) // 手动清除缓存 delete require.cache[require.resolve(routerFilePath)] } return { ...platformPageConfig, ...pagesJson } }
大功告成,项目的路由配置一下清晰了许多,由于路由配置文件为js,可以加入代码进行条件化判断生成的路由。如果只需要生成一个平台的代码,也可以在此基础上对路由进行模块化。
参考文章 https: