mafeifan

mafeifan 查看完整档案

郑州编辑  |  填写毕业院校  |  填写所在公司/组织 mafeifan.com 编辑
编辑

你自以为你了解的可能一无所知。

个人动态

mafeifan 赞了回答 · 3月3日

解决Laravel中Blade的Component如何使用。

这个就是相当于php的require_once功能,唯一不同的是你可以带入变量。

@component("所引用的文件的相对路径。以views文件夹为起点", ["变量名字"=>"变量值"])
@endcomponent

举个例子,在你的views文件架下面有2个文件:

views|
     |--template(文件夹)|
     |                 |--tpl.blade.php (这个是你打算引用的文件)
     |--main.blade.php

文件内容如下:

// tpl.blade.php
<div>
    name:<input type="text" value="{{$me}}">
</div>


// main.blade.php

@component("template.tpl", ["me"=>"凤舞九天"]) // 
@endcomponent

关注 3 回答 2

mafeifan 赞了文章 · 2月1日

使用React.memo()来优化函数组件的性能

原文链接: Improving Performance in React Functional Component using React.memo
原文作者: Chidume Nnamdi
译者: 进击的大葱
推荐理由: 本文讲述了开发React应用时如何使用shouldComponentUpdate生命周期函数以及PureComponent去避免类组件进行无用的重渲染,以及如何使用最新的React.memo API去优化函数组件的性能。

React核心开发团队一直都努力地让React变得更快。在React中可以用来优化组件性能的方法大概有以下几种:

  • 组件懒加载(React.lazy(...)和<Suspense />)
  • Pure Component
  • shouldComponentUpdate(...){...}生命周期函数

本文还会介绍React16.6加入的另外一个专门用来优化函数组件(Functional Component)性能的方法: React.memo

无用的渲染

组件是构成React视图的一个基本单元。有些组件会有自己本地的状态(state), 当它们的值由于用户的操作而发生改变时,组件就会重新渲染。在一个React应用中,一个组件可能会被频繁地进行渲染。这些渲染虽然有一小部分是必须的,不过大多数都是无用的,它们的存在会大大降低我们应用的性能。

看下面这个例子:

import React from 'react';

class TestC extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        }
    }
    
    componentWillUpdate(nextProps, nextState) {
        console.log('componentWillUpdate')
    }
    
    componentDidUpdate(prevProps, prevState) {
        console.log('componentDidUpdate')
        
    }
    
    render() {
        return (
            <div >
            {this.state.count}
            <button onClick={()=>this.setState({count: 1})}>Click Me</button>
            </div>
        );
    }
}
export default TestC;

TestC组件有一个本地状态count,它的初始值是0(state = {count: 0})。当我们点击Click Me按钮时,count的值被设置为1。这时候屏幕的数字将会由0变成1。当我们再次点击该按钮时,count的值还是1, 这时候TestC组件不应该被重新渲染,可是现实是这样的吗?

为了测试count重复设置相同的值组件会不会被重新渲染, 我为TestC组件添加了两个生命周期函数: componentWillUpdate和componentDidUpdate。componentWillUpdate方法在组件将要被重新渲染时被调用,而componentDidUpdate方法会在组件成功重渲染后被调用。

在浏览器中运行我们的代码,然后多次点击Click Me按钮,你可以看到以下输出:


我们可以看到'componentWillUpdate'和'componentWillUpdate'在每次我们点击完按钮后,都会在控制台输出来。所以即使count被设置相同的值,TestC组件还是会被重新渲染,这些就是所谓的无用渲染。

Pure Component/shouldComponentUpdate

为了避免React组件的无用渲染,我们可以实现自己的shouldComponentUpdate生命周期函数。

当React想要渲染一个组件的时候,它将会调用这个组件的shouldComponentUpdate函数, 这个函数会告诉它是不是真的要渲染这个组件。

如果我们的shouldComponentUpdate函数这样写:

shouldComponentUpdate(nextProps, nextState) {
    return true        
}

其中各个参数的含义是:

  • nextProps: 组件将会接收的下一个参数props
  • nextProps: 组件的下一个状态state

因为我们的shouldComponentUpdate函数一直返回true,这就告诉React,无论何种情况都要重新渲染该组件。

可是如果我们这么写:

shouldComponentUpdate(nextProps, nextState) {
    return false
}

因为这个方法的返回值是false,所以React永远都不会重新渲染我们的组件。

因此当你想要React重新渲染你的组件的时候,就在这个方法中返回true,否则返回false。现在让我们用shouldComponentUpdate重写之前的TestC组件:

import React from 'react';

class TestC extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        }
    }
    
    componentWillUpdate(nextProps, nextState) {
        console.log('componentWillUpdate')
    }
    
    componentDidUpdate(prevProps, prevState) {
        console.log('componentDidUpdate')
    }
    
    shouldComponentUpdate(nextProps, nextState) {
        if (this.state.count === nextState.count) {
            return false
        }
        return true
    }
    
    render() {
        return ( 
            <div> 
            { this.state.count } 
            <button onClick = {
                () => this.setState({ count: 1 }) }> Click Me </button> 
            </div>
        );
    }
}

export default TestC;

我们在TestC组件里添加了shouldComponentUpdate方法,判断如果现在状态的count和下一个状态的count一样时,我们返回false,这样React将不会进行组件的重新渲染,反之,如果它们两个的值不一样,就返回true,这样组件将会重新进行渲染。

再次在浏览器中测试我们的组件,刚开始的界面是这样的:

这时候,就算我们多次点击Click Me按钮,也只能看到两行输出:

componentWillUpdate
componentDidUpdate 

因为第二次点击Click Me按钮后count值一直是1,这样shouldComponentUpdate一直返回false,所以组件就不再被重新渲染了。

那么如何验证后面state的值发生改变,组件还是会被重新渲染呢?我们可以在浏览器的React DevTools插件中直接对TestC组件的状态进行更改。具体做法是, 在Chrome调试工具中点击React标签,在界面左边选中TestC组件,在界面的右边就可以看到其状态state中只有一个键count,且其值是1:


然后让我们点击count的值1,将其修改为2,然后按回车键:


你将会看到控制台有以下输出:

componentWillUpdate
componentDidUpdate
componentWillUpdate
componentDidUpdate

state的count被改变了,组件也被重新渲染了。

现在让我们使用另外一种方法PureComponent来对组件进行优化。

React在v15.5的时候引入了Pure Component组件。React在进行组件更新时,如果发现这个组件是一个PureComponent,它会将组件现在的state和props和其下一个state和props进行浅比较,如果它们的值没有变化,就不会进行更新。要想让你的组件成为Pure Component,只需要extends React.PureComponent即可。

让我们用PureComponent去改写一下我们的代码吧:

import React from 'react';

class TestC extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        }
    }
    
    componentWillUpdate(nextProps, nextState) {
        console.log('componentWillUpdate')
    }
    
    componentDidUpdate(prevProps, prevState) {
        console.log('componentDidUpdate')
    }
    
    /*shouldComponentUpdate(nextProps, nextState) {
        if (this.state.count === nextState.count) {
            return false
        }
        return true
    }*/
    
    render() {
        return ( 
            <div> 
            { this.state.count } 
            <button onClick = {
                () => this.setState({ count: 1 })
            }> Click Me </button> 
            </div >
        );
    }
}

export default TestC;

在上面的代码中,我将shouldComponentUpdate的代码注释掉了,因为React.PureComponent本身就帮我们实现了一样的功能。

改完代码后,我们刷新一下浏览器,然后多次点击Click Me按钮看组件被渲染了多少遍:


由上面的输出可知,我们的component只在state由0变为1时被重新渲染了,后面都没有进行渲染。

函数组件

上面我们探讨了如何使用PureComponentshouldComponentUpdate的方法优化类组件的性能。虽然类组件是React应用的主要组成部分,不过函数组件(Functional Component)同样可以被作为React组件使用。

function TestC(props) {
    return (
        <div>
            I am a functional component
        </div>
    )
}

对于函数组件,它们没有诸如state的东西去保存它们本地的状态(虽然在React Hooks中函数组件可以使用useState去使用状态), 所以我们不能像在类组件中使用shouldComponentUpdate等生命函数去控制函数组件的重渲染。当然,我们也不能使用extends React.PureComponent了,因为它压根就不是一个类。

要探讨解决方案,让我们先验证一下函数组件是不是也有和类组件一样的无用渲染的问题。

首先我们先将ES6的TestC类转换为一个函数组件:

import React from 'react';

const TestC = (props) => {
    console.log(`Rendering TestC :` props)
    return ( 
        <div>
            {props.count}
        </div>
    )
}
export default TestC;
// App.js
<TestC count={5} />

当上面的代码初次加载时,控制台的输出是:


同样,我们可以打开Chrome的调试工具,点击React标签然后选中TestC组件:


我们可以看到这个组件的参数值是5,让我们将这个值改为45, 这时候浏览器输出:


由于count的值改变了,所以该组件也被重新渲染了,控制台输出Object{count: 45},让我们重复设置count的值为45, 然后再看一下控制台的输出结果:


由输出结果可以看出,即使count的值保持不变,还是45, 该组件还是被重渲染了。

既然函数组件也有无用渲染的问题,我们如何对其进行优化呢?

解决方案: 使用React.memo()

React.memo(...)是React v16.6引进来的新属性。它的作用和React.PureComponent类似,是用来控制函数组件的重新渲染的。React.memo(...) 其实就是函数组件的React.PureComponent

如何使用React.memo(...)?

React.memo使用起来非常简单,假设你有以下的函数组件:

const Funcomponent = ()=> {
    return (
        <div>
            Hiya!! I am a Funtional component
        </div>
    )
}

我们只需将上面的Funcomponent作为参数传入React.memo中:

const Funcomponent = ()=> {
    return (
        <div>
            Hiya!! I am a Funtional component
        </div>
    )
}
const MemodFuncComponent = React.memo(FunComponent)

React.memo会返回一个纯化(purified)的组件MemoFuncComponent,这个组件将会在JSX标记中渲染出来。当组件的参数props和状态state发生改变时,React将会检查前一个状态和参数是否和下一个状态和参数是否相同,如果相同,组件将不会被渲染,如果不同,组件将会被重新渲染。

现在让我们在TestC组件上使用React.memo进行优化:

let TestC = (props) => {
    console.log('Rendering TestC :', props)
    return ( 
        <div>
        { props.count }
        </>
    )
}
TestC = React.memo(TestC);

打开浏览器重新加载我们的应用。然后打开Chrome调试工具,点击React标签,然后选中<Memo(TestC)>组件。

接着编辑一下props的值,将count改为89,我们将会看到我们的应用被重新渲染了:


然后重复设置count的值为89:


这里没有重新渲染!

这就是React.memo(...)这个函数牛X的地方!

在我们之前那个没用到React.memo(...)的例子中,count的重复设置会使组件进行重新渲染。可是我们用了React.memo后,该组件在传入的值不变的前提下是不会被重新渲染的。

结论

以下是几点总结:

  • React.PureComponent是银
  • React.memo(...)是金
  • React.PureComponent是给ES6的类组件使用的
  • React.memo(...)是给函数组件使用的
  • React.PureComponent减少ES6的类组件的无用渲染
  • React.memo(...)减少函数组件的无用渲染
  • 为函数组件提供优化是一个巨大的进步

我是进击的大葱,关注我的公众号,获取我分享的最新技术推送!

查看原文

赞 11 收藏 2 评论 1

mafeifan 关注了用户 · 1月11日

小俞 @yuyang040160120

对技术不懈追求

关注 228

mafeifan 赞了文章 · 1月5日

使用 Jenkins 自动部署 Docker 服务(一、Jenkins 搭建篇)

直接使用 Jenkins 官方的镜像一般会有两个问题导致不能正常自动部署基于 Docker 的服务。

存在的问题

  • 官方的镜像默认不是使用 root 账号,虽然 Jenkins 可以正常启动,但是因为没有权限导致不能向宿主机写文件
  • Jenkins 基于 Docker 搭建,虽然 Jenkins 同样可以正常启动,但不能在容器内部随意使用 Docker

准备工作

安装 docker、修改 docker 镜像仓库、安装 pip、安装 docker-compose
# 如果觉得麻烦可以用这个部署辅助工具自动完成
git clone https://github.com/kwkwc/dockerSH.git

# 进入工具目录并自动部署
cd dockerSH && ./deploy.sh

问题一 解决

重新创建镜像修改为 root 用户,安装 docker 依赖库(问题二解决)

Dockerfile

FROM jenkins/jenkins:2.137
MAINTAINER kwkw "kwkw@example.com"
ENV REFRESHED_AT 2018-08-13

USER root

RUN echo '' > /etc/apt/sources.list.d/jessie-backports.list \
  && echo "deb http://mirrors.aliyun.com/debian jessie main contrib non-free" > /etc/apt/sources.list \
  && echo "deb http://mirrors.aliyun.com/debian jessie-updates main contrib non-free" >> /etc/apt/sources.list \
  && echo "deb http://mirrors.aliyun.com/debian-security jessie/updates main contrib non-free" >> /etc/apt/sources.list

# 安装 docker 依赖库
RUN apt update && apt install -y libltdl7

创建新镜像

docker build -t kwkw/jenkins:2.137 .

问题二 解决

将宿主机的 Docker 程序挂载到 Jenkins 容器内部(宿主机环境为 Ubuntu 16.04,其他环境未测试)

docker-compose.yml

version: '2'
services:
  jenkins:
    restart: always
    image: kwkw/jenkins:2.137
    container_name: jenkins
    expose:
      - "8080"
      - "50000"
    ports:
      - "8080:8080"
      - "50000:50000"
    environment:
      JAVA_OPTS: "-Djava.awt.headless=true -Duser.timezone=Asia/Shanghai"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      # 将宿主机的 Docker 程序挂载到 Jenkins 容器内部
      - /usr/bin/docker:/usr/bin/docker:ro
      - ../data/jenkins:/var/jenkins_home

启动 Jenkins

docker-compose up -d

浏览器打开

http://127.0.0.1:8080

图片描述

初次使用需要填写密钥

请根据 docker-compose.yml 里面填写的挂载路径查找

图片描述

安装

一般我们选择安装推荐的插件,但是因为默认插件源在国外,速度非常慢而且安装失败率高,所以请自行查找特殊办法

图片描述

创建管理员用户

图片描述

搭建完成

图片描述

如果已经搭建好可以使用 Docker 的 Jenkins,请移步到这篇文章

使用 Jenkins 自动部署 Docker 服务(二、构建部署篇)

查看原文

赞 1 收藏 1 评论 0

mafeifan 赞了文章 · 2020-12-26

凹凸实验室的过去与未来

作者:凹凸曼

https://www.qq.com/video/m321...

凹凸实验室隶属于京东零售用户体验设计部(JDC),成立于 2015 年秋冬之交,诞生自深圳前海之滨,至今已走过 5 个年头,5 年的时光穿梭而过,凹凸实验室也不断发展壮大,从曾经专注前端的团队成长为如今涵盖前后端、全栈、算法、测试各类方向的全能型研发团队,工作模式也从传统的人力密集型研发转向创新型平台体系化研发,如今,凹凸的各类技术输出与沉淀在业界影响深远。

<iframe frameborder="0" data-original="https://v.qq.com/txp/iframe/player.html?vid=m3215ilu1ay" allowFullScreen="true"></iframe>

星火

2015 年,凹凸实验室的前身多终端研发部成立刚好一年,彼时的多终端研发部,虽然是一个拥有 20 多位开发人员的独立前端研发部门,但更多的是在支撑着公司内部的各种业务的研发,从微信手 Q 的购物业务到京东商城的营销活动、拍拍网,以及京东云的大改版,业务的类别五花八门,作为一个工线支持部门,每天在各类业务开发中穿插,协助各类业务需求的开发。

<div style="text-align: center; margin-bottom: 20px; color: #999">2015 加入凹凸实验室的同仁</div>

在此期间,部门也产生了很多精品业务,凭借着在 H5 动画方面的造诣,在京东内部小有名气,每到一些大促的时间节点都能收到很多的业务需求,这让团队开始在京东内部开始崭露头角。

<div style="text-align: center; margin-bottom: 20px;">H5 动画作品合集</div>

在这一阶段我们也产生了很多优秀的文章,不完全列举:

同时,在沉淀了大量精品的 H5 业务之后,我们也开始尝试打造一个可视化搭建工具 HiPage,通过拖拽搭建的方式就能将沉淀的 H5 动画元素组合出新的 H5 页面,实现快速上线,得到业务方的一阵惊叹。这是我们第一个颇具意义的技术产品,它既服务好了业务方,也满足了我们作为技术人员对技术的追求,同时也为我们埋下了关于团队方向思考的引子。

作为技术团队,我们一直在思考,我们所能做的是否仅仅只是服务好业务就够了?或者换一个角度,作为一个工线部门,我们除了努力把业务做好,还能再做些什么?

2015 年 9 月,一个燥热的周五晚上,在白石洲的鸡煲大排档里,关于上面的问题,关于团队的发展,关于团队的未来,团队里的几位大佬一边吃着鸡煲,一边激烈讨论。最终,留着一头飘逸长发的老黄掐灭手里的烟说道,“我们要做深圳最知名的前端团队”,在场的大家听罢后都陷入了沉思。

彼时落入大家心中的是一点点星火,似乎点亮一丝丝前方的光明,但是,星星之火,可以燎原。

一个月后,凹凸实验室正式成立,朝着 “要做深圳最知名的前端团队” 这个目标,团队的所有小伙伴都充满干劲。很快,我们和设计师通力合作,设计了沿用至今的团队 Logo。

同时也确定了我们的团队的理念:开放、开源,凹凸实验室的名字也来源于此,这一理念灌注在团队血液中,为之后的技术产品研发奠定基础。全新的团队官网也建立起来了,这个官网承载了不仅仅是团队小伙伴的技术文章,同时也是一个个关于技术梦想的追求。团队内也开始举办各类技术分享、编程马拉松,组织各小组的 Code Review,整个团队的技术氛围开始形成,凹凸如一个蹒跚习步的孩童,不断摸索,不断向前,磕磕碰碰,但不失朝气。

沉舟侧畔千帆过,病树前头万木春。

成长

回顾我们思考的疑问,我们在建设一个具有一定规模的前端团队的时候,其目的是否仅仅是服务好业务?

我们给出的答案是否定的。

正如凹凸灵魂导师老黄的文章《关于前端团队架构的思考》中所说的。

这个就好比一个人活着不能止于「有食可进有衣可穿」这种基础的物质条件,团队也同样有「精神层面」的内涵,具体如:

  • 影响力
  • 创新力
  • 技术视野

这些「精神层面」的东西看似很虚,但实际上会以另外一些形式正向的反馈给团队,间接影响团队服务业务的过程甚至结果。
建设团队在公司内外的影响力,可以营造团队的专业口碑,吸引优秀的专业人才主动加盟,而优秀的人才对于团队高效处理业务需求或研发需求的能力具有促进作用。

于是我们开始关注如何服务好业务的同时,提炼我们自己的技术产品,以业务为盾,以技术产品为剑,去打造我们梦想中的技术团队。

从业务中来,到业务中去

时间来到 2015 年末,此时凹凸承接的业务呈现暴涨的趋势,各类业务接踵而至,为了更好地应对业务增长带来的人力瓶颈,我们加速探索前端工程化,期望使用工程化的手段来解决前端模板化、组件化、自动化开发的问题,并推出了凹凸实验室第一个比较完善的开源产品 Athena。当然以现在的眼光来看 Athena 并不是一个优秀的产品,它的文档很糟糕,可扩展性几乎为 0,但在当时还是支撑起了团队大部分业务的开发,为业务研发增效提供源源不断的动力。请参见我们是如何做好前端工程化和静态资源管理

在打磨好工程化工具后,我们团队也终于迎来了非常重量级的业务——京东商城 PC 首页改版,此时 PC 首页依然承载着非常多的流量,改版的工作备受重视,而同时首页的复杂度特别是对性能、体验、稳定性的要求远远超出了我们过往的项目,秉承团队过往打造精品业务的理念,我们想要将 PC 首页这个项目做到全方位的极致。所以承接项目的小伙伴压力山大,在奔赴北京熬了一个多月后,项目终于顺利上线。当双 11 前夕,线上首页稳定顺畅地出现在办公室一个个显示器上的时候,我们难掩心中的激动,互相击掌庆祝彼此的胜利。具体请参见京东2016版首页改版前端总结

而在 PC 首页上线之后,为了进行更好地项目管理,同时保证项目流程自动、稳定地运行,我们开发了统一上线平台,可以进行项目管理、自动构建、构建后代码 diff 、项目操作日志以及一键发布和回滚等操作,极大地规范了项目流程管理工作,同时将项目的上线统一进行管控,大大降低了项目出现线上问题的可能性,开始为工程化补全串联研发流程的工作,也为后续我们开发一站式云端产研平台提供了宝贵经验。

但是工程化带来的提效,远远跟不上业务需求增加的速度,为了应对层出不穷的业务需求,17 年,我们在 HiPage 的基础之上,继续探索页面可视化搭建,期望通过建设高可用的可视化搭建引擎,配合海量的(想象中)模板和组件,产出一套 No Code 系统,让运营或者可以自己搭建页面直接上线。于是诞生了内部代号为「Atom」 的页面搭建平台,帮助内部快速上线了几千个页面,凹凸实验室在业务方那儿成为了“活儿好”的代名词。

同样是 17 年,随着京东商城业务的蓬勃发展,传统的设计师作图,业务方套模板生产广告图等物料的方式已然非常落后,生产效率低下极度依赖人力,同时也无法满足越来越多的个性化图片需求,为了应对这样的场景,我们开始打磨羚珑智能设计平台,通过海量图片模板和基于用户数据实时合图能力,解放了设计师的双手,也节约了业务方获得高质量图片的成本,让每个人都能轻松完成图片制作。

拥抱开源技术的初心

依然是 17 年,这一年我们在不断提升业务支持,围绕业务打磨技术产品的同时,在开源上我们也在不断奋进。这一年京东商城的前端主流技术栈还停留在 jQuery,而对于我们的业务来说已经无法忍受 jQuery 带来的研发效率低下的困境,我们开始探索新的技术栈,经过缜密的调研后,开始着手开发类 React 框架 Nerv,在内部业务经过一番验证后,开始在 GitHub 开源。凭借着当时团队大牛澈哥的出口转内销的推广策略,Nerv 开源第一天登上 GitHub 的 trending 榜,迅速斩获了上千 Star,这对于以开源为理念的我们来说,无疑是振奋人心的。请参见Nerv - 京东高性能前端框架

时间匆匆忙忙来到 18 年,彼时对于业务来说又迎来新的挑战,各类小程序平台层出不穷,为了应对业务拓展渠道的需求,我们开始探索多端统一开发解决方案,并迅速推出了 Taro,实现开发一次,同时生成多端应用,凭借着对 React 语法的独特支持和一天 3 个版本火线迭代的速度,Taro 成为诸多开发者喜爱的解决方案,帮助很多业务上线多端应用,Taro 也成为凹凸实验室的一张技术名片。请参见多端统一开发框架 - Taro

<div style="text-align: center; margin-bottom: 20px; color: #999">Taro stars 数破 2w 庆祝会</div>

向全栈迈进

而为了应对内部业务的数据服务请求,以及内部诸多的自研平台系统,凹凸实验室又自建了后端研发团队,为各大系统平台提供坚实的后端服务,为业务封装各类微服务方便调用,同时也在数次大促节点抗住了流量压力,团队的技术栈已经不再局限于前端了,开始向全栈模式转变。

平台化转型

18 年 19年,我们在不断对我们的各类工具系统进行打磨,做好能力储备。而与此同时,中台的概念兴起,我们团队也开始探索设计研发在中台领域的地位,开始打造公司的设计中台。我们深刻地认识到团队除了对人才的培养之外,更应该关注团队研发资产的沉淀,工具、平台系统、研发组件这些都是团队宝贵的研发资产。而除了不断进行研发能力建设和储备的同时,我们应该将这些已有的能力积木串联起来,成体系化地对外进行赋能,从而实现传统的人力密集型研发向创新型平台体系化研发的转变。

破局

2020 年,20 年代的第一年,从开年就注定是不寻常的一年。这一年我们也从宝安中心的龙光大厦搬到了前海内的卓越前海壹号。

今年,是凹凸实验室成立的第 5 年,5 年过去,团队的技术沉淀已然成型,曾经“开放、开源”的初心理念也未曾忘却。而在这一年我们对团队的能力积木做了一次重新的梳理,并思考如何进行体系化串联。

造积木

回顾过往,我们已经做了非常多的技术储能,并且团队的技术产品发展是全方位地进行,从智能设计到产品研发,基本每个领域都有我们探索的印记。

在图片和视频能力上,我们打造了 羚珑智能设计,可以通过海量图片模板和基于用户画像的智能算法实现图片和视频的智能生成。

在多端适配与框架能力上,我们打造了 Nerv,并从 Nerv 的中孵化出了 Taro, 可以实现一次开发,生成多端应用。

在可视化搭建能力上,我们从 HiPage 时代开始一步步探索, 到 Atom 时代可以搭建各类营销页面,再到现如今的羚珑可视化搭建,可以直接拖拽生成多端应用,并且覆盖营销、店铺等诸多场景。

在研发资产沉淀能力上,我们打造了 夸克资产平台,已经沉淀了海量的研发组件、图片、字体、动效等研发资产。

在数据可视化能力上,我们打造了 树懒平台,可以对业务统计和监控数据进行可视化查阅。

在服务端能力上,我们打造了专业的 服务端团队和系统,为各类业务和平台需求提供专业可靠的服务端能力支撑。

盖大厦

我们拥有诸多的能力积木,但是如果不能进行体系化串联,我们就不能进行产品化包装,以及对外进行技术赋能。

我们发现,纵观整个产研流程,将我们的能力积木放入之后,在某些环节依然有所缺失,例如,从设计师到研发,我们没有很好地进行对接,当有个性化需求需要开发以及需要进行研发组件沉淀时,我们依然需要人工将设计稿进行还原然后进行业务逻辑绑定开发,不仅仅是滞后我们的研发效率,同时对我们的设计研发体系来说也是一种断层,所以,今年我们进行了 设计稿一键生成代码 的探索,尝试对设计研发这一环节进行能力补全,同时提升我们的产研效率。

而同时,在研发流程上,我们只有 Taro 本身是远远不够的,Taro 只能解决代码开发本身和部分工程化的问题,只是研发流程中的一环,而研发流程则是包括开发、调试、测试、上线、统计监控完整的链路,为了打通研发流程全链路,同时统一研发环境,今年我们又开始进行了 一站式云端集成研发平台 即 Cloud IDE 的探索,尝试将业务研发、资产沉淀搬到云端,仿佛在走一遍统一上线平台的老路,但却是完全不一样的风景。

设计稿一键生成代码一站式云端集成研发平台 成为了补全产研体系化建设的两块拼图,让产研流程可以成体系化进行串联。

目前我们现有的产研流程,首先设计稿通过智能代码能力一键生成可二次开发的代码,代码导入 Cloud IDE 中进行开发调整,最后可以通过 Taro 生成多端应用,这是一个线性的过程,而同时,在此过程中也能快速沉淀设计研发资产,设计研发资产也能作为智能代码智能识别的样本数据,沉淀设计资产又可以提供给可视化搭建平台,直接搭建出多端应用,同时羚珑智能设计将为应用提供个性化的图片和视频,丰富应用的运营能力。由此,实现了一个良性的产研闭环。

目前,我们整体的能力全景图如下。

启下

立足业务,技术储能是过去五年凹凸实验室的主题。

而智能化设计研发体系将绘制凹凸实验室未来 5 年的技术产品的梦想画卷。

接下来我们将通过【凹凸技术揭秘】系列文章,为大家分享、剖析凹凸的关键技术布局,希望能为业界带来更多的思想碰撞,也希望能吸引更多有志青年加入我们,共同实现关于技术关于产品关于团队的梦想。

年光似鸟翩翩过,世事如棋局局新,唯有不忘初心,坚守本心,方能乘风破浪,济沧海。

其他

感谢一直关注凹凸实验室的读者,为了提供更优质的内容,希望您能抽出几分钟时间,完成一个小调查,明年凹凸公众号的内容由你决定。点击直达

加入凹凸实验室开放、开源、专业、有爱、有梦的大家庭?点击直达

还没有关注「凹凸实验室」的读者们,关注我们吧,我们一个月只有 4 次推送机会,我们很珍惜每一次推送,不会让你失望的。微信搜索「凹凸实验室」关注即可。


欢迎关注凹凸实验室博客:aotu.io

或者关注凹凸实验室公众号(AOTULabs),不定时推送文章。

查看原文

赞 6 收藏 1 评论 0

mafeifan 关注了专栏 · 2020-12-25

K8S生态

Container, Docker, Go, Kubernetes, Python, Vim; 微信公众号: MoeLove

关注 10587

mafeifan 关注了用户 · 2020-12-25

张晋涛 @moelove

微信公众号:MoeLove
Container, Docker, Go, Kubernetes, Python, Vim;

为了准确筛选信息,可使用付费问答 https://segmentfault.com/pay/...

关注 193

mafeifan 赞了文章 · 2020-12-25

Docker 新发布的 hub-tool 可直接查看账户配额

Docker Desktop v3.0 已于前两周正式发布,从这个版本起,Docker 官方承诺每次的更新将以增量更新的方式来提供,以便减少下载包的体积,提升效率。

除了将 Docker Engine 更新至 v20.10.0 外,也对其他的依赖做了更新,如下图:

image

最吸引我的是本次新增的 Docker Hub Tool v0.2.0 ,它是 Docker 官方提供的 Docker Hub CLI 工具,具备管理 DockerHub 上的帐号,镜像等相关资源的能力。

以下,我来为你介绍下 Hub Tool 的主要功能。

(MoeLove) ➜  hub-tool -h
A tool to manage your Docker Hub images

Usage:
  hub-tool
  hub-tool [command]

Available Commands:
  account     Manage your account
  help        Help about any command
  login       Login to the Hub
  logout      Logout of the Hub
  org         Manage organizations
  repo        Manage repositories
  tag         Manage tags
  token       Manage Personal Access Tokens
  version     Version information about this tool

Flags:
  -h, --help      help for hub-tool
      --verbose   Print logs
      --version   Display the version of this tool

Use "hub-tool [command] --help" for more information about a command.

从一级菜单来看,主要功能包括:

  • 登录/登出 DockerHub;
  • 账户相关管理功能;
  • 组织相关管理功能;
  • 仓库和 tag 的相关管理功能;
  • token 的相关管理功能;

当前我使用的是最新版本 v0.2.0 。

(MoeLove) ➜  hub-tool version
Version:    v0.2.0
Git commit: 0edf43ac9091e7cac892cbc4cbc6efbafb665aa4

登录/退出

登录/退出只要执行 hub-tool login 或者 hub-tool logout 即可。

但这里需要注意的是 Hub Tool 并没有使用 Docker Desktop 默认的用户凭证,也就是说,即使你在 Docker Desktop 中已经登录了帐号,你同样还是需要再次在终端下执行 login 操作。

关于为何没有共用用户凭证的问题,我跟 Docker Inc. 的产品经理聊过,是因为当前 Hub Tool 还是一个独立的 CLI 工具,并没有与 docker CLI 进行集成,也暂时没想好要如何集成。等真正要集成进 docker CLI 的时候,就会直接共用用户凭证了。

(MoeLove) ➜  hub-tool login
Username: moelove
Password:

账户管理

账户管理的两个功能:

  • 查看账户信息;
  • 查看当前账户下的流量限制 , 这是我个人觉得比较有用的一个功能;
(MoeLove) ➜  hub-tool account
Manage your account

Usage:
  hub-tool account
  hub-tool account [command]

Available Commands:
  info          Print the account information
  rate-limiting Print the rate limiting information

Flags:
  -h, --help   help for account

Global Flags:
      --verbose   Print logs

Use "hub-tool account [command] --help" for more information about a command.
(MoeLove) ➜  hub-tool account rate-limiting
Limit:     200, 6 hours window
Remaining: 200, 6 hours window
(MoeLove) ➜  hub-tool account info
Username:    moelove.info
Full name:    Jintao Zhang
Company:
Location:
Joined:        6 years ago
Plan:        free
Limits:
  Seats:        1
  Private repositories:    1
  Parallel builds:    1
  Collaborators:    unlimited
  Teams:        unlimited

组织管理

可以看到,hub-tool org 的功能就是展示一些相关信息了。

(MoeLove) ➜  hub-tool org
Manage organizations

Usage:
  hub-tool org
  hub-tool org [command]

Available Commands:
  ls          List all the organizations
  members     List all the members in an organization
  teams       List all the teams in an organization

Flags:
  -h, --help   help for org

Global Flags:
      --verbose   Print logs

Use "hub-tool org [command] --help" for more information about a command.
(MoeLove) ➜  hub-tool org ls
NAMESPACE    NAME    MY ROLE    TEAMS    MEMBERS

仓库和 tag 管理

由于这两个都和镜像有直接的关系,我就聚合到一起介绍了。

  • 对 repo 的查询和删除功能:
(MoeLove) ➜  hub-tool repo -h
Manage repositories

Usage:
  hub-tool repo
  hub-tool repo [command]

Available Commands:
  ls          List all the repositories from your account or an organization
  rm          Delete a repository

Flags:
  -h, --help   help for repo

Global Flags:
      --verbose   Print logs

Use "hub-tool repo [command] --help" for more information about a command.
(MoeLove) ➜  hub-tool repo ls
REPOSITORY                             DESCRIPTION       LAST UPDATE      PULLS    STARS    PRIVATE
taobeier/saythx-work                                     2 years ago      56989    0        false
...
(MoeLove) ➜  hub-tool repo ls -h
List all the repositories from your account or an organization

Usage:
  hub-tool repo ls [ORGANIZATION]

Aliases:
  ls, list

Flags:
      --all             Fetch all available repositories
      --format string   Print values using a custom format ("json")
  -h, --help            help for ls

Global Flags:
      --verbose   Print logs
  • 对 tag 的列表,查询,查看详细等功能。 这里 可以看到 tag 最近一次的 Push/Pull 操作,如果明年 Docker 开始实行镜像保留策略的话,我建议你关注一下
(MoeLove) ➜  hub-tool tag
Manage tags

Usage:
  hub-tool tag [flags]
  hub-tool tag [command]

Available Commands:
  inspect     Show the details of an image in the registry
  ls          List all the images in a repository
  rm          Delete a tag in a repository

Flags:
  -h, --help   help for tag

Global Flags:
      --verbose   Print logs

Use "hub-tool tag [command] --help" for more information about a command.
See 'hub-tool tag ls --help'.

Usage:  hub-tool tag ls [OPTION] REPOSITORY

List all the images in a repository
(MoeLove) ➜  hub-tool tag ls taobeier/saythx-work
TAG                            DIGEST                                                                     STATUS    LAST UPDATE    LAST PUSHED    LAST PULLED    SIZE
taobeier/saythx-work:latest    sha256:3133a607d062dd3a8b46f38c8271099c258f5e59cecd652bebddf6e15789cb32    active    2 years ago    2 years        6 days         52.94MB
taobeier/saythx-work:1.0       sha256:3133a607d062dd3a8b46f38c8271099c258f5e59cecd652bebddf6e15789cb32    active    2 years ago    2 years        6 days         52.94MB

Token 相关管理功能

对个人 Token 的创建/删除,激活/失效,列表,查询详细等功能。

(MoeLove) ➜  hub-tool token -h
Manage Personal Access Tokens

Usage:
  hub-tool token [flags]
  hub-tool token [command]

Available Commands:
  activate    Activate a Personal Access Token
  create      Create a Personal Access Token
  deactivate  Deactivate a Personal Access Token
  inspect     Inspect a Personal Access Token
  ls          List all the Personal Access Tokens
  rm          Delete a Personal Access Token

Flags:
  -h, --help   help for token

Global Flags:
      --verbose   Print logs

Use "hub-tool token [command] --help" for more information about a command.
(MoeLove) ➜  hub-tool token ls
DESCRIPTION               UUID                                    LAST USED       CREATED      ACTIVE
test-docker-token         xxxxxxxx-xxxx-xxxx-xxxx-moelove.info    9 months ago    9 months     true
(MoeLove) ➜  hub-tool token inspect xxxxxxxx-xxxx-xxxx-xxxx-moelove.info
Token:
UUID:    xxxxxxxx-xxxx-xxxx-xxxx-moelove.info
Description:    test-docker-token
Is Active:    true
Created:    9 months ago
Last Used:    9 months ago
Creator User Agent:    Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.4103.116 Safari/537.36
Creator IP:    100.000.000.00
Generated:    By user via Web UI

总结

以上就是关于 Docker 新发布的 Hub Tool 的全部功能介绍了。
当前它是随着 Docker Desktop 一起发行的,所以 Linux 下暂时没有。但是计划会尽快开源。敬请期待!


欢迎订阅我的文章公众号【MoeLove】

TheMoeLove

查看原文

赞 3 收藏 0 评论 0

mafeifan 关注了用户 · 2020-12-23

zangeci @zangeci

关注 28

mafeifan 赞了回答 · 2020-12-23

解决数组分组条件汇总处理

var data = [
  ['CHN001', 'CHN001014', true ],
  ['CHN002', 'CHN002001', true ],
  ['CHN002', 'CHN002001', false ],
  ['CHN002', 'CHN002002', true ],
  ['CHN002', 'CHN002002', false ],
  ['CHN002', 'CHN002003', true ],
  ['CHN002', 'CHN002004', true ],
  ['CHN002', 'CHN002005', true ],
  ['CHN002', 'CHN002007', false ],
  ['CHN002', 'CHN002008', false ],
  ['CHN003', 'CHN003001', true ],
  ['CHN003', 'CHN003001', false ],
  ['CHN005', 'CHN005001', true ],
  ['CHN005', 'CHN005001', false ],
  ['CHN005', 'CHN005002', true ],
  ['CHN005', 'CHN005003', true ],
  ['CHN005', 'CHN005004', true ],
  ['CHN007', 'CHN007001', true ],
  ['CHN007', 'CHN007001', false ],
  ['CHN007', 'CHN007001', false ],
  ['CHN007', 'CHN007002', true ],
  ['CHN007', 'CHN007003', true ],
  ['CHN007', 'CHN007003', false ],
  ['CHN007', 'CHN007004', true ],
  ['CHN007', 'CHN007004', true ],
  ['CHN007', 'CHN007004', false ],
  ['CHN007', 'CHN007007', true ],
  ['CHN007', 'CHN007008', true ],
  ['CHN007', 'CHN007009', false ]
]

function computeScore(list) {
  const results = list.reduce((res, [no,code,result]) => {
    res[no] = res[no]||{};
    res[no][code] = (typeof res[no][code] == 'undefined' ? true : res[no][code])&&result;
    return res;
  }, {});
  
  return Object.keys(results).reduce((res,key) => {
    res[key] = Object.values(results[key]).reduce((acc,bol) => acc+bol,0)
    return res;
  }, {})
}
computeScore(data)

关注 2 回答 1

认证与成就

  • 获得 85 次点赞
  • 获得 61 枚徽章 获得 4 枚金徽章, 获得 18 枚银徽章, 获得 39 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2014-08-07
个人主页被 1.6k 人浏览