When learning becomes habit, knowledge becomes common sense. Thank you for your attention, likes, favorites and comments.

New videos and articles will be sent to the wechat official account as soon as possible. Welcome to Lyn Li Yongning

This article has been collected in Github warehouse Liyongning /blog, welcome Watch and Star.

Introduction to the

It records the whole process in detail, starting with problem location, making an issue to the framework (UNI-App), making a solution (PR), and finally thinking.

Before the order

When you stumble on open source frameworks in your business, it’s your misfortune, but it’s also your luck, because it’s a great opportunity to add some sparkle to your resume.

Contributing PR to the open source community is a great way to prove that you have the technical side of P7, which is judged by business and technology, business benefits, depth and breadth of technology (you can do better with what others have, and you can do better with what others don’t).

The whole process took 3-4 days. I had never read the source code of UNI-App and UCharts before, so I shared the whole process here to give you an idea of how to solve the problem.

The environment

  • Uni-app CLI version 3.0.0-alpha-3030820220114011
  • Hbuilder version 3.3.8.20220114 – alpha
  • Ucharts version UNI-Modules 2.3.7-20220122

The phenomenon of

Uni-app and VUe3 + UCharts draw charts. The development environment is normal, but H5 cannot draw charts and does not report any errors after it is packaged and put online.

The development of online
APP normal normal
H5 normal Can’t draw

Problem orientation

I submitted an issue to the community of UCharts. After communication, the maintainer “suspected” that there was something wrong with renderJS of VUe3 of UNI-App, but he could not give a positive reply. Let go to the uni-app community to raise issue and not use uCharts in the example. I was skeptical of the answer and decided to position the question myself.

Suspected bug in uCharts

  • Ucharts View section key code
<view ... Other properties :prop="uchartsOpts" :change:prop=" rdchart.ucinit "> <canvas... Attributes / > < / view >Copy the code

The change:prop callback is called when a prop is changed. This is a capability provided by the UNI-App framework, but not mentioned in the official documentation, as can be seen in the source code.

  • After looking at the source code of UCharts, the code execution process of drawing charts is as follows:

When this. UchartsOpts = newConfig is executed, the change:prop event is not triggered, so it looks like there is a problem with uni-app’s View component

Thanks to the official of UCharts. After communicating with the community in the process of locating the problem, UCharts gave away a permanent super member for free. Thanks 🙏 🙏!!

View component prop and change: Prop

The following example is provided:

<template>
  <view>
    <view :prop="counter" :change:prop="changeProp"></view>
		<view>{{ msg }}</view>
  </view>
</template>

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from "vue";

const counter = ref(1)
const msg = ref('hello')

function changeProp() {
	msg.value = 'hello' + counter.value
}

// @ts-ignore
let timer = null
onMounted(() => {
	timer = setInterval(() => {
		counter.value += 1
	}, 1000)
})

onBeforeUnmount(() => {
	// @ts-ignore
	clearInterval(timer)
})
</script>

<style>
</style>

Copy the code
H5 development environment H5 after packaging
vue2 normal normal
vue3 normal Change: prop did not perform

There was no problem in the development environment, so by looking at the call stack in the change: Prop method and finding the method that triggered the change: Prop callback, we finally found the place where uni-App overwrites the render function. In @ dcloudio/uni – h5 – vue/dist/vue runtime. Esm. Js.

Read the uni-app source code and get the following:

Reactive data changes, triggering a reactive update of the VUE. For example, if your responsive data is passed as the prop attribute of an element, the patchProps method will be triggered in the patch phase. After this method is triggered, the method will check whether the old and new props have changed. If so, the new props object will be traversed and each attribute and value will be compared with the old one. If the value of __UNI_FEATURE_WXS__ is true and the key of the props is change:xx, then the patchProp method is called. At the beginning, patchWxs is called, and the patchWxs method will eventually call the change: Prop callback method through nextTick.

The following is a flow chart of the above execution process:

The problem was finally identified as __UNI_FEATURE_WXS__, which was true in the development environment but changed to false when packaged.

__UNI_FEATURE_WXS__

__UNI_FEATURE_WXS__ is a global variable, so it must be set with vite’s define option.

The next step is to find out where __UNI_FEATURE_WXS__ is set. You can search globally for this variable and find a method called initFeatures in the @dcloudio/uni-cli-shared package that declares a features object:

const {
  wx,
  wxs,
  / /... Other variables
} = extend(
  initManifestFeature(options),
  / /... Other methods
)

const features = {
  // vue
  __VUE_OPTIONS_API__: vueOptionsApi, // enable/disable Options API support, default: true
  __VUE_PROD_DEVTOOLS__: vueProdDevTools, // enable/disable devtools support in production, default: false
  // uni
  __UNI_FEATURE_WX__: wx, / / whether to enable small program component instance of apis, such as: selectComponent (uni - core/SRC/service/plugins/appConfig)
  __UNI_FEATURE_WXS__: wxs, / / whether to enable WXS support, such as: getComponentDescriptor (uni - core/SRC/view/plugins/appConfig)
  / /... Other attributes
}
Copy the code

WXS is true in both development and production environments. The next step is to find out who called the initFeatures method, and perhaps once that’s done, determine the current command by, for example, setting __UNI_FEATURE_WXS__ to false during build.

I just wanted to go forward. Vite-plugin-uni is a plug-in framework that uni-App provides for Vite. The vite configuration in Uni-App comes from this framework.

The uni plugin provides the config option. The config option is returned by calling the createConfig method, which returns an object that will be deeply merged with the vite configuration. This object has the define option, and the value of this option is the return value of createDefine, which is an object in which initDefine is called, and when you look down, it fails, and the path is dead.

After finding that the above forward derivation failed, I began to reverse derivation, i.e. global search, where initFeatures were called, and then pushed down step by step to obtain the correct flow chart as follows:

After final debugging, it was found that the final call path when starting the development environment and packaging is: uniH5Plugin -> createConfig -> configDefine -> initFeatures. The ultimate problem is the initManifestFeature method called by the initFeatures method.

The answer

Final positioning to the wrong place at the @ dcloudio/uni – cli – Shared/SRC/vite/features. The ts file initManifestFeature method. There are the following comparisons:

  • Github repository: 3.0.0-alpha-3030820220114011
if (command === 'build') {
    // TODO needs to be precompiled?
    // features.wxs = false
    // features.longpress = false
  }
Copy the code
  • Issued version of the code, highest version number: 3.0.0-alpha-3031120220208001
if (command === 'build') {
    // TODO needs to be precompiled?
    features.wxs = false;
    features.longpress = false;
}
Copy the code

The issued version is actually higher than the latest version number in the warehouse. View the release information on NPM:

The version number was found to be rolled back. Each of these rollback versions is a non-conforming version number and may contain bugs, such as the highest version mentioned above.

The version number of the release does not conform to the specification because the project does not have a standard release process, but it is already the alpha version, so this kind of low-level error should be avoided.

The more deadly operation is to roll back the version number. Uni-app currently each upgrade is the value after the minimum version number of the upgrade, and the package.json of the business project is “@dcloudio/uni-app”: “^ XXX “, which means that every time you repackage (for example, during automated deployment) or upgrade a package, you will update to a higher version of the bug, which will cause the online system to report a bug.

The solution

So the correct thing to do here is to reissue a higher version of the package, not to roll back the version. This operation may cause a bug in the system on the user’s line, that is, the following code cannot be executed properly:

<view :prop="msg" :change:prop="cb"></view>
Copy the code

When MSG changes, the change:prop callback is executed. However, this bug-laden high version of the package sets __UNI_FEATURE_WXS__ to false at package time (NPM run build), resulting in the change:prop callback not being called.

conclusion

The code can be rolled back, but the version number should not be rolled back. Based on the current stable version, send a new version with a higher version number.

Therefore, I proposed an issue and a solution to the official.

The results of

This solution has been adopted by the authorities to release a new version with a higher version based on the current stable version.

thinking

For a framework like Uni-App that is in alpha, it is true that the use of the ^ symbol should not continue within the project. Instead, the version number should be the latest tag version, because following the latest alpha version can be a real mistake.

link

  • Proficient in the UNI-APP column
  • Proficient in Vue technology stack source code principle column
  • Component Library column
  • Microfront-end

Thanks for following, liking, favorites and commenting, and we’ll see you next time.


When learning becomes habit, knowledge becomes common sense. Thank you for your attention, likes, favorites and comments.

New videos and articles will be sent to the wechat official account as soon as possible. Welcome to Lyn Li Yongning

This article has been collected in Github warehouse Liyongning /blog, welcome Watch and Star.