9***@qq.com
9***@qq.com
  • 发布:2020-04-08 00:10
  • 更新:2022-03-16 11:22
  • 阅读:8545

解决uni-app的pages.json的模块化及模块热重载的问题

分类:uni-app

uni-pages-hot-modules

uni-app的pages.json的模块化及模块热重载

解决uni-app的pages.json无法模块化的问题,并且解决模块热重载和缓存的问题

WOW!

0.1.0版本之后,直接可以使用require达到热更新,只需要引入高阶函数hot即可
废弃hotRequire方法,但是您仍可以使用,使用方式可以查看之前版本的说明

安装

npm i uni-pages-hot-modules -S

pages.json模块化及使用了uni-pages-hot-modules进行模块热重载的uni-app示例项目

注意!

  • 发现uni-app每次更新对pages.js的支持度会不同,比如某个版本竟然注释掉了对pages.js的热重载依赖,这里做了兼容。只要uni-app不推翻自己的设计,此功能长久有效
  • 使用uni-pages-hot-modules引入模块必须输入全的文件名包括后缀,否则将不会进行热重载

uni-pages-hot-modules做了什么

// 做了非常轻便的事情,相当于  
loader.addDependency(modulePath)  
delete require.cache[modulePath]  
require(modulePath)

uni-app的“彩蛋”

uni-app自带一个webpack loader钩子文件pages.js,在项目src目录下建立pages.js(与pages.json同级)即可生效(pages.json仍然需要存在,作为初始值,建议存放一些和路由无关的配置)。
pages.js要求CommonJS规范,直接通过module.exports输出一个钩子函数。

pages.js输出的函数参数

pagesJson < Object >

pages.json的解析内容

pages.js的模块化

由于是js,就可以实现模块的依赖,如果不考虑模块的热重载问题,可以不使用hot高阶函数
但是大多数情况下,需要依赖的模块也可以通过热重载更新pages.js,由于不是webpack的标准运行依赖,所以需要手动添加依赖项(使用addDependency),并且需要每次清除模块的缓存,因此uni-pages-hot-modules就诞生了

pages.js示例

const { hot } = require('uni-pages-hot-modules')  
module.exports = hot((pagesJson) => {  
    let basePages = []  
    let baseSubPackages = []  
  
    return {  
        // 合并pages.json的内容  
        ...pagesJson,  
        pages:[  
            ...basePages,  
            ...require('./page_modules/tabbar.js'),  
            ...require('./page_modules/component.js'),  
            ...require('./page_modules/appPlus.js'),  
            ...require('./page_modules/module1.js')  
        ],  
        subPackages:[  
            ...baseSubPackages,  
            ...require('./subpackage_modules/api.js'),  
            ...require('./subpackage_modules/extUI.js'),  
            ...require('./subpackage_modules/template.js')  
        ]  
    }  
})  
  

模块的规范

被加载的模块也是CommonJS规范,通过module.exports输出

module1.js示例

module.exports=[  
   {  
       "path": "pages/sub/sub",  
       "style": {  
           "navigationBarTitleText": "sub"  
       }  
   },  
   // 在模块里继续引入其他子模块  
   ...require('./some-sub-module1.js')  
]

API

context {function}

模拟webpack的require.context
与webpack不同的地方是不会将调用此方法的模块输出,没有id属性,resolve方法返回绝对路径

const files = require.context('.', true, /\.js$/)  
const modules = []  
files.keys().forEach(key => {  
    if (key === './index.js') return  
    const item = files(key)  
    modules.push(...item)  
})  
module.exports = modules

缺陷:require.context是模拟的,所以在支持热更新时也有一定缺陷,就是新创建的文件不支持热更新,需要重新编译即可(或者手动触发一次调用require.context的文件的更新也可以达到对新文件的热更新激活),删除和修改原有文件可以很好的支持热更新

其他

不支持条件编译,需要自己通过process.env.VUE_APP_PLATFORM来判断(不建议使用process.env.UNI_PLATFORM,因为在webpack客户端包里无法读取此环境变量,除非设置DefinePlugin),自定义环境的需要自己添加env变量来判断

7 关注 分享
内心油腻 DCloud_UNI_LXH 1***@qq.com 冷月i Jackpot ai自由畅想 BoredApe

要回复文章请先登录注册

JL

JL

我在pages.js 文件中加入 const files = require.context('./tabBar', true, /index\.js$/) 代码后,hbuilderx 一直处于编译中
2022-03-16 11:22
9***@qq.com

9***@qq.com (作者)

回复 今天回复我了吗 :
放心用,多个生产环境在使用
2022-02-09 19:48
今天回复我了吗

今天回复我了吗

好用吗,有人放在生产上了吗,会有问题吗
2021-12-03 17:28
9***@qq.com

9***@qq.com (作者)

回复 a***@vip.qq.com :
配合nodemon就可以有效果,不过会重新开始编译uni项目
2021-08-20 10:28
a***@vip.qq.com

a***@vip.qq.com

很赞,就是require.context新增文件没效果太可惜了
2021-07-06 10:56
TADPOLE

TADPOLE

**确实是一个非常好的工具,因为pages.json的维护问题困扰项目组很久了。**
### 受相关项目的启发,写了一个HBuilderX的插件[Pages-Tool](https://ext.dcloud.net.cn/plugin?name=pages-tool)。
**个人认为使用更简单,功能更灵活。欢迎大家共同讨论完善。**
2021-04-06 14:41
9***@qq.com

9***@qq.com (作者)

2020-11-10 15:45
内心油腻

内心油腻

mark
2020-11-06 17:40
小白_chen

小白_chen

回复 小白_chen :
我解决了。
2020-11-06 14:45
小白_chen

小白_chen

如果我想在这里修改导航栏的背景色呢?我试过了会报错,有什么解决方案吗?
2020-11-05 15:10