Giter Club home page Giter Club logo

mip2's Issues

MIP2 Checklist

MIP2 执行关键路径时间点

  • [6.1] 打通 MIP2 上线机制,上线 mip.js mip.css 到线上 v2 目录,供开发者调试使用
  • [6.18] 完成 MIP2 除组件迁移外的所有工作
  • [6.18] 有一个外部灯塔能上线(delay至6月29上线)
  • [6.18 - 7.18] 筛选出能够静默替换 mip.js 到 v2 的站点作为测试站点
  • [6.18 - 7.18] 完成和明确 v1 和 v2 性能、稳定性等统计方案
  • [6.29] 完成官方组件的迁移
  • [7.2] 明确 MIP1 => MIP2 静默替换方案
  • [7.18] 至少一个灯塔完全使用 MIP2 的代码,包括 mip.js 和所有组件

组件内使用watch监听数据出错

BUG 描述
vue单文件内,使用watch监听数据时,this显示undefined,但是在这里打断点,就可以读到this

复现步骤

  watch: {
    currentIndex: (cur, pre) => {
      console.log(this)
    }
  },

期望结果

正确拿到this

截图

17cf3f164ced1dcdf639a01da3c18c53

61592bfd7ba606f6ba19843e7f2f114d

环境及版本信息:

  • OS: MAC OS
  • Browser Chrome
  • Version 67
  • mip-cli 1.17

其他信息

mip-shell切换页面时,需要不同的行业shell允许自定义loading样式

背景:
目前mip-shell切换时,页面入场动画都是统一的从右往左滑动入场,但是在小说这个业务中,用户进行翻页操作时,大范围的页面入场,整体交互体验较差,希望可以自定义行业shell的loading入场动画。

诉求:
希望mip-shell能够暴露出来创建loading和页面入场动画的接口,行业shell可以根据需求自行定制。

刷新返回,iframe依旧存在

  • 类型:bug
  • 概率:必现
  • 复现:页面A跳转至页面B,刷新页面B,返回至页面A,页面A B 同时存在

操作如图:

2018-07-09 17_08_31

完善错误提示

  1. on 事件执行过程中如果发生错误,应该给予提示,应提示开发者哪句话错了,以及错在哪里,如下面代码,点击毫无反应,也没有错误或者警告日志
<mip-data>
  <script type="application/json">
  {
    "text": "aaaa"
  }
  </script>
</mip-data>
<span m-text="text"></span>
<button on="tap:MIP.setData({text: 'btn clicked'})">button</button>
  1. m-bind/m-text 绑定不存在的变量时无效,也不提示
<span m-text="aaa"></span>
<button on="tap:MIP.setData({aaa:'btn_clicked'})">button</button>

MIP2 核心代码体积和性能优化

当前的 MIP2 核心代码 gzip 前为 328.73kb, gzip 后为 95.8kb

现在基本总结出有以下优化点 (每一点还可以细化,但是现在还没有具体方案,具体方案和进展本 issue 同步):

  • [6.13] 尝试使用 rollup 做最后的构建工作,使用 webpack 进行 dev 开发
  • [6.13] JSON5 库的优雅替代方案
    • [6.13] JSON.parse 精准报错信息
  • [6.13] core-js 的 polyfill 和 src/polyfills 的合并
  • [6.13] esl 采用 runtime 版本,去掉高级功能
  • [6.26] 与 mip2 vue 组件项目的编译的配合机制的优化(重点)
  • [待定] 针对 mip1 代码,尤其是较大的文件进行的深度 review 和优化

viewer 的首屏机制当滚动条不是在 body 上的时候会失效

当滚动条不是在 body 上而是在 body 上的 dom 容器的话,那 viewer 首屏机制就不会生效。

从具体表现上来看:

现在 /examples/wecoffee/index.html 这个 case 所有的图片都在第一次加载页面的时候全部加载进来,这不符合 mip-img 的预期,对性能会有很大的影响。

iOS 下 UC/手百 切换页面造成未响应

问题描述

在进行页面切换时,会把当前的 <iframe> 进行隐藏/展现,使用 display: none
但是在 iOS 的 UC/手百 下,切换时会出现页面不响应,假死的现象,十分奇怪。

打开这个简单的 测试页面 /mip/examples/page/iframe/uc.html ,就可以复现,步骤如下:

  1. 原始页面使用 <iframe> 嵌入一个测试页面 scroll.html
  2. 点击隐藏按钮隐藏掉整个 iframe
  3. 原始页面不响应,表现为无法滚动,按钮无法点击等等

测试页面 scroll.html 包含一个菜单,使用了 iOS 弹性滚动。另外还包含以下测试:

  1. 嵌入 m.baiduAMP 页面 都会出现这种情况。而 PC 百度,eleme H5 则不会出现。
  2. 使用以下方法隐藏 <iframe> 同样会出问题:
  • visibility: hidden
  • opacity: 0 + height: 0 + width: 0

可能的原因

微信不存在这个问题,因为在 iOS 下使用了较新的 WKWebview。
而 UC/手百 使用的是 UIWebView。除了这个奇怪的问题,还有诸如 scroll 事件延迟 等其他滚动相关的问题,详见

有问题的页面使用了弹性滚动 -webkit-overflow-scrolling: touch;
而一旦不使用这个属性,或者在隐藏 iframe 的同时由被嵌入的页面去掉这个属性,就不会出现问题。

// 需要在隐藏的同时去掉 -webkit-overflow-scrolling: touch;
iframe.contentDocument.querySelector('.menu').classList.remove('touch-scrolling')

解决方案

第一种比较直接,就是判断处于 UC/手百 下,在页面切换时,就直接删除 iframe,而不是隐藏。

第二种就是在页面切换也就是隐藏 iframe 时,关闭掉所有组件的弹性滚动。
但是这样做的问题就是,内置的组件还好办,用户写的组件也会使用到弹性滚动,这就要求页面切换时需要通知所有的组件,让用户做这样的操作。

全局共享组件方案

问题背景

目前在根页面中以 iframe 方式打开多个子页面,各个子页面渲染各自的自定义组件。
有一种需求是类似登录框这样的组件,并不需要每个页面都渲染一遍,而是应该由根页面统一负责渲染。

例如目前的 <mip-shell>,虽然每个页面都会写在各自的 HTML 中,但实际只会在根页面中运行。
更类似于一种全局性的配置文件。

而全局组件比 <mip-shell> 更加复杂,因为可能会与页面中其他组件交互。

大致思路

在子页面中,在自定义组件注册之前,一旦识别到全局组件(加上特殊的 attribute),向根页面通过 postMessage 发送组件 DOM 结构(字符串形式),然后从 DOM 中删除避免触发 connectedCallback

根页面接收到事件,如果当前不存在这个全局唯一的组件,请求组件对应的 JS,插入 DOM 结构开始渲染。

可能存在的问题是和原子页面中其他组件的交互。不过如果统一使用全局的状态数据,似乎子页面其他组件也不用关心这个全局组件的具体渲染细节。

on 事件执行 setData 时,如果数据表达式使用了括号,将无法执行

BUG 描述
on 事件触发执行 MIP.setData 时,如果数据表达式使用了括号,将无法执行

复现步骤

<mip-data>
  <script type="application/json">
  {
    "value": 1
  }
  </script>
</mip-data>
<h1 m-text="value" on="tap:MIP.setData({value:(m.value+1)})"></h1>

把表达式中的括号去掉就可以正常执行了,已验证过与 setData 方法无关

期望结果
点击触发 setData,h2内容随着点击自增

环境及版本信息:
没有特定环境

[WIP] mip iframe & shell 向 2.0 迁移

MIP 2.0 支持在站点页面内无缝原生地切换页面。页面体验与之前 MIP1.0 在搜索结果页打开的体验对齐 (参考 MIP 官网的预览效果),即:点击任意链接后,马上出现一个新页面侧滑进入当前页面,并显示头部和 loading;加载完成后保留头部、取消 loading。

在搜索结果页 superframe 环境下打开时,我们依然沿用这一行为:MIP 站点的页面之间切换(内链),仍然由 MIP 2.0 的核心代码管理并组织;而在站点之间(外链)切换或者调起百度搜索相关服务(登录、支付等熊掌号能力)的时候,则交由 superframe 控制。

为了讨论简单起见,我们首先讨论内链的行为。

内链行为

  • 内链需要在百度搜索结果页内有平滑的切换交互效果(under iframe,待测试)。
  • 内链切换需要在非百度搜索结果页环境下拥有平滑的交互效果(现在好像是头部瞬间变化,底下做动画,需要一起动画过来)。
  • 切换之后,若页面本身是在搜索结果页环境下打开的,那么需要修改路由行为,以便在刷新之后也能保持历史记录:
    • 内部路由使用 replaceState 而不是 pushState 修改 url
    • 将修改后的 url 传递给 superframe,由后者通过 pushState 修改浏览器上的 url
      • 需要双方确定 api
      • 需要双方开发联调

按代码命名规范在本地json中书写驼峰属性,无法正常读取

BUG 描述
代码命名规范在本地json中书写驼峰属性,无法正常读取(根本没过来?)

复现步骤

<!-- html -->

<mip-json>
  <script type="application/json">
    {
      "mipProps": "mipProps",
      "mip-components": "mip-components"
    }
  </script>
</mip-json>
// components

export default {
  props: {
    mipProps: {
      type: String,
      default: ''
    },
    mipComponents: {
      type: String,
      default: ''
    }
  },
  mounted () {
    console.log(this.mipProps)       // 空
    console.log(this.mipComponents)  // mip-components
  }
}

驼峰属性无法打印,连字符正常

环境及版本信息:

  • OS: IOS
  • Browser chrome
  • Version 67
  • mip-cli 1.19

mip-cli dev 不支持js 后加md5戳,会导致浏览器缓存

mip-cli dev 不支持js 文件加md5戳,会导致浏览器缓存,手机预览时需要清理缓存

image

自己查看源码后发现是:html 是通过自己的中间件生成,js通过webpack 中间件生成,这两者之间没有通信机制
现在的机制是: html 为静态文件,js 是每次请求都要编译一次
解决方案: 能否通过webpack 插件来处理html 并对其中的相对路径进行替换并添加md5 戳,将产出html
js文件输出到静态目录(可以是硬盘或内存)如果文件有更新,编译完毕后通过websocket 进行推送访问此地址的页面应该刷新了

mip-script 标签实现方案

在这次方案重新设计之前,mip-script 方案是由组件核心来实现的,开发者在页面里编写如下代码就可直接运行,方案和组件的沙盒方案一样,采用的黑盒方案,可以看这个 issue 的第一段 #5

<script type="application/mip-script">
MIP.watch('var_name', function () {
});
</script>

同样,会有黑名单频繁需要更新,且无法达到足够安全的程度,因此,mip-script 方案也需要重新设计。

#5 一样,也采用白盒方案

  • 实现 mip-script 自定义标签
  • mip-script 标签内置白名单列表
  • mip-script 分析自定义 js 的语法树,找到使用的全局变量
  • 如果这些全局变量不在白名单中,中止分析,不执行 js
  • 如果在白名单中,给这些全局变量加上 MIP.sandbox. 前缀,保证这些变量使用的是沙盒中的变量

mip-shell 翻页切换时闪动

背景:小说夜间模式切换时,页面会闪白。

问题1:如何控制#mip-page-loading-wrapper晚点消失,给iframe中的页面渲染的时间?

问题2:头部切换时样式反白一下,且宽度不沾满屏幕

loading

on="click:" 属性需要配合 cursor: pointer 才能生效,可以兼容下避免踩坑

<div on="click:xiaoshuo-shell.showShellFooter" class="click-cursor">
.click-cursor {cursor: pointer}

如果站长用了on="click:却没加on="click:属性会导致click不生效,不能触发eventAction。建议在click绑定事件时,默认加上一个class或style="cursor: pointer", 不用开发者自己写

附MIP1.0当时信息:
issue:mipengine/mip#307
PR: https://github.com/mipengine/mip/pull/306/files

(掉坑里两次了)

gesture 报错

RT,如果在子元素上绑定 touchstart 事件并 stopPropagation 阻止冒泡,而对 touchmove 之类的事件没有阻止外冒泡,会导致 js 报错

mip2内置通用方法和工具的文档补充

背景:
mip1中有部分通用工具函数但是目前没有被整理到mip2的文档中,
合作方开发的时候,阅读的是mip2.0的文档, 这部分会经常有疑惑,总是要找老版本的文档给他们看,这样会给他们带来一些开发上的困惑

这里建议把这部分通用工具方法的文档也写进mip2的开发文档里~

MIP2 组件沙盒方案

在这之前,我们确定的方案是 Context 方案,通过将组件的 script 包裹在我们的沙盒中,然后将全局的变量在这个沙盒中重新实现,达到屏蔽一些危险的变量和方法的目的,如下代码所示:

// sandbox.js
export let document = {
 // 不包含 createElement 方法
};

// component-a.js
let document = MIP.sandbox.document; // 重写 document 对象,编译时注入
export default new Vue({
  methods: {
    created() {
      let a = document.createElement('a') // 操作不被允许
    }
  }
});

后来发现这种方法很难控制, window 下的变量茫茫多,不仅有浏览器默认的变量,还有 MIP 里挂载到全局的变量,如:window._m, window.MIP_ROUTER 等等,这样的黑名单方案不可靠,经常需要升级,因此,我们将沙盒方案改为白盒方案只允许组件使用 window 中的某些变量和函数

白盒方案分为两步:

  • 开发者提交组件进行校验,校验全局变量是否有用到非白名单列表之内的变量或者函数
  • 运行时的沙盒,重写白名单列表的变量和函数,部分变量和函数改为 getter,不让用户修改,只能使用

MIP2 内外路由 API

#2 讨论,在百度搜索结果页环境下,我们需要在 MIP 中设计一个路由通信的 API,以实现路由的完整性。

在下文的讨论中,我将百度搜索结果页的 superframe 框架称为“外”框架,而 MIP 页面中负责路由机制的模块称为“内”框架。

路由通信是一个双方(有从内到外,也有从外到内)、单向(只发送通知,不处理返回)的通信机制,目前基于 iframe-shell 的 messenger 模块来做。以下是双方需要实现的事件:

内 -> 外 通知外部路由新增状态

事件名:pushState

事件参数:

  • url:一个需要 push 的 url。注意这里采用带 origin 的绝对 url,如 http://localhost:8080/path/to/page.html

内 -> 外 通知外部路由前进后退

事件名:historyNavigate

事件参数:

  • step:前进后退的步数。必须 >0 或者 <0。如 -1 表示后退。

内 -> 外 关闭服务

事件名:close

事件参数:

外 -> 内 通知路由变化

事件名:changeState

事件参数:

  • url:路由的目标 url
  • historyNavigateStep:如果 state 是由 historyNavigate 触发,会将 step 传入;否则为 0。如果用户点击浏览器上的前进后退,该变量也为 0。

UPDATE:移除了 state 参数;增加了 historyNavigateStep。

官方组件和第三方组件编写规范

越来越多的官方组件和第三方组件提交,为了可维护性和代码统一,因此需要对组件提出一些规范的要求,需要遵守的规范包括:

  • 目录规范
  • 文档规范
  • 代码规范
  • 命名规范

iOS 关闭 iframe 光标仍在

问题描述

iOS 打开 iframe 弹起软键盘后,不点击键盘上的“完成”,直接点击后退按钮切换页面,此时 iframe 隐藏,但是输入光标仍在,软键盘也不会收起
image

ios7下 m-bind数据 通过props传到组件中 变为null

<body>
      <mip-data>
          <script type="application/json">
              {
                  "payConfig":{}
              }
          </script>
      </mip-data>
    <div>
      <h2>First MIP page</h2>
      <h2>Add MIP components here</h2>
      <mip-example m-bind:pay-config="payConfig"></mip-example>
    </div>
     <script src="https://bos.nj.bpc.baidu.com/assets/mip/projects/mip.js"></script>
    <script src="/mip-example/mip-example.js"></script>
  </body>

mip-example.vue

export default {
  props: {
    payConfig: {
      type: Object,
      required: true
    }
  },
  watch: {
    payConfig (newVal, oldVal) {
      // watch it
      alert('new' + JSON.stringify(newVal))
      alert('old' + JSON.stringify(oldVal))
    }
  },
  mounted () {
    alert(JSON.stringify(this.payConfig))
    console.log('This is my first custom component !')
  }
}

ios7下共弹出2次,两次是被更新后弹出的

MIP1 改造 MIP2 迁移注意事项 [DRAFT]

MIP2 和 MIP1 大体上一样,但还是有一些点不太一样,需要在迁移内置组件的时候注意,并且遵循以下规范

以下规范还是 Draft,随时会更新

代码规范

  • 使用 es6 和 ES Module 编写组件
  • 全部代码需要通过 eslint 审核才能提交,遵循社区 standard 规范
  • 不到万不得已,不许使用 eslint-disable
  • Vue 的 template 部分需要遵守 Vue 的编码规范

JS 代码规范
Vue 规范

MIP1 需要改造的点

  • MIP 组件采用 customElement v1 标准 或者通过编写 Vue 来实现,参考文档 组件生命周期
  • MIP1 页面存在大量操作全局的操作,如 mip-nav-slidedown,作为一个浏览器的自定义标签,居然把事件代理到 document,customElement 只能负责自己的逻辑,尽量不要越界
  • MIP2 组件编写方式和 MIP 1 有很大变化,有两种方式,1. 通过 extends MIP.BaseElement,然后重写父类的方法来编写 MIP2 的组件 2. 编写 Vue 文件
  • MIP2 中将 isIframed 这个变量的含义改变了,判断是否在搜索结果页通过 MIP.standalone 来判断,代替具有歧义的 viewer.isIframed 变量
  • 不要写 let me = this 这样的语句,如遇到这种情况,请使用箭头函数

postMessage 数据格式问题

问题描述

目前根页面和各个子页面 <iframe> 通信使用 postMessage(),传递的数据对象是不需要开发者自己序列化的。MDN

但是 message 被地图接到之后,不加 try catch 直接当做字符串处理,就会报错。
image

z-index 规范

由于 MIP 页面里存在内置组件、公共组件、第三方组件,还有 mip-shell 和 MIP HTML,多数都有遮住全屏的 mask,因此 z-index 的管理就很有必要

  • mip-shell:z-index >= 1000
  • 内置组件和公共组件:z-index < 2000
  • 第三方组件:z-index < 1000
  • MIP HTML:z-index < 100

除 mip-shell 外,其他不设置最小值

iOS 滚动穿透问题

问题描述

iOS 开启弹性滚动后,容易滚动到下方容器。
可以在 iOS 下任意浏览器中访问 http://localhost:8080/examples/page/iframe/iframe.html
或者直接看这个 GIF:

解决方案

  • 页面初始状态就滚动 1px。
  • 监听 scroll 事件,滚动到顶时强制设置滚动距离为 1,即永远到不了最顶部。

Google AMP 也是这么做的,在 iOS 上打开 AMP 页面,滚动到顶触发 iOS 的弹性滚动,仔细观察页面会有一个轻微的不易察觉的向上滚动。

核心组件mip-img新增浏览体验需求

需求描述:
mip-img 中存在一个popup属性,可以控制点击图片采用弹出的形式浏览大图。但是这种浏览能够实现单张浏览。现在希望在这个基础上,能够扩展这个功能,点击图片弹出大图浏览时,可以进行左右滑动切换,浏览页面上其他配置了popup属性的图片。
一个具体的yi应用case如下图所示:
https://mip.putibaby.com/master_card?mcode=x6f3adb702b5c7a530aee9f6a3e4bf78f

image
image

MIP2核心代码目前不支持mustache的渲染,需要增加

【使用背景】

MIP组件迁移2.0,不改变站长使用组件的方式。也就是说,站长使用xx组件从1.0升级到2.0,只需要把v1/mip-xxx/mip-xxx.js 改成 v2/mip-xxx/mip-xxx.js, html部分不变

【问题】

目前站长是这样使用组件的:
image
组件获取配置的数据(mip1中直接选择,mip2中用props),template内容(不需要直接获取, 传递包含template的element,mip1中会使用queryselector选择),渲染成html后插入页面。
image

【需求】

由于不能改变组件用法,支持站长自己用mustache语法写template标签并渲染,需要mip2核心代码提供类似的templates供Mip2组件require.

移动端适配rem转换问题

目前组件在mip2 build过程中样式中的px并没有转换成rem,是否可以统一下转换规则,然后在打包过程中把这个功能添加上?

不支持同时暴露多个组件

背景 与 需求

迁移 mip 选项卡组件

目前的最佳实现<mip-vd-tabs/>为选项卡容器,<vd-tab/> 为选项卡,根据站长的需求,数量不一定。期望的结构如下

<!-- 这是 HTML 文件,非 Vue 单文件 -->

<mip-vd-tabs>
  <vd-tab name="标签1" :selected="true">
    <h2> MIP 2.0 </h2>
    <p> 内容11111 </p>
  </vd-tab>
  <vd-tab name="标签2">
    <p> 内容222222 </p>  
  </vd-tab>
  <vd-tab name="标签3">
    <p> 内容333333 </p>  
  </vd-tab>
  ...
</mip-vd-tabs>

效果如图:

2018-06-14 13_36_47

问题

组件<mip-vd-tabs/>导入<vd-tab/>,可正常注册并使用。但在 HTML 中(即站长使用时),子组件(<vd-tab/>)无法被解析。因为只导出了<mip-vd-tabs/>组件,<vd-tab/>是没有暴露出来的。

不支持暴露多个组件的其他方案

拿选项卡为例

  • DOM 操作: 用<slot/>插入 dom,然后在<mip-vd-tabs/>组件内, 选中元素、属性、遍历、赋值……�
<!-- 用 slot  -->

<mip-vd-tabs>
  <div name="标签1" class="active">
    <h2>MIP 2.0</h2>
    <p> 内容11111 </p>
  </div>
  <div name="标签2">
    <p> 内容222222 </p>  
  </div>
  <div name="标签3">
    <p> 内容333333 </p>  
  </div>
  ...
</mip-vd-tabs>
  • json数据
    • json 传输的内容限制太大
    • 站长改造升级不平滑
    • 选项卡内容不易自定义结构
<!-- 用 json  -->

<mip-vd-tabs>
  <script type="application/json">
    {
      "items": [{
          "name": "标签1",
          "content": "<h2>MIP 2.0</h2><p>内容11111</p>"
        },{
          "name": "标签2",
          "content": "<p>内容22222</p>"
        },{
          "name": "标签3",
          "content": "<p>内容33333</p>"
        },{
          ...
        }
      ]
    }
  </script>
</mip-vd-tabs>

需求场景

在 html 中任意插入子组件,升级成本低、结构直观、 子组件嵌套的内容自定义方便

  • 选项卡

    <mip-vd-tabs>
      <vd-tab>  </vd-tab>
      <vd-tab>  </vd-tab>
      <vd-tab>  </vd-tab>
    
      ...
    
    </mip-vd-tabs>
  • 焦点图

    <mip-carousel>
      <carousel-item>  </carousel-item>
      <carousel-item>  </carousel-item>
      <carousel-item>  </carousel-item>
    
      ...
    
    </mip-carousel>
  • ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.