Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

小程序开发进度 #410

Open
RubyLouvre opened this issue Oct 19, 2018 · 17 comments

Comments

@RubyLouvre
Copy link
Owner

commented Oct 19, 2018

10.23 ~ 10.28要做的事

  • 重写三套模板,让支持快应用
  • 写一整套支持快应用的组件
  • 启用babel7,搞定中文转义问题
  • 内置webview组件
  • 模板的开发目录改成source,生产目录视构建目标有所不同(快应用为src, 其他为dist)
@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Oct 20, 2018

  1. 修复支付宝的事件对象不支持x,y属性的BUG ,解决方法pageX, pageY代替它们
  2. 修复支付宝的自定义组件不在json.usingComponents引用它们,就不会在组件JS 中引入Component的BUG ,解决方法,在子类的json.usingComponents添加父类的引用
  3. 修复无狀态组件的wxml, axml, swan生成错误,原因是两次进入render.exit方法,导致重复重成,第二次时jsx变成h方法,解决方法,通过modules.registerStatement是否为假值进行隔离
  4. 修复中文unicode化的问题,解决方法,通过以下正则
result.code.replace(/\\?(?:\\u)([\da-f]{4})/ig, function (a, b) {
        return unescape(`%u${b}`);
    });
  1. 修复if指令导致多生成一个block标签的问题,解决方法,重构logic helper,让它总是返回组数组
  2. 修复快应用的import标签的src计算不正确的BUG,见
// miniappTransform.js
var ux = `${uxFile.template || ''}`;
let using = uxFile.config && uxFile.config.usingComponents;
if (using) {
    //假设存在<import>
    let importTag = '';
    for (let i in using) {
        let importSrc = path.relative(sourcePath, path.resolve(cwd + "/src/" + using[i]));
        importTag += `<import name="${i}" src="${importSrc}.ux"></import>`;
    }
    ux = importTag + ux;
}
  1. 美化wxml, swan, awxml, ux文件,解决方法,引入 js-beautify模块
@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Oct 23, 2018

百度

template for中不能使用template is

快应用

事件对象没有currentTarget, 点击事件 没有pageX, pageY这些表示位置的属性,
元素没有dataset对象,
样式与其他小程序差异巨大,并且不能继承, display只有flex|none,没有绝对定位,相对定位,没有浮动
style, class的值不能直接用{{}}
class 有吞并空格BUG

支付宝

标识组件是使用usingComponents而不是component: true
<web-view/>标签的dataset总是为空对象
组件没有与create对应的生命周期
同一排组件的生命周期的触发顺序是乱的

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Oct 25, 2018

支付宝样式处理

previous: <div className={'foo' + this.state.className}></div> -> <div className="{{'foo' + state.className}}"
current: <div className={'foo' + this.state.className}></div> -> <div className="foo {{state.className}}"
@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Oct 30, 2018

prettify-xml
js-beautify
html-minifier

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Oct 31, 2018

大约从11月份开始,我们切换到branch3开发

原来master上使用 template机制来编写组件,它其实规避了许多问题,因为4大小程序的自定义组件机制都各有不同,
template则是兼容成本最低的方案。但是用template编写组件,其实那不是组件,对于小程序来说就是视图片段。换言之,
一个页面只有一个组件,而这个组件的数据则是非常庞大。果不其然,它在支付宝小程序的IOS8/9中因为性能问题挂掉,只好
匆匆切到branch3

branch3使用自定义组件机制实现组件,目前来看,微信与百度很相似,内部是运行一个迷你React,加上我们的迷你React,
事实上是两个React拼接视图,创建组件。并且这两套React生命周期触发顺序与官方React是一样的。

我们的组件机制是这样的实现的,首先,anu diff 虚拟DOM ,在onBeforeRender时机 将组件实例放到构造器上的reactInstances数组上,
然后小程序在渲染视图,它内部也diff 虚拟DOM,在created生命周期钩子中,拿到this(小程序的组件实例),
然后再从reactInstances shift出一个React组件实例,让它们互相关联,用React的数据刷新小程序组件实例。

但,支付宝的生命周期名字不一样,并且少了created钩子,那我们想在didMount钩子(对应微信的attached钩子)拿到this,然后。。。
可惜支付宝没有让我们这么顺利。 假设一个页面有4个名为Dialog的组件,那么它们钩子的触发顺序应该根据它们在视图的位置从上到下,从左至右触发的,
而支付宝是随机触发的。于是我们在编译阶段,在React的JSX 与 支付宝的awxml上都添加了一个UUID,确保我们的React实例能找到真正对应的支付宝小程序实例。

快应用就更麻烦些,它像vue那样三种格式都放在同一个文件中,而script标签是无法export出任何东西,于是我只好将组件定义单独拆到另一个文件。这样搞定引用父类的问题。

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 1, 2018

支付宝的React基本完工!

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 7, 2018

An expiration time represents a time in the future by which an update should flush. The priority of the update is related to the difference between the current clock time and the expiration time. This has the effect of increasing the priority of updates as time progresses, to prevent starvation.

过期时间表示将来更新应该刷新的时间。更新的优先级与当前时钟时间和过期时间之间的差异有关。这样做的效果是随着时间的推移增加更新的优先级,以防止饥饿。

Starvation and Livelock 饥渴和活锁
Starvation and livelock are much less common a problem than deadlock, but are still problems that every designer of concurrent software is likely to encounter
饥渴和活锁相比死锁是不那么常见的问题,但是仍然是同步软件开发的每个开发者有可能会遇到的问题。

Starvation 饥渴
Starvation describes a situation where a thread is unable to gain regular access to shared resources and is unable to make progress. This happens when shared resources are made unavailable for long periods by "greedy" threads. For example, suppose an object provides a synchronized method that often takes a long time to return. If one thread invokes this method frequently, other threads that also need frequent synchronized access to the same object will often be blocked.
饥渴描述了这样一种状况:一个线程不能够正常访问共享资源造成它不能够前进往下执行。这通常发生在当共享资源因为贪婪的线程长时间不能够被其他线程获得。比如,假如有一个同步方法通常需要很长时间才返回。如果一个线程频繁调用这个方法,其他的线程也需要频繁的同步访问同一个对象,这就会造成阻塞。

Livelock活锁
A thread often acts in response to the action of another thread. If the other thread's action is also a response to the action of another thread, then livelock may result. As with deadlock, livelocked threads are unable to make further progress. However, the threads are not blocked — they are simply too busy responding to each other to resume work. This is comparable to two people attempting to pass each other in a corridor: Alphonse moves to his left to let Gaston pass, while Gaston moves to his right to let Alphonse pass. Seeing that they are still blocking each other, Alphone moves to his right, while Gaston moves to his left. They're still blocking each other, so...

一个线程通常会有一些动作回应其他线程的活动。如果其他线程也会回应另一个线程的活动。这时就会导致活锁的发生。就像死锁,活锁也不能继续向前执行。然而线程并没有被阻塞-它们只是忙于彼此互相回应而不能继续工作。这可以比作有2个人在走廊上试图让彼此都通过:Alphonse移动他的左脚让Gaston通过,同时Gaston移动他的右脚让Alphonse通过。可以看到他们仍然互相阻塞,Alphone移动他右脚的时候,Gaston移动他的左脚。他们仍然互相阻塞在

java中发生线程饥饿的原因
高优先级的线程占用了大部分的cpu时间,低优先级线程发生饥饿
线程被永久堵塞在一个等待进入同步块的状态
线程在等待一个本身(在其上调用wait())也处于永久等待完成的对象
高优先级的线程占用了大部分的cpu时间,低优先级线程发生饥饿
你可以给每个线程单独的设置优先级。优先级越高,就会获得越高的cpu执行的机会。

线程被永久堵塞在一个等待进入同步块的状态
java 的synchronize语句块不保证线程进入语句块的顺序,所以这就存在一个可能的问题,有一个线程一直阻塞在synchronize语句块,永远都无法进入synchronize。

线程在等待一个本身(在其上调用wait())也处于永久等待完成的对象
同样的,类似synchronize,notify也不保证线程被唤醒的顺序。所以也存在一个风险,就是一个wait的线程一直处于wait的状态,永远也没有被notify所唤醒。

作者:六尺帐篷
链接:https://www.jianshu.com/p/8abbba62afce
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 14, 2018

快应用现在遇到的问题与难点

  1. 现在 this.$app 这个东西是无法保存起来,希望有类似getApp()全局方法,得到app.ux的对象,在里面加方法或数据
    能跨页面保存不会丢失。 重要!!

  2. 希望有类似的 wx.createSelectorQuery API 传入id或类名,得到页面上某一元素的位置与长宽
    https://developers.weixin.qq.com/miniprogram/dev/api/wxml/SelectorQuery.select.html
    这在开发UI组件时非常有用

  3. 希望有类似scrollTo的方法 , 用于设置滚动条的位置

  4. 事件对象希望有pageX, pageY这样的位置属性

  5. text,span等标签中能使用slot机制

  6. CSS的支持要更为完善

  7. 希望开发者工具有预览功能

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 18, 2018

需要重新实现的组件 slider, swiper(它们都依赖于touch事件,快应用暂时不支持,可以先在微信上测试),picker, scroll-view, icon, button

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 19, 2018

checkbox, radio, picker的重新实现, window下的路径问题, 一个页面内有多个相同的组件它们与react实例对接时是否正常,YIS render的支持

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 19, 2018

import { registeredComponents, usingComponents, updateMiniApp } from './utils';
import { dispatchEvent } from './eventSystemQuick';
export function registerComponent(type, name) {
    registeredComponents[name] = type;
    type.ali = true;
    var reactInstances = (type.reactInstances = []);
    var wxInstances = (type.wxInstances = []);
    return {
        data(){
            return {
                props: {},
                state: {},
                context:{}
            };
        },

        onInit() {
            usingComponents[name] = type;
            /*
            var instance = reactInstances.shift();
            if (instance) {
              
                console.log("created时为", name, "添加wx");
                instance.wx = this;
                this.reactInstance = instance;
            } else {
             
                console.log("created时为", name, "没有对应react实例");
                wxInstances.push(this);
            }
            */
        },
        onReady() {
            var uid = this.props.instanceUid;
            for (var i = reactInstances.length - 1; i >= 0; i--) {
                var reactInstance = reactInstances[i];
                if (reactInstance.instanceUid === uid) {
                    reactInstance.wx = this;
                    this.reactInstance = reactInstance;
                    updateMiniApp(reactInstance);
                    reactInstances.splice(i, 1);
                    break;
                }
            }
            /*
            if (this.reactInstance) {
                updateMiniApp(this.reactInstance);
             
                console.log("attached时更新", name);
            }*/
        },
        onDestroy() {
            this.reactInstance = null;
        },
        dispatchEvent
        
    };
}
@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 20, 2018

image

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 20, 2018

image

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 20, 2018

image

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Nov 20, 2018

image

@avalonjs

This comment has been minimized.

Copy link

commented Feb 15, 2019

node-sass改成dart-sass

@RubyLouvre

This comment has been minimized.

Copy link
Owner Author

commented Feb 15, 2019

根据npm源处理补丁组件的内外部组件的合并问题。内部组件比外部组件多了像日历等只有去哪儿网内部员工才能用的组件

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.