解决uni-app的pages.json模块化及模块热重载问题
解决uni-app的pages.json模块化及模块热重载问题
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变量来判断
在uni-app中,pages.json
文件用于配置页面的路由、导航条、选项卡等属性。为了实现模块化管理和模块热重载,我们可以结合Vue的组件化思想和uni-app的页面配置来实现。下面是一个示例,展示如何通过模块化配置pages.json
以及如何实现模块热重载。
1. 模块化配置pages.json
首先,我们可以将页面配置拆分成多个模块,然后在pages.json
中引用这些模块。例如,我们可以创建pagesConfig
文件夹,并在其中创建不同的配置文件,如homeConfig.json
、aboutConfig.json
等。
pagesConfig/homeConfig.json
[
{
"path": "pages/home/home",
"style": {
"navigationBarTitleText": "Home"
}
}
]
pagesConfig/aboutConfig.json
[
{
"path": "pages/about/about",
"style": {
"navigationBarTitleText": "About"
}
}
]
pages.json
{
"pages": [
// 引入homeConfig模块
{
"pages": require("./pagesConfig/homeConfig.json")
},
// 引入aboutConfig模块
{
"pages": require("./pagesConfig/aboutConfig.json")
}
// ... 其他页面配置
]
}
注意:pages.json
中直接引用模块的方式可能不被直接支持,这里的示例旨在展示模块化思路。实际上,你可能需要在构建脚本中合并这些配置文件,或者通过其他方式间接实现模块化。
2. 模块热重载
为了实现模块热重载,我们可以利用Webpack的HotModuleReplacementPlugin或者Vite等现代前端工具链的HMR(Hot Module Replacement)功能。不过,uni-app本身并没有直接提供对HMR的原生支持,但你可以通过配置Vite等支持HMR的工具来实现。
由于uni-app主要面向多端开发,其构建流程可能与传统的Webpack项目有所不同。因此,如果你希望实现模块热重载,可能需要:
- 使用支持HMR的自定义构建工具链(如Vite)。
- 修改uni-app的构建脚本,以集成HMR功能。
- 编写自定义的Webpack插件或Vite插件,以处理uni-app特有的构建逻辑。
由于这部分内容涉及到较复杂的构建配置和插件开发,这里不给出具体的代码示例。但你可以参考Vite或Webpack的官方文档,以及uni-app的社区和插件市场,寻找相关的解决方案或插件。
总之,通过合理的模块化配置和构建工具链的选择,你可以在uni-app中实现页面的模块化和模块热重载。