# Q&A

# 限制

此方案虽然将整个 Web 端框架包含进来并提供了适配层,但是也不是银弹,无法满足所有场景,限制的原因主要出自小程序本身的运行机制限制。

# 答疑

Q:kbone 主要有哪些依赖包?如何安装升级 kbone 依赖?
A:kbone 依赖主要包含三个:mp-webpack-pluginminiprogram-elementminiprogram-render。其中 mp-webpack-plugin 是一个 webpack 插件,需要安装在项目目录中。miniprogram-elementminiprogram-render 则是小程序代码的依赖,需要安装在小程序目录中。默认情况下,使用 webpack 和 mp-webpack-plugin 生成小程序代码的时候,会在小程序目录生成 pakckage.json,直接在小程序目录执行 npm install 就会在小程序目录下安装 miniprogram-elementminiprogram-render。升级过程和安装同理。


Q:kbone 的构建是否会影响 Web 端代码?
A:kbone 的本质是一个运行在原始 Web 端代码和小程序环境之间的适配器,它只会处理输出到小程序端的代码,不会处理 Web 端的构建,因此 Web 端构建产生的问题基本和 kbone 无关。当然,你也可以按照自己需要对 Web 端的构建进行调整,不用非要使用 demo 的 Web 端构建方法,只要做好和小程序端代码构建的隔离就行(demo 里就是分成两份配置来做隔离)。


Q:webpack 构建模式能否指定成 development
A:不建议将构建模式指定成 production 之外的模式,以免出现奇怪的问题。比如 development 可能就会引入 eval 调用,这在小程序中是不支持的。如果需要调试业务代码,可以通过调整 minimizer 配置来取消压缩处理;如果需要调试第三方代码,可以通过设置 resolve.alias 来将指向第三方包未压缩的入口文件。


Q:对于像 getBoundingClientRect 等接口,有没有什么兼容方案?
A:部分无法直接适配的接口会以 dom/bom 扩展 api 的方式提供。


Q:是不是小程序里的所有页面必须同源?
A:目前的设计是这样的,遇到不同源的页面会提供事件提示和异常页面跳转配置。


Q:能否支持异步组件?
A:受限于小程序环境,目前无法支持。


Q:为什么无法支持 scoped style?
A:因为小程序不支持动态追加未声明的属性。


Q:为什么使用 reduce-loader 不生效?
A:请检查一下是否给 script 标签设了 lang="ts",如果是的话可以去掉这个属性再试试,目前 ts-loader 对行内 loader 的支持不够完善。


Q:为什么 iframe 标签无法支持?
A:小程序里的 web-view 组件提供了类似 iframe 标签的实现,但是 web-view 组件不支持自定义大小,故放弃了对 iframe 的支持。


Q:为什么 vue 的 transition 组件的使用效果不如预期?
A:transition 组件内部使用了同步接口 window.getComputedStyle,故无法完美支持。


Q:对于异步请求要如何兼容?
A:内置的 XMLHttpRequest 对象可以满足大部分场景;对于上传文件等场景需要自行兼容,比如可以选用 wx.uploadFile 来实现文件上传。


Q:能否使用小程序内置组件?
A:目前代码里预埋进了能力,但是仅支持部分组件,用法可阅读开发文档,后续会慢慢补齐。


Q:为什么 img 标签有 mode 属性和没有 mode 属性表现会不太一样?
A:因为 img 标签有 mode 属性在底层会被渲染成 background-image 模式(即小程序 image 组件默认的形态),没有 mode 属性会被渲染成和 web 端相同的 img 模式。


Q:为什么不支持 radio-group/checkbox-group 内置组件?
A:因为 radio-group/checkbox-group 内置组件下的 radio/checkbox 不支持跨自定义组件,可以使用 input 的 change 事件来替代 radio-group/checkbox-group 的 change 事件,通过获取 input 的 checked/value 也可以获取到其状态(类似 web 端的表现)。


Q:项目中用到的图片等静态资源要如何处理?
A:目前暂不支持相对路径,故静态资源可以考虑转成 base64 或者使用网络地址。


Q:能否支持分包?
A:分包和分包预下载已支持,具体可参考 mp-webpack-plugin 的 runtime 配置项。独立分包可通过 generate.app 配置变相支持。


Q:为什么 label 不支持 button 组件?
A:因为小程序 label 组件不支持跨 shadow-tree 绑定,所以 label 标签的效果其实是在逻辑层监听点击事件后模拟出来。而 button 支持的复杂特性都需要用户亲自点击触发,无法在逻辑层模拟触发,故不支持。


Q:为什么使用小程序内置组件的时候,对于父子节点会相互影响的样式表现(比如 flex)会不太符合预期?
A:0.x 版本和 1.x 版本绝大部分小程序内置组件在渲染时会插入一层容器节点,所以会对部分样式有影响。对于这种情况,可以参考这篇文档里提到的的方式来处理。


Q: 为什么使用小程序内置组件的时候样式有时候会不生效?
A: 和上一个问题的原因相同,对于这种情况,可以参考这篇文档里提到的的方式来处理。


Q:为什么 v1.x 版本的 scroll-view 的 scroll-into-view 属性有时可用有时不可用?
A:因为 v1.x 版本的 scroll-into-view 找寻的节点只能在当前 shadow-tree 下,因此只有传入 domSubTreeLevel 配置对应层级内的 div、img 标签对应的 id 方能生效。如果 domSubTreeLevel 的值为 5,那么只有 scroll-view 下 5 层节点内的 div、img 标签上的 id 可以作为该 scroll-view 上 scroll-into-view 的值。v2.x 版本则无此问题。


Q:页面做更新的时候,有时候很快,有时候很慢,这是怎么回事?
A:更新慢的时候,通常这是一棵比较矮胖的 dom 树,所有节点都在一个自定义组件里面了,导致小程序基础课做更新 diff 时,特别慢。这种情况可以将频繁更新的部分包裹在一个 wx-view 标签内,这样会强制创建新的自定义组件。此方法有利有弊,自定义组件过多也会导致渲染变慢,所以需要根据实际情况进行调整,不能一味地使用 wx-view。


Q:已知 location.href,如何封装成对应的小程序的页面路由?
A:先找到对应的页面路径,假设是 pages/home/index,那么封装方式:/pages/home/index?type=${type}&targeturl=${encodeURIComponent(location.href)}&search=${encodeURIComponent(location.search)}&hash=${encodeURIComponent(location.hash)}。type 支持 open(新开页面)、jump(页面内跳转)和 share(分享进入),一般在配置体验版、添加工具模式等情况下使用 type=open 即可;targeturl 是经过编码的 location.href(也可以是 /test/abcde?id=123#hash 这样不带 origin 的 url,以缩减页面路由的长度,kbone 会自动取配置中的 origin 进行拼接);search 和 hash 可传可不传,如若不传,则取 targeturl 中的 search 和 hash 进行解析。


Q:为什么我新增页面后重新构建,代码包会变大那么多?
A:新增页面后,依赖会重新调整输出,但是 kbone 的 demo 中输出是增量的,所以并没有清理旧的输出文件,因此代码包里会残留废弃文件。开发者可在执行构建命令前对输出目录进行一次清理(比如使用 rimraf),即可保证输出目录是纯净的。


Q:react/preact 进行多页开发的时候,在页面关闭时没有执行 componentWillUnmount 钩子要怎么处理?
A:react/preact 并没有提供根组件实例的销毁方法(如 vue.$destroy),因此开发者可自行监听 wxunload 或 beforeunload 事件来进行页面的销毁工作,比如调用 render 方法渲染一个空节点,强行触发页面组件的 componentWillUnmount 钩子。


Q:在小程序 tabbar 页面里使用了单页模式(比如 vue-router),所有关于路由的配置都加上了,为什么进入页面会白屏?
A:这种情况大部分是因为单页配置的路由没有响应 / 导致。小程序 tabbar 的配置不支持在页面路径后面追加参数,导致进入页面时默认进入的 path 是 /,如果开发者没有响应此 path,那么页面就是空的。可以尝试在单页配置的路由上补充 / 的跳转(比如 vue-router 可以通过配置 redirect 让 / 响应并自动跳转到想要展示的路由上)。


Q:使用 Web 框架时,发现存在某些节点的布尔值属性无法设置该怎么办?(比如在 vue 中想要设置 video 的 controls 属性为 false)
A:请参考文档批量设置节点属性


Q:使用 Web 框架时,发现存在某些节点的事件监听器无法设置该怎么版?(比如在 react 中想要监听 picker-view 的 change 方法)
A:请参考文档批量设置事件监听器

# 反馈

如果还遇到其他问题,可在 issue 中反馈。

使用遇到问题可在 Kbone社区 发帖。