Ant Design

一个服务于企业级产品的设计体系,基于『确定』和『自然』的设计价值观和模块化的解决方案,让设计者专注于更好的用户体验。

官网: https://ant.design/index-cn
文档: https://ant.design/docs/react/introduce-cn

Ant Design of React
这里是 Ant Design 的 React 实现,开发和服务于企业级后台产品。

特性

  • 提炼自企业级中后台产品的交互语言和视觉风格。
  • 开箱即用的高质量 React 组件。
  • 使用 TypeScript 构建,提供完整的类型定义文件。
  • 全链路开发和设计工具体系。

支持环境

  • 现代浏览器和 IE9 及以上(需要 polyfills)。
  • 支持服务端渲染。
  • Electron

安装

使用 npm 或 yarn 安装#
我们推荐使用 npm 或 yarn 的方式进行开发,不仅可在开发环境轻松调试,也可放心地在生产环境打包部署使用,享受整个生态圈和工具链带来的诸多好处。

  1. $ npm install antd --save
  2. $ yarn add antd

如果你的网络环境不佳,推荐使用 cnpm。

浏览器引入

在浏览器中使用 script 和 link 标签直接引入文件,并使用全局变量 antd。

我们在 npm 发布包内的 antd/dist 目录下提供了 antd.js antd.css 以及 antd.min.js antd.min.css。你也可以通过UNPKG 进行下载。

强烈不推荐使用已构建文件,这样无法按需加载,而且难以获得底层依赖模块的 bug 快速修复支持。
注意:3.0 之后引入 antd.js 前你需要自行引入 moment。

示例

  1. import { DatePicker } from 'antd';
  2. ReactDOM.render(<DatePicker />, mountNode);

引入样式:

  1. import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'

按需加载

下面两种方式都可以只加载用到的组件。

  • 使用 babel-plugin-import(推荐)。

    1. // .babelrc or babel-loader option
    2. {
    3. "plugins": [
    4. ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] // `style: true` 会加载 less 文件
    5. ]
    6. }

    注意:webpack 1 无需设置 libraryDirectory。

    然后只需从 antd 引入模块即可,无需单独引入样式。等同于下面手动引入的方式。

    1. // babel-plugin-import 会帮助你加载 JS 和 CSS
    2. import { DatePicker } from 'antd';
  • 手动引入

    1. import DatePicker from 'antd/lib/date-picker'; // 加载 JS
    2. import 'antd/lib/date-picker/style/css'; // 加载 CSS
    3. // import 'antd/lib/date-picker/style'; // 加载 LESS

当你不再自我设限时,全世界都会为你让路

你不是输给命运,而是输给自己。

——江晚舟

1.你不试试怎么知道你做不到

我是一个从小就很胆怯的人,总觉得自己什么都做不到。

记得大学班里组织跳大绳接力比赛,我下意识的就是逃避,因为从小就觉得跳大绳是一件极其危险的事,绳子那么粗,甩到人得多疼啊,无奈避无可避,只能硬着头皮上了。

真的是将近10次都是半途而废,真的害怕!后来在同学的鼓励下成功跳了一个,那种惧怕的心理就像太阳出来后的露珠,完全消散了,我笑着说:“嗯,感觉挺好玩的。”

面对害怕的事物,心里总是给自己设限——做不到的,但面对并战胜后才发现,真的没有想的那么难。

所以外教课上被问到,“你怎样处理自己十分害怕的事物?”

“Face it.(面对它)”,我毫不犹豫的回答。

人这一辈子,老来总有遗憾,没有跟爱的人表白,没有做自己喜欢做的事,去自己喜欢的地方,甚至连骂一句讨厌的人都没做到……

其实,说白了,就是自我设限,不愿意相信自己了。

然而,害怕是本能,失败受挫也是常态,但若因此就告诉自己“你不行,你做不到的”,这跟胆小鬼又有什么区别?

自我设限,只会让自己错过人生的更多种可能。

当你不再自我设限时,全世界都会为你让路

2.年龄设限,丢掉的是你的运气

中国人自古以来提倡,什么年龄做什么事,所以若是年龄太小,或是年龄过大,都变成一种束缚,觉得不能做不符合年龄的事。

记得奶奶讲过这样一个故事:

月娘是一个非常不幸的人。父母在她年幼的时候就把她抛弃了,后来为了活下去找了一个人嫁了,可那人却生性暴戾,没让月娘过过一天好日子,后来那人死于意外,对月娘来说虽是解脱,可也意味着她要自己拉扯3个孩子长大。

很多人劝月娘改嫁,可月娘说:“都这么大了,还想这些做什么,平平安安的我就谢天谢地了。”

在那个时代,很多人受着封建思想的荼毒,包括到现在,这也是很多人告诫自己的理由。

“你还小,什么都不懂”“哎,我都这么大了,还能干什么”……错误的年龄观,耽误了一生的好运。

其实,年龄虽然有所影响,但绝对不能限制任何事。

摩西奶奶是闻名全球的风俗画画家,可知道她的人都知道,她是77岁才开始作画的,正如她所说“任何年龄的人都可以作画。”

不管幸与不幸,都不要为自己的人生设限,以免阻挡了生命的阳光。

不被自己年龄限制的人,生命的阳光总是热烈又充沛。

当你不再自我设限时,全世界都会为你让路

3.感情设限,没有人会喜欢你退缩逃避

“我很喜欢他,但是我觉得自己配不上他”,表妹丹丹和我谈心时说。

“他长得帅家里也有钱,又有很多人喜欢;而我性格长相都很普通,还是农村户口,真的站在他面前都觉得很自卑。”

我后来推荐她去看一本小说《我不喜欢这个世界我只喜欢你》,真人真事境况相同,但在这个故事里,我只看到了幸福和甜蜜。

现在的人谈起爱情,下意识的想到婚姻、房子、长相、家室、工作,然后有了诸多人眼里的不配。

“那个人长得丑,配不上某某女明星”

“那个人灰姑娘,配不上高富帅的他”

“王祖蓝长得矮,配不上他老婆”

……

可这样的不配,未免太过肤浅和幼稚,真正成熟的感情,是寻求精神上的契合,而非物质外表上的相配。

就像《恶作剧之吻》中的袁湘琴和江直树,很多人包括他们自己都觉得两人不配,甚至一度虐恋,但还不是以幸福收场。

其实啊,感情里唯一的不配,是“他不喜欢你!”

面对喜欢的人却因“不配”而选择退缩,不过是把感情设限了。但感情,无非就是你情我愿,哪有那么多条条框框?

当你不再自我设限时,全世界都会为你让路

4.能力设限,不敢想不敢试等于失败

其实,最常见的还是我们对自己的能力设限。

就像蒂娜·齐莉格说的:

我们从职业、收入、居所、开的车、教育,甚至是占卜等多个方面自我设限。所有限制都把我们禁锢在某种固有假定中,这些假定有自己是谁,我能干什么。
因为自己是一个普通人,能力普通,所以从来不敢尝试超出自己认定的能力以外的事,更不敢奢望过不平凡的生活。

可是这世界上这么多的成功人士,又有多少是天生我才?多少是靠着不对自己设限拥有了不凡的人生?

提到蔡依林大家并不陌生,不是天才,却靠着自己的努力达到了和天才一样的高度。

从一个四肢不协调的舞蹈盲,到家喻户晓的亚洲舞娘。从瑜伽到艺术体操,再到现代舞。她在刷新着自己的极限,也在刷新着人们的认知。

她跟自己说“努力就一定会成功,如果我失败了,那一定是我不够努力。”

而我们更喜欢说的是“很多事情努力也没有办法。”所以依旧平庸。

法齐娅·库菲在《我不要你死于一事无成》中说:

把目标放高,你永远无法估计一个人的爆发力能达到什么程度,如果一开始就已经设限,那么,这一辈子,你很可能就没有了爆发的欲望,何来高度深度宽度可言?
就好比考试时我们给自己设立目标是60分,那你要超过及格分太难了,但目标若是90分,及格自然不在话下。

很多时候,我们人生的失败,都源于自我设限。

当你不再自我设限时,全世界都会为你让路

知乎上有一个高赞问答:

问:“你有什么相见恨晚的知识想推荐给年轻人?”

答:“做你害怕做的事情。然后你会发现,不过如此。”

正如尼克·胡哲在《人生不设限》中说的:

人生最可悲的并非失去四肢,而是没有生存希望及目标!人们经常埋怨什么也做不来,但如果我们只记挂着想拥有或欠缺的东西,而不去珍惜所拥有的,那根本改变不了问题。真正改变命运的,并不是我们的机遇,而是我们的态度。
现实生活中,很多人在遇到无能为力或者稍有难度的事情,就会对自己说,你就这点能力,不要异想天开了,于是默默无闻了一辈子。

这就像跳蚤变成“走蚤”一样:并不是失去了跳跃的能力,而是一次次受挫后习惯了麻木了。入口的玻璃罩已经不在了,但是却罩在了它的心上,跳蚤没有了“再跳一次”的勇气。

而我们有多少人,在自己的心上罩了一个无形的玻璃罩,一次次的跟自己说不可能?

自我设限的真相就是:一次失败,终生认输。

你不是输给命运,而是输给自己。

关于时间

一渺秒

  即百亿亿分之一秒,阿托秒(attosecond)
  科学家是用渺秒来对瞬时事件进行计时的。
  研究人员已经用稳定的高速激光产生了仅持续250渺秒的光脉冲。尽管这一时间间隔短得无法想像,但是和普朗克时间相比还是很长的。普朗克时间大约为10^-25渺秒,被认为是可能持续的最短时间。

一飞秒

  即千万亿分之一秒
  一个分子里的一个原子完成一次典型振动需要10到100飞秒。完成快速化学反应通常需要数百飞秒。光与视网膜上色素的相互作用(产生视觉的过程)约需200飞秒。

一皮秒

  即万亿分之一秒
  最快晶体管的运行以皮秒计。一种高能加速器产生的罕见亚原子粒子b夸克在衰变之前可存在1皮秒。室温下水分子间氢键的平均存在时间是3皮秒。

一纳秒

  即十亿分之一秒
  光在真空中一纳秒仅传播30厘米(不足一个步长)。个人电脑的微处理器执行一道指令(如将两数相加)约需2至4纳秒。另一种罕见的亚原子粒子K介子的存在时间为12纳秒。

一微秒

  即百万分之一秒
  光在这个时间里可以传播300米,大约是3个足球场的长度,但是海平面上的声波只能传播1/3毫米。高速的商业频闪仪闪烁一次大约持续1微秒。一筒炸药在它的引线烧完之后大约24微秒开始爆炸。

一毫秒

  即千分之一秒
  典型照相机的最短曝光时间为一毫秒。一只家蝇每三毫秒扇一次翅膀;蜜蜂则每五毫秒扇一次。由于月亮绕地球的轨道逐渐变宽,它绕一圈所需的时间每年长两毫秒。在计算机科学中,10毫秒的间隔称为一个jiffy。

一分秒

  寓言中常说的“一眨眼”的时间就是十分之一秒。人类的耳朵需要十分之一秒的时间来分辨发声回声。远离太阳系飞行的飞行器旅行者1号,每十分之一秒飞离太阳约两公里。蜂雀在这个时间里可以拍打7次翅膀。为A到中C定调的调音叉振动4次。

一秒

  健康人的一次心跳大约持续一秒。美国人平均每一秒吃掉350块比萨饼。地球每一秒绕太阳旋转30公里,而与此同时太阳在银河系中穿行274公里。一秒钟不足以使月光到达地球(需1.3秒)。传统意义上,一秒是24分之一天的60分之一的60分之一,但是科学家给出了一个更精确的定义:铯133原子基态超精细能阶跃迁的9 192 631 770个周期所持续的时间,称为一秒。

php高效率计算文件行数

  1. /*
  2. * 高效率计算文件行数
  3. */
  4. function count_line($file)
  5. {
  6. $fp = fopen($file, "r");
  7. $i = 0;
  8. while (!feof($fp)) {
  9. // 每次读取2M
  10. if ($data = fread($fp, 1024 * 1024 * 2)) {
  11. // 计算读取到的行数
  12. $num = substr_count($data, "\n");
  13. $i += $num;
  14. }
  15. }
  16. fclose($fp);
  17. return $i +1;
  18. }
  19. $count = count_line($filename);
  20. echo $count;

自动生成免费 letsencrypt ssl 证书的全自动 nginx 反向代理 docker 镜像

转载, 原文地址: https://github.com/Neilpang/nginx-proxy/wiki
本文是介绍一个 docker 镜像的, 可以全自动实现反向代理, 并自动配置 ssl 证书.

这里主要说两个问题:

  1. 对于只有一个公网 ip 的 docker host, 如果想在其中跑多个 web server 就有问题了, 因为 80 端口只能分配给一个 docker container. 怎么办, 一个好办法就是开一个反向代理. 把 80 端口分配给反向代理, 然后反向代理再根据域名分发给不同的内部 docker container. 看起来很简单对吧, 这没什么. 但是你一旦关闭重启内部的 web server container, 它的内部 ip 可能就会发生改变, 此时你不得不修改反向代理的配置, 并重新加载. 这些工作能不能自动完成 ?
  2. 第二个问题, 反向代理上能不能自动配置 ssl 证书. letsencrypt 不是有免费证书吗?
    很好, 这两个问题的答案都是肯定的. 分三步来说. 不用担心, 非常简单, 本文不会很长, 你会在几分钟只内完成.

1. 先说第一个问题. 自动配置 docker 反向代理.

用 nginx 镜像做一个反向代理, 并且能根据当前 docker host 的 container 的变化, 自动配置反向代理的 ip 和端口.

这个问题其实早就有人解决了, 比如这两个项目:

使用 docker api 可以自动监控 container 变化, 根据模板生成配置文件.

https://github.com/jwilder/docker-gen

作者另外的一个项目, 专门实现了 nginx 的反向代理.

https://github.com/jwilder/nginx-proxy

如果你只需要反向代理, 并不需要自动配置 ssl 的话, 本文你读到这里就可以了.

2. 为 nginx 反向代理自动配置 ssl

为了自动配置 ssl, 我 fork 了上面的项目, 并做了少量修改, 加入了 acme.sh 的支持, 可以实现全自动 配置 ssl 证书.

https://github.com/Neilpang/nginx-proxy

并且已经在 docker hub 上发布了 trusted build:

docker pul neilpang/nginx-proxy

3. 第三步, 快速上手

首先在运行反向代理:

  1. mkdir proxy
  2. cd proxy
  3. docker run \
  4. --rm -it -d \
  5. -p 80:80 \
  6. -p 443:443 \
  7. -v /var/run/docker.sock:/tmp/docker.sock:ro \
  8. -v $(pwd)/certs:/etc/nginx/certs \
  9. -v $(pwd)/acme:/acmecerts \
  10. neilpang/nginx-proxy

稍微解释一下: 运行一个反向代理 并把 80 和 443 端口都分配给它. 并且把 /var/run/docker.sock 传递给 container , 这是 docker api 操作文件.

现在可以运行你的 web server container 了:
先把你的一个域名解析到 docker host ip, 例如: example.com

然后, 我们随便启动一个 webserver:

  1. docker run --rm -itd \
  2. -e VIRTUAL_HOST=example.com \
  3. --name test \
  4. httpd

注意到上面的参数了吗: -e VIRTUAL_HOST=example.com

我们在上一步中运行的 neilpang/nginx-proxy 会自动监控这个 host 上的每一个 container 的变化. 如果发现有 VIRTUAL_HOST 变量, 就会自动配置反向代理.

试试访问你的域名:

http://example.com
现在给这个反向代理配置 ssl:

在此之前,请确保你的域名已经指向了主机 ip, 因为 letsencrypt 证书需要验证域名所有权.

  1. docker kill test
  2. docker run --rm -itd \
  3. -e VIRTUAL_HOST=example.com \
  4. -e ENABLE_ACME=true \
  5. --name test \
  6. httpd

注意到不同了吗, 仅仅多了一个变量: ENABLE_ACME=true

大概几十秒之后, ssl 证书就会自动配置成功了.

访问试试:

https://example.com
注意, 这个证书是自动配置的, 今后会自动更新, 让你完全忘了它的存在.

有多个域名绑定: 用逗号分隔.

  1. docker kill test
  2. docker run --rm -it -d \
  3. -e VIRTUAL_HOST=example.com,www.example.com \
  4. -e ENABLE_ACME=true \
  5. --name test \
  6. httpd

另外, 这个镜像还有一个好处就是已经配置了从 http 跳转到 https, 并且自动启用 http 2.0

反代 非 80 的自定义端口:
加上: VIRTUAL_PORT=8080 即可

  1. docker run --rm -itd \
  2. -e VIRTUAL_HOST=example.com,www.example.com \
  3. -e ENABLE_ACME=true \
  4. -e VIRTUAL_PORT=8080 \
  5. --name test \
  6. httpd

比如搭建gogs 服务器:

  1. docker run -itd --restart always \
  2. --name gogs \
  3. -e VIRTUAL_HOST=git.ngapp.net \
  4. -e ENABLE_ACME=true \
  5. -e VIRTUAL_PORT=3000 \
  6. -v /data/gogs:/data \
  7. gogs/gogs

原文链接: https://github.com/Neilpang/nginx-proxy/wiki

希望能帮到更多人,节约你的时间和精力.

欢迎大家转载 请保留链接.

欢迎 star:

https://github.com/Neilpang/nginx-proxy

Vant - 有赞移动端 Vue 组件库


logo



logo


A Vue.js 2.0 Mobile UI at YouZan

Build Status
downloads
Coverage Status
npm version
license

特性

  • 50+ 个经过有赞线上业务检验的组件
  • 单元测试覆盖率超过 90%
  • 完善的中英文文档和示例
  • 支持 babel-plugin-import
  • 支持 TypeScript
  • 支持 SSR

安装

  1. npm i -S vant

快速上手

方式一. 使用 babel-plugin-import (推荐)

  1. # 安装 babel-plugin-import 插件
  2. npm i babel-plugin-import -D
  1. // 在 .babelrc 或 babel-loader 中添加插件配置
  2. // 注意:webpack 1 无需设置 libraryDirectory。
  3. {
  4. "plugins": [
  5. ["import", {
  6. "libraryName": "vant",
  7. "libraryDirectory": "es",
  8. "style": true
  9. }]
  10. ]
  11. }

接着你可以在代码中直接引入 Vant 组件,插件会自动将代码转化为方式二中的按需引入形式。

  1. import { Button } from 'vant';

方式二. 按需引入组件

  1. import Button from 'vant/lib/button';
  2. import 'vant/lib/vant-css/base.css';
  3. import 'vant/lib/vant-css/button.css';

方式三. 导入所有组件

  1. import Vue from 'vue';
  2. import Vant from 'vant';
  3. import 'vant/lib/vant-css/index.css';
  4. Vue.use(Vant);

CDN

  1. <!-- 引入样式 -->
  2. <link rel="stylesheet" href="https://unpkg.com/vant/lib/vant-css/index.css">
  3. <!-- 引入组件 -->
  4. <script src="https://unpkg.com/vant/lib/vant.min.js"></script>

更多内容请参考 快速上手.

贡献代码

修改代码请阅读我们的 开发指南

使用过程中发现任何问题都可以提 Issue 给我们,当然,我们也非常欢迎你给我们发 PR

浏览器支持

现代浏览器以及 Android 4.0+, iOS 6+.

手机预览

可以手机扫码以下二维码访问手机端 demo:

qrcode

链接

开源协议

本项目基于 MIT 协议,请自由地享受和参与开源。

vagrant+docker一键搭建php+mysql开发环境

必备软件

  1. Vagrant
  2. Virtual Box

启动脚本

  1. Vagrantfile
  1. Vagrant.configure("2") do |config|
  2. config.vm.box = "ubuntu/xenial64"
  3. config.vm.network "forwarded_port", guest: 80, host: 80
  4. config.vm.network "forwarded_port", guest: 3306, host: 3306
  5. config.vm.network "private_network", ip: "10.0.0.2"
  6. config.vm.provision "shell", inline: <<-SHELL
  7. # 更换aliyun软件源
  8. cp /etc/apt/sources.list /etc/apt/sources.list.bak
  9. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse' > /etc/apt/sources.list
  10. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse' >> /etc/apt/sources.list
  11. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse' >> /etc/apt/sources.list
  12. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse' >> /etc/apt/sources.list
  13. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> /etc/apt/sources.list
  14. apt-get update
  15. # 安装docker
  16. apt-get -y install apt-transport-https ca-certificates curl software-properties-common
  17. curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
  18. add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
  19. apt-get -y update
  20. apt-get -y install docker-ce docker-compose
  21. # 使用aliyun加速docker镜像
  22. mkdir -p /etc/docker
  23. echo '{' > /etc/docker/daemon.json
  24. echo ' "registry-mirrors": ["https://kag9wqej.mirror.aliyuncs.com"]' >> /etc/docker/daemon.json
  25. echo '}' >> /etc/docker/daemon.json
  26. systemctl daemon-reload
  27. systemctl restart docker
  28. usermod -G docker vagrant
  29. cd /vagrant
  30. docker-compose up -d
  31. # 开机自启动
  32. echo '#!/bin/bash' > /etc/rc.local
  33. echo 'sleep 10' >> /etc/rc.local
  34. echo 'cd /vagrant' >> /etc/rc.local
  35. echo 'docker-compose up -d' >> /etc/rc.local
  36. echo 'exit 0' >> /etc/rc.local
  37. sudo rm /bin/sh
  38. sudo ln -s /bin/bash /bin/sh
  39. SHELL
  40. end
  1. docker-compose.yml
  1. version: '2'
  2. services:
  3. mysql:
  4. image: mysql
  5. environment:
  6. - MYSQL_ROOT_PASSWORD=root
  7. volumes:
  8. - "./mysql:/var/lib/mysql"
  9. ports:
  10. - '3306:3306'
  11. networks:
  12. - bridge
  13. www:
  14. build: .
  15. volumes:
  16. - "./wwwroot/www:/app"
  17. - "./wwwroot/static/Uploads:/app/Uploads"
  18. environment:
  19. - VIRTUAL_HOST="你要绑定的域名"
  20. - PHP_DB_HOST=mysql
  21. - PHP_DB_NAME=你的数据库名称
  22. - PHP_DB_USER=root
  23. - PHP_DB_PASSWORD=root
  24. networks:
  25. - bridge
  26. lb:
  27. image: 'dockercloud/haproxy'
  28. volumes:
  29. - /var/run/docker.sock:/var/run/docker.sock
  30. links:
  31. - www
  32. ports:
  33. - '80:80'
  34. networks:
  35. - bridge
  36. networks:
  37. bridge:
  1. Dockerfile
  1. FROM php:5.6-apache
  2. # 安装扩展
  3. COPY ./soft/*.tgz /soft/
  4. WORKDIR /soft
  5. RUN pecl install redis-3.1.6.tgz \
  6. && pecl install xdebug-2.5.5.tgz \
  7. && docker-php-ext-enable redis xdebug \
  8. && docker-php-ext-install pdo_mysql \
  9. && docker-php-ext-install mysqli \
  10. && rm -rf /soft
  11. # URL重写
  12. RUN a2enmod rewrite
  13. # 安装composer
  14. ADD ./soft/composer.phar /usr/local/bin/composer
  15. RUN chmod 755 /usr/local/bin/composer \
  16. && composer config -g repo.packagist composer https://packagist.phpcomposer.com
  17. # 安装代码
  18. COPY ./wwwroot /app/
  19. # 修改网站主目录
  20. ENV APACHE_DOCUMENT_ROOT /app
  21. RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
  22. RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
  23. # 可写权限
  24. RUN chmod -R 777 /app/
  25. # 默认工作目录
  26. WORKDIR /app
  27. # 暴露工作端口
  28. EXPOSE 80 443 22

前端框架Semantic-ui

官网: http://www.semantic-ui.cn/

更快地设计赏心悦目的网站

Semantic作为一款开发框架,帮助开发者使用对人类友好的HTML语言构建优雅的响应式布局。

简洁的 HTML

Semantic UI中词语和类(css clases)是可以相互替换的概念

直观的使用自然语言中的语法,词汇和语序等来定义一个类(css class)。

取BEM 和 SMACSS 的精华,同时使之更易于使用。

直观明了的 Javascript

Semantic 使用被叫做 behaviors 的简单短语来触发功能

开发者可以更改任何组件中的配置来设置该组件中的某一设置

化繁为简的调试

记录日志使您很方便的追踪到性能瓶颈,而不必去堆栈轨迹中发掘问题所在。

官网: http://www.semantic-ui.cn/

基于 Composer 的 PHP 模块化开发

转载, 文章原始地址: https://zhuanlan.zhihu.com/p/27943241
订阅号:假装我会写代码

这个话题之前是在微博公司内部做的技术分享,这里拿出来分享给大家。

基于 GitHub 或者其它平台托管的开源项目的引入大家应该都已经非常熟悉了,但是公司内部项目的模块化应该怎么做呢?这或许是不少朋友头疼的问题。

我们先聊聊 PHP 模块化开发演进的过程,在没有 GitHub 之前,我们大家获取与分享代码的方式主要是博客,国内的 CSDN 或者博客园还有很多很多,大家都是从文章内复制到自己项目里面使用。现在看起来真的是相当原始粗暴,但是那个时代也没有太多可选的方案。导致的现象就是一段代码在 N 个项目里出现,可能见得最多的就是获取客户端 IP 的那几行了,在互联网上不止出现了几万遍。现在很多项目里都还是这段:

是不是很熟悉?

这种引入代码的方式有很多弊端:比如不安全,因为很多人是直接复制粘贴就用上了,根本没花时间去考证它是否真的是安全的。另外一个问题就是不同步,你今天在别人那里复制过来就用上了,后来作者发现了 bug 并修复更新了文章也不会通知你,你也不可能记得这段代码来自哪里去检查更新。

在没有 Composer 之前我们是如何引入代码的呢?除了上面说的复制粘贴以外,在 PHP 中还有 pear,不过自从用过两次我就再也不用它了,一种说不出来的感觉。

不信你可以找一些旧的项目看看,在没有 Composer 之前的项目中,你会发现大量的重复代码,以及各种花样的组织格式,各种规范的写法。这也是 Composer 诞生的原因之一。

Composer 给我们带来了诸多的好处:

  • 模块化,降低代码重用成本
  • 统一的第三方代码组织方式
  • 更科学的版本更新
    这三个是比较重要的特征了,基于 GitHub 的共享代码方式解决了传统引入方式带来了各种问题。

我们先来了解一点 Composer 基础。

Composer 的实现结构相对比较简单,http://Packagist.org 是 Composer 官方数据源,它的数据基于 GitHub 等代码托管平台,你在本地使用 Composer 命令行工具,基于 http://Packagist.org 的数据信息安装与更新依赖。
本地安装 Composer 非常简单,主要有以下几种方式:

新手同学需要注意的是,这里一定要确定 composer 安装目录在环境变量 $PATH 内才能全局使用 composer 命令。

那接下来我们聊一下如何创建一个 Composer 包。

步骤很简单,创建目录,然后在目录内使用命令 composer init 按照提示完成包的初始化。

接着就是完成你的代码编写,然后在 composer.json 文件配置你的引入方式等信息。
然后我们如何对已经写好的代码进行测试呢?

我们需要在其它任何地方建立一个测试项目(不要在刚才创建的包目录就可以),比如这里我们创建一个叫 ‘my-package-test’ 的目录,然后在目录里 composer init 完成项目初始化。接着就是声明项目依赖,我们这里要依赖的就是刚才建立好的包,由于我们的包还没有发布到 packagist,所以是无法直接 composer require 来安装的,我们需要告诉 composer 从哪里加载我们的包信息:

  1. $ composer config repositories.foo path /Users/overtrue/www/foo/bar

我们通过这个命令在 composer.json 中 repositories 区块添加了一个项目源。

然后我们添加包依赖:

  1. $ composer require foo/bar:dev-master -vvv

这样就完成了包的安装,你会发现这样的安装方式它只是创建了一个软链接到包目录,所以,你在测试的时候就可以直接在 vendor/foo/bar 下修改代码,这样就加快了你的开发速度。

更多细节这里你就自己去研究了,我们来看看 composer.json 文件:

我们最需要关心的就是图里上面的三个部分了,包名、依赖、以及自动加载,是必不可少的部分。

刚才我们提到了包的安装,安装依赖包的方式主要有以下两种:

手动方式是不太推荐的,容易写错,比如后面多一个逗号之类的,不过你可以写完以后使用以下命令来验证:

  1. $ composer validate

更新依赖就非常简单了:

虽然在上一篇文章我们已经讲了语义化版本,这里再提一次:

我们在依赖一个包的时候,很多同学对于依赖的版本一直处于蒙逼状态,那看完下一页你就恍然大悟了,首先是两个符号:”~” 与 “^”

接着是版本号的范围的各种写法:

还有包含稳定性的标识:

这里需要说一下生产环境最重要也一直是好多同学不清楚的一个东西:版本锁定,很多人在纠结,要不要把 composer.lock 上传到代码库啊。我可以给你一个特别简单的判断方法:

如果你的代码是一个项目,就上传,如果是一个工具包,给大家用的,就别上传。

在已经存在 composer.lock 的目录执行 composer install 的时候,是不会分析包依赖的,它只是按 composer.lock 中描述的下载地址直接下载,所以会快很多,而且版本号是具体的。那怕包已经发了新版,只要 composer.lock 没动过,它就会按 composer.lock 里的版本来安装。composer update 时会更新 composer.lock,所以不要乱用 composer update。

包开发好了怎么发布?开源的方式是这样的:

最后一句请酌情考虑。

另外一种发布方式是闭源,公司内部用的包,上传到 GitLab 或者其它私有的代码托管平台,有两种玩法:

  1. 最容易的玩法,在 composer.json 中添加 repositories 直接用 vcs 指定代码库地址
    这样做有一个缺点,当你的包很多的时候,你全都得在 composer.json 中加上才行。

  2. 自已架设 Packagist 类似的服务,Packagist 官方提供了两款: toran,收费,开源方案是 Satis,不过它偏手动一些,自己酌情选择即可。

私有包有一个点需要注意:授权,私有包肯定都是需要授权才能访问的,这里由于方案不太通用,大家根据自己的场景来解决就好了。

另外,有一些痛点不晓得啥时候能够解决:

好在 Laravel China 已经为了我提供了国内目前最稳定最好用的镜像源,Composer 中文镜像 / Packagist 中国全量镜像正式发布!

最后总结一下:

  在 PHP 现代开发中,Composer 已经是离不开的东西了,它的确加快了我们的开发速度节省了开发成本,如果你还在纠结用不用 Composer,那你真得反思一下了。

  本文标题是模块化开发,内容主要介绍了包的创建与测试,以及公有包与私有包的发布方案。但是无法帮你解决,如何拆分项目这类问题,这得基于你的长期经验积累,但是有一些经验可以分享一下:

  • 不要过度设计,很多自以为很 NB 我不把学到的东西用上就是不爽的同学,上来就分库分表,uuid 做主键之类,项目运营了好几年一个表还没到100万条记录,也是够厉害的。

  • 不要过早设计,真正 NB 的架构是演进而来的,不是前期设计出来的,当然不是说完全不需要设计哈,恰当的根据实际情况来就好,不要立项就把“千万”、“亿级”、“百亿” 这些单位挂在嘴边,也许到你项目倒闭那天你都没到过任何一个量级。随着项目逐渐改进即可。

  • 优先关注成本,很多同学以为是性能,No! 技术团队真正的成本是人力,所以开发效率才是优先需要关注的。上次文章在发在知乎有人就强制把我的“不要首先关注性能”解读成了“性能不重要”,也是够厉害的,语文也许跟养殖场动物学的。数学正常一点的人都会算,一台服务器多少钱?一个技术员工多少钱?服务器你花 20 万是永久资产,一个员工 20 万呢?半年工资?一年工资?

docker的web管理工具

海鸥

Docker Pulls
GoDoc
Gitter

简介

Seagull 友好的docker Web界面管理工具

  • 易于安装和卸载在Docker容器
  • 单击开始/停止/删除容器和镜像
  • 超快速(小于10ms)的搜索和过滤
  • 支持多主机管理和监控
  • 国际化主要包括英语、汉语、德语和法语

更多信息, 请到 dockerseagull.com, 观看 三分钟视频官方的幻灯片.

github地址

点击跳转: https://github.com/tobegit3hub/seagull

安装

  1. docker run -d -p 10086:10086 -v /var/run/docker.sock:/var/run/docker.sock tobegit3hub/seagull

或运行 docker-compose up -d.

截图

多主机

Seagull支持监控多台服务器。确保你开始Docker守护这样。

  1. docker -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -api-enable-cors=true -d

参与

Seagull is written in Go with tools like Docker, Beego, AngularJS, Bootstrap and JQuery.

  1. Install golang and setup $GOPATH
  2. go get github.com/astaxie/beego
  3. go get github.com/tobegit3hub/seagull
  4. go build seagull.go
  5. sudo ./seagull

More detail in seagull-design-and-implement and we have excellent documents in docs.

提醒

The issue #2 每个人都可以在IP和端口海鸥接触访问您的码头工人守护。为了安全,你可以绑定到本地主机的访问限制。

  1. docker run -d -p 127.0.0.1:10086:10086 -v /var/run/docker.sock:/var/run/docker.sock tobegit3hub/seagull

类似的Docker项目

现在有很多类似的项目提供了Web界面来监控Docker。海鸥就是受他们影响并且期望做得比他们更好。

我想把这些项目都介绍给你们,任何人都可以根据他们所需要的进行选择。

Dockerui

这是它的Github主页,https://github.com/crosbymichael/dockerui.

你可以发现海鸥的UI是有点像Dockerui。因为我们都使用了Bootstrap和AngularJS作为前端框架。它是一个很好的项目并且在Github上有差不多2000个关注。

海鸥从Dockerui中学习了很多,包括使用JQuery.Gritter作为网站通知。但Dockerui的界面不够简洁,而且它没有考虑到国际化的需求,而我们考虑到了。我们愿意为全世界的开发者多做些事情。Dockerui还没有实现搜索功能而海鸥则很擅长这点。

Dockerui和海鸥是同类型产品,用于监控Docker。你没必要同时使用他们。而我们的目标就是用一个更友好、更实用的UI满足用户,并且取代Dockerui。

Zdocker

这是它的Github主页,https://github.com/love320/Zdocker.

Zdocker做了同类的事情来监控Docker镜像和容器。但它是使用Java实现的,而且没有提供Docker镜像,而且人们很难使用和学习。

这只能算是个人项目,我并不建议你去使用。因为目前为止我也不知道该怎样去运行它。

Shipyard

这是它的Github主页,https://github.com/shipyard/shipyard.

Shipyard设计来管理一个Docker集群。你必须输入服务器的SSH认证代码才能部署Shipyard引擎。然后你就可以通过命令行或者Web界面在你管理的服务器上部署容器了。

它和海鸥是非常不同的,因为海鸥仅仅是监控Docker而不会要求更多的权限。因此你可以使用Shipyard作为管理系统,同时使用海鸥来监控Docker。

CAdvisor

这是它的Github主页,https://github.com/google/cadvisor.

CAdvisor来自于Google,它主要是为了分析容器的资源。你可以使用它来监控你的容器占用CPU或者内存的历史情况。

然后,你不能用CAdivsor来管理你的镜像和容器。

Docker Registry Web

这是它的Github主页,https://github.com/atc-/docker-registry-web.

这是为Docker参与设计的Web界面。它的UI展示不错但你必须手动添加私有仓库地址。它用了Cookies来存储这个地址所以每次你运行时都要重新添加。

当我尝试去搜索Docker镜像时程序崩溃了。当我尝试去或者镜像详细信息的时候它显示“方法未授权”。

我希望他们可以在我们添加私有仓库时就默认添加Docker官方仓库。但我不太可能因为http://registry.hub.docker.com不支持CORS。

Docker Registry UI

这是它的Github主页,https://github.com/worksap-ate/docker-registry-ui.

这也是为Docker仓库设计的Web界面。它能用但是UI不是很好。

Docker Register Frontend

这是它的Github主页,https://github.com/kwk/docker-registry-frontend.

这几乎是跟Docker-registry-web和Docker-registry-ui是一样的东西。