Giter Club home page Giter Club logo

mip2's People

Contributors

brunoon avatar ccksfh avatar chenqiushi avatar clark-t avatar craigchencc avatar easonyq avatar html5david avatar huanghuiquan avatar huochezaodian avatar liuruoran88 avatar mip-workflow[bot] avatar miyapan avatar pengxing avatar ricardo-li avatar shawntu avatar tayqassqan avatar venyxiong avatar xiaoiver avatar yenshih avatar yuyutong avatar zoumiaojiang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mip2's Issues

不支持同时暴露多个组件

背景 与 需求

迁移 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>
  • ...

组件内使用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

其他信息

移动端适配rem转换问题

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

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次,两次是被更新后弹出的

iOS 关闭 iframe 光标仍在

问题描述

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

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。

[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
      • 需要双方开发联调

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 的预期,对性能会有很大的影响。

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内容随着点击自增

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

按代码命名规范在本地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

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 这样的语句,如遇到这种情况,请使用箭头函数

iOS 滚动穿透问题

问题描述

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

解决方案

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

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

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

(掉坑里两次了)

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

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

image

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

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

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

image
image

刷新返回,iframe依旧存在

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

操作如图:

2018-07-09 17_08_31

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

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

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

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 时,关闭掉所有组件的弹性滚动。
但是这样做的问题就是,内置的组件还好办,用户写的组件也会使用到弹性滚动,这就要求页面切换时需要通知所有的组件,让用户做这样的操作。

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

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

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

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 外,其他不设置最小值

全局共享组件方案

问题背景

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

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

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

大致思路

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

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

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

完善错误提示

  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 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 和所有组件

postMessage 数据格式问题

问题描述

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

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

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,不让用户修改,只能使用

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. 前缀,保证这些变量使用的是沙盒中的变量

gesture 报错

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

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

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

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

mip-shell 翻页切换时闪动

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

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

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

loading

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.