探索Web编程的另一种形态 俞天翔

前端狗

2019/06/10 发布于 技术 分类

Vue 

文字内容
1. 探索Web编程的另一种形态 天翔Skyline PPT Powered By vue-mark-display(@Jinjiang)
2. 起源 老板:“我们来搞个快手小程序吧” 我:“好的” 老板:“我说的是快手里的小程序哦,不是快手小程序” 我:“明白” 老板:“为了让别人迁移成本低一些,我们就直接用微信的API吧!” 我:“好的” 老板:“月底搞完初版哈~” 我:“……”
3. Demo
5. 架构设计
6. 通信 try { const result = await bridge.invoke( bridge.invoke('xxxx' 'xxxx') ) } catch catch(e) (e) { // TODO Something }
7. 通信封装 SDK 内部维护Promise状态控制与global callback注册/销毁
8. 层 View Runtime Vue.js
9. 模板编译
10. WXML TO Vue Template
11. wxml wx:if wx:elif wx:else vue template v-if v-else-if v-else wx:for wx:key v-for="(item, index / key) in items" wx:for-index wx:for-item wx:attr v-bind bindevent v-on parse5
12. Vue Template TO Vue Render Functions vue-template-compiler + vue-template-es2015-compiler @vue/component-compiler-utils
13. 歪个楼
14. vue-block-lite-component + @vue/component-compiler-utils = SFC Render Function > > > > 拯救那些从React过来的开发者们
15. 代码编译 JS
16. 入口劫持 - Webview const code = appConfig.pages.reduce(( appConfig.pages.reduce((code: string string, , id: string string) ) => { const { render, staticRenderFns } = getRenderFunctionsById(id); const css = compileCss(resolve(__dirname, `../../demo/ `../../demo/${id} ${id}.wxss` .wxss`)); )); code += ` window.currentPage = { path: '${id} '${id}', ', render: ${render} ${render}, , staticRenderFns: ${staticRenderFns} ${staticRenderFns}, , css: \`${css} \`${css}\` \` }; require('../../demo/${id} require('../../demo/ ${id}.js') .js') `; ` ; return code; }, '' ''); ); return source.replace( source.replace('/* '/* <%=element> */', */', code);
17. 入口劫持 - JSCore const code = appConfig.pages.reduce(( appConfig.pages.reduce((code: string string, , id: string string) ) => { const { render, staticRenderFns } = getRenderFunctionsById(id); code += ` global.currentPage = { path: '${id} '${id}', ', render: ${render} ${render}, , staticRenderFns: ${staticRenderFns} ${staticRenderFns}, , }; require('../../demo/${id} require('../../demo/ ${id}.js'); .js'); `; ` ; return code; }, '' ''); ); return source.replace( source.replace('/* '/* <%=app-service> */', */', code);;
18. 代码执行 JS
19. 劫持 - Webview Methods window.Page = function ( window.Page (options:'>options: options:'>options: PageOption) PageOption) { const vueOptions: {[key: string string]: ]: any any} } = { methods: {}, }; Object.keys(options).forEach( Object .keys(options).forEach(key key => { if (!mpLifeHooks.includes(key) && typeof options[key] === 'function' 'function') ) { vueOptions.methods[key] = function ( (...args:'>args: ...args:'>args: any any) ) { publish( 'page.methods.event', 'page.methods.event' , { methodName: key, val: args.map(( args.map((params: any any) ) => { return params instanceof UIEvent ? replaceEvent(params as UIEvent) : params; }), }, [window [ window.__webviewId__], .__webviewId__], ); }; } }); }
20. vdom 不完整的执行render,就不能拿到完整的vdom tree
21. So
22. 魔改Vue.js
23. Fake document API 从这里面下手就好了= =
24. 组件 JS 把公司内的组件库拿来直接用就好了……
25. 原生组件 使用Vue.component Wrap一下,然后通知Native渲染位置
26. 坑!! 几何属性只能在webview中获取 native能力只能在JS Core中使用
27. 临时性方案: Object.keys(component.options.methods).forEach(key Object.keys(component.options.methods).forEach( key => { const oldMethod = component.options.methods[key]; component.options.methods[key] = function ( (...args:'>args: ...args:'>args: any any) ) { try { const res = oldMethod.call(this oldMethod.call(this, , ...args); if (res && typeof res.then === 'function' 'function') ) { res.catch(( res.catch( (e: any any) ) => { console.log( console .log(` ` ${key}` ${key} `); publish( 'runInService', 'runInService' , { id:'>id: this this._uid, ._uid, data:'>data: args, method:'>method: key, }, [window [ window.__webviewId__], .__webviewId__], ); }); } return res; } catch (e) { console.log( console .log(` ` ${key}` ${key} `); publish( 'runInService', 'runInService' , { id:'>id: this this._uid, ._uid, data:'>data: args, method:'>method: key, }, [window [ window.__webviewId__], .__webviewId__], ); } }; }); 不好,异步方法出错了,方法名为 不好,同步出错了,方法名为
28. 映射关系 component 通过私有属性: _uid
29. : Run in Service console.log('updateComponent:::''>updateComponent:::' console.log( 'updateComponent:::''>updateComponent:::' + JSON JSON.stringify(data)); .stringify(data)); if ( (this this.route.webviewId .route.webviewId !== data.webviewId) { return; return ; } console.log( console .log(` ` ID ${this.vm._uid} ${this.vm._uid}` `); const component = this this.findChildComponent(data.data.id .findChildComponent(data.data.id + this this.vm._uid .vm._uid - 1); if (component) { console.log( console .log(` ` ${data.data.method} nodeId ${component.nodeId} ${component[data.data.method]}` ${component[data.data.method]} `, ); console.log( console .log('data 'data ' + JSON JSON.stringify(data)); .stringify(data)); if ( (Array Array.isArray(data)) .isArray(data)) { return component[data.data.method](...(data.data.data [])); } 当前跟组件 为 找到组件啦!!接下来要执行 函数为: 为 return component[data.data.method](data); } console.log( console .log(' ' fork Vue 我没找到, , 改 不得好死!活特么该!(逃'); '); 为 ,
30. 后续 项目还是砍掉了
31. 著名前端专家xx:"其实小程序就是微信挖的封闭生态,其他 家玩也难受不玩更惨。"
32. 小程序是业务形态,并不是技术形态
33. 痛苦 写的既不是Web,也不是Node
34. 这玩意存在到底有什么价值!?!
35. 如果你跳出现有思维模式想一下呢? by 勾三股四
36. 重新思考一下小程序的技术价值
37. 线程隔离 数据驱动 组件化 有限的API调用
38. 在Web下是否有类似的可能性?
39. ! Web Worker
40. 线程隔离: Web Worker 数据驱动:Vue.js 组件化:Vue.js 有限的API调用:Web Worker
41. 微前端
42. 以前:iframe 现在:可以考虑使用web worker
43. 技术的探索总会有它的价值
44. Q/A