How We Build the Complex Web

这个标题被翻译成当下的话,就是当我们在构建大型 Web App 时,我们应该怎么做?


- 选一套好用的框架,最佳实践(技术框架)

和配图一致,当今世界已三分天下,分别是

选择哪一套都没有明显的优劣,都能完成一些特定的任务。无论是社区、生态和各自的语法都已经比较完善,余下怎么选,就看个人和团队的偏爱了。

我们的选择是 React,原因有以下:

  • Component 的理念比较能接受
  • 有着强大的社区和背后的 Facebook,这是信心的保障
  • Ant.Design 等组件库的支持。

但要说明的 React 并不是一个构建前端的框架,它只是一个视图的库,如果想构建大型的项目,依然需要一个框架来支持,像 Flux 模式的轻量实现 Redux。

  • React
  • ReactRouter v4
  • Redux


- 选一套好的 UI 组件库

一个复杂的前端系统,是需要一整套完整且统一风格的组件库的。这个组件库会大大降低整个项目的复杂度,并带来统一的风格和交互体验。

UI 组件库一般都会提供布局 Layout (Grid/Flexbox),浏览器兼容,常用组件库等功能。

当然从 bootstrap 这个伟大的产品开始,业界在这方面的努力就没有停止过。目前主流的有:

BBootstarp 和 Bulma 只是传统的 JS 和 CSS 的库,但它们在每个平台上都有对应的封装,对应 React 的:

Ant.Design 不一样的是,它就是为了 React 而生,而且由蚂蚁金服提供,相比前两个的 React 版本,这个更能获得信任。


- 选一套好用的方案, 最佳实践(流程)

项目结构

构建流程

一般,我们的开发都会包括对应的多套环境,像:

  • Dev
  • Test
  • Production

在开发环境时,需要启动。在其它环境时,还需要进行构建,发布的操作。

  • Debug
  • Build

对应这些需求,常见的工具则表现为:

  • Glup
  • ⭐️ Webpack

Webpack 2 * js css, html, image, import, using as name.
Glup


- 还有最后一点。有好的案例参考为佳。

Bootstrap

  • Rubix,这是一套收费的组件库,口碑不错。

Ant Design

  • 也有 antd - Admin,这是个人开源的,仅供参考用。

REF::


这里的参考来自我的同事,从刚开始使用 React + antd,到现在完能一些大的项目,她个人对这个组合已经是完全的推荐了。

标准与创新

昨天和一个做 HR 的朋友聊天,谈到了一件事,就是互联网公司的管理的混乱。我也谈了下自己的看法,互联网是个新兴的行业,不像传统企业,一种模式都运行了上百年,有着成熟的管理方案,像麦肯锡,精益管理,Six Sigma 这些耳熟能详的经典。而新兴的行业总是带有着一些创新性的,特别是在这个技术和文化大爆炸的时代,对传统更是提出了挑战。而我个人,是喜欢这种创新的,因为只有在创新中,才能有更多的机遇,有更好玩的事,去思考,去探索。

回到技术上,也有这样的情景。

Native & HTML

一个是创新,一个是标准。

原生就是一座城,HTML 不停的突围,当年 Broswer 打败了原生,成了一时主流,也成就了 Web 2.0 时代的辉煌,但迅速的在 Mobile 的战场又败北给 Native App,时过境迁,随着 Cordova 等一批先驱的尝试,在 Native 世界中,HTML 又一次被带上热点,Hybrid App, React Native 等新一批的统一标准又再一次登上舞台。

回首 2017,Native 的招聘热度骤降,也能深刻的体现这一点。

这不就是标准与创新吗?

  • HTML 是多个平台,多个厂商,利益集团的标准,一个新的事物总是要反复的讨论,才能形成标准。
  • 而 Native 则通常是一个平台,一个厂商的产物,可以方便的添加新事物,也就容易产生创新。

标准永远是跟随着创新走的,除非创新变慢了、稳定了,形成了标准。

所以,回过头再看移动领域的 HTML 标准 之所以有一些突破,就是移动端的创新也在变慢的反映。

那当下的创新是什么呢?2017,当然是智能穿戴硬件,AR、VR,不信你看,这些依然是各家纷争,没有标准的,但预见不久也一定会有标准产生的。

规律就是这样

所以,作为开发者,是困惑,是抱怨,还是积极面对?

  • 如果你还在抱怨原生不行了,那一定是你太固化了,在一个老旧的领域没有去思考,去创新。

  • 如果你在抱怨新的东西不断在更新,学起来太累,那一定是你处于一个好的领域,在成长,你可以去面对它,也可以逃避。

  • 也或许,你好久没有感受过新的东西,那可能是处于行业领域周期的中、尾端了,可以考虑抬头看一下这个飞奔的世界。

REF::


How I Do Node Deploy

Docker Docker Docker

  • 不需要在服务器上做太多的事
  • node 的版本,global 库的版本,都可以自己控制。
  • 安全


Docker base image

base image 就像设计模式的模板模式,好处是,给你一个标准的流程,且最大限度的帮你完成一些重复的操作,同时,也限定了这个容器的操作范围,不会让你出错。

于是我们就做了一个

这个 base image onbuild 做了以下几件事情

  • 限定工作目录 /app/
  • 安装指定版本 pm2
  • 复制 package.json 和 yarn.lock,并进行 production 的安装。
  • 复制项目到 /app
  • 导出端口 80 443
  • 指定启动脚本 pm2-docker(脚本参数可改)


boilerplate

https://github.com/lanvige/koa2-boilerplate

对应这个 image 还有一个完整个 node 项目,是基于 koa2 的。

项目的目录结构:

1
2
3
4
5
6
7
8
9
10
.
├── app
├── bin
├── config
├── lib
├── docker-compose.yml
├── Dockerfile
├── package.json
├── process.yml
└── yarn.lock

dockerfile

其中 dockerfile 最简单,因为 base image 中做了全部的事情,这里只需要一个空的设置就可以了。

因为是 base image 是 onbuild 的,所以还是需要一个这个的文件。

docker-compose.yml

compose 文件,是构建 docker image 和 启动的一些设置。像容器名字,端口绑定,环境设置

process.yml

process.yml 这是 pm2 启动的配置。


使用

  • yarn build,将代码进行编译,生成目录 dist
  • app config build,创建使用环境的 config 到 dist/config 目录
  • docker-compose up -d, 在 dist 目录下,运行 docker compose 命令构建镜像并启动。

简单到无聊~


线上发布

理论上好的流程是,一台 docker build server 负责制作 image,然后推到 registry,线上服务器拉取镜像,再启动。

但实际中,这个成本有点高,首先需要一台 build server,其实,镜像很大,占流量。

于是,在个人项目中,直接使用 shipit 来进行发布,在本地做项目的构建,然后,将 dist 的代码同步到服务器,服务器直接本机构建 docker image,然后启动。

通过 shipit-deploy,可以方便的完成 前面的代码构建,同步到服务器上的操作。
通过 shipit remote 的功能,也很方便的扩展 docker 的一些命令。


演进

NODE_ENV: 之前将 node_env 放在了 Node 构建时进行设置,后来发现,这样可能就导致一个容器只能在一种环境下启动,想修改,必须在启动后,通过 exec 进入容器后才能修改。

于是将这个配置向后移,放到了 pm2 的配置中。

这样,在启动容器时,可以通过修改 docker cmd 来进行配置:

1
command: start --env production /app/process.yml


REF::


  • [none]

Node 包管理的一些心得

自从 node 变成了最主要的语言,用的多了,经验也会多一些。

node 的包管理一直是一个很烦的事情,它没有一个本地的中央仓库,所有的依赖都是项目级别的,更早之前还是以依赖进行嵌套放置的,导致大量重复的安装。

使用 nvm

node 的版本变化很快,特别是一些新的特性,一些特性在新的版本中可能就不需要使用 babel 来配置了,所以经常要切换版本。

同事就发生过一直在 5.x 下进行开发,结果当 node 换成了 6.x 或以上版本时,整个项目都无法编译,导致无法上线。

经常的将自己的代码放到新的版本里去测试,也是一个必要的事。

nvm 是最好的助手。

  • nvm install (v) - 安装一个新的版本
  • nvm use (v) - 临时切换一个版本,关闭 terminal 后失效
  • nvm alias default (v) - 设置系统默认版本

第一原则是推荐 yarn

它解决了:

  • 本地代理+缓存,这样,最少解决了速度问题,不需要每次安装都从服务器上去接,这样太慢,效率大大提升。
  • 使用多线程去下载,更快。
  • 更主要的是版本锁定,这样,就避免了因版本不一致而出现的各种问题。

我们已经在生产环境使用上了

开发环境的 global bin 迁移问题

nvm 虽然解决了 node 的版本问题,但每次升级都要对 global 的命令进行迁移,也是一件很烦的事情。

yarn 很好的解决了这个问题,在 macOS 上, yarn 的配置和文件目录被放置了在 ~/.config/yarn 下,global 的目录则对应在 ~/.config/yarn/global,这样,就和 nvm 脱离了关系。每次升级不再有 global 迁移的苦恼。

发布

发布时,要带上两个文件

  • pakcage.json
  • yarn.lock

Docker image build

如果使用 docker 时,一定要把这两个文件先进行复制,然后安装其依赖。再复制项目。

包依赖的变化不是特别频繁,这样可以重复的使用已有的 docker image layer,节约空间,提升效率。

祝女主人女神节快乐!

今天是个特别的节日,当然要有个特别的专题给特别的人,对啦,这就是花府的女主人。

忽然,思绪就被拉回到一些照片定格的时间,那时,吃货还是个时髦的词,花叔还是个瘦子。于是一个貌美如花负责吃喝玩乐,带着一个负责赚钱养家,开始了一场如星辰大海般的吃途。

随着照片的年代越久远,除了能看出当时手机摄像头的薄弱外,最明显的就是身材。以至于昨天见到老同事,那看我的小眼神。当然,上天是公平的,时光刻刀留下的痕迹也不止留在我一人身上,女主人在这个幸福的便当里光速迷失,也渐渐远离了窈窕二字。

即然是吃喝玩乐,那就要走出家门,去心中的远方,两个人的旅行,好过一个的漂流,在几年间,去了不少的地方,那些年许过的环游世界梦想,渐渐变成了现实,越来越多的小旗帜插在地图上各处,出行的劳累竟都变成时间长河中慢慢的记忆。

品尝了夜的的巴黎,踏过下雪的北京,累计了许多飞行,用心挑选纪念品,拥抱热情的岛屿,搜集了地图上每一次的风和日丽。这是陈绮贞的歌,忽然就哼了起来。

生活的琐事,总也甩也甩不掉,工作、生活、家庭。这些年,总有很多的事情,回首当时,都是一种焦灼,但如今再望时,发现不过是世间的一粒尘埃,都不值得一提。不过在这些事情的记忆中,都有一个要感谢的人,我是一个急躁的人,情商也就一般,但女主人是我的另一面,总是让人学着沉着。

中年而立,忽然对生活多了一些看法,那些以前看不惯的装饰、滤镜,现在再回首看,已经是热爱生活的标志了。在经历这么欢喜和忧伤,生活就也开着变得平淡起来,每一寸的阳光,都能改变一片的心情,于是那些还在为美动手的事,总会被拿起赞赏。于是,去年,在女主人的执(Bi)领(Po)下,装修了家里的院子,那段时间,为了装扮这个小院,家里忙碌了几个月,不断的添购,终于一个开满鲜花的地方,迎接了一次又一次的朋友来访。正是这些鲜花冠名,我们为小院起名叫花府。(这也是花叔名字的来历哦)

女主人说,一定要热爱生活,这样你才会过的有意义,所以我经常给同事安利,一定要多出去走走,这样你回首时,才不会感到青春的落寞。

回到工作,对一个码农来说,有一个设计师的老婆是一件很了不得的事,这几乎是一家创业公司的标配,况乎女主人还转型做了产品。业余的时间,差不多就是你帮我的文章配个图,我给你讲讲你前天写的三生三世组件编排。会觉得无聊,会吗?😜

回头一看,女主人正在很努力的写东西,边上放了好几支笔(败家),字写的很好看,这解决了一个大问题,将来小孩作业家长签字的问题。

热爱生活,艺术天份,努力,自然,气质,这些词送给女主人。如果要在这个节日要送一个特别的礼物,那一定是这些年来,我一直放在心里的那份感激,并附上我最高水平画像一副:

DevOps - Server Manage Practice

不要用 root

添加一个运维的组:

1
2
# deployer
$ groupadd devops

添加用户,加入到新建的组中:

1
2
3
4
# 添加一个用户 ares, -G 加到devops组里,-m 创建用户目录,-N 不创建同名 group。
$ useradd ares -G devops -N -m
# 给用户设置一个密码
$ passwd ares


给账号免 sudo 的能力

在运维发布时,推荐使用 passwordless sudo。这样非 root 用户也可以直接使用 sudo 命令,而不必通过 PTY 来输入密码。Guide:

其实就是在系统里,给指定用户赋上某些指令的 sudo 权限。在 Ubuntu 下,修改 /etc/sudoers 来添加要使用的命令。

1
2
3
4
5
6
7
8
9
10
/etc/sudoers
# 给指定用户,添加 passwordless 命令
ares ALL=NOPASSWD:/usr/sbin/service, /bin/ln
# 也可以设置一个组
%devops ALL=NOPASSWD:/usr/sbin/service, /bin/ln
# 也可以将所有程序都设置为不要密码,不过太不安全,不建议
#ares ALL=(ALL) NOPASSWD: ALL


ssh-copy-id

输入服务器用户密码后就 deploy 就进行了。不想每次都输密码,ssh-copy-id 可能是你想要的。

每次运行 cap 都要输入密码,可以将本地的 ssh公钥 存到 server 上,就可以省下很多时间。

ssh-copy-id 就是这么一个将本机的公钥复制到远程机器的 authorized_keys 文件的工具,其也能让你拥有远程机器的 home, ~./ssh , 和 ~/.ssh/authorized_keys 的权利。

首先本地机器上要创建 ssh key

1
$ ssh-keygen
1
$ ssh-copy-id aers@192.168.1.1

macOS 上 ssh-copy-id 不是默认安装的,可通过 Homebrew 进行安装

1
$ brew install ssh-copy-id

Shipit Node App with Docker

上面提到如何在代码部署到 Remote Server 后,将 Sercert file link 到相应位置,然后通过 PM2 启动服务。

但我们真实的项目,是构建 Docker 镜像然后启动镜像来实现最终的发布。

这里的流程又是什么样子呢?

  1. 将代码放到 remote server 指定位置(已完成)。
  2. 在 remote server 上将 shared dirs/files 放到指定位置。
  3. 在代码目录下 build docker image。
  4. 启动。

但实践中,发现一件很麻烦的事:docker dislike symbolic link 😓

shiptit-shared-copy

首先的是,app 目录中不能含有 soft link 文件,不然不会被 copy 到 docker 镜像中。

像 config/application.yml 这种通过 link 方式存在的,就不行了。

所以,直接 fork shipit-shared 项目,把 symbolic link 改成 copy。

每次都会把文件复制到 current 对应的 release 版本中。

配置文件和 shipit-shared 保持不变:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = function (shipit) {
require('shipit-deploy')(shipit);
require('shipit-shared')(shipit);
shipit.initConfig({
default: {
shared: {
overwrite: true,
files: [
'config/application.yml',
'config/database.yml'
],
}
}
});
};

deploy-duplicate

解决完 app 内部 soft link 的问题后,然后在 current 下用 docker-compose 构建镜像,然后启动。发现不能重复,原因是,每次构建的目录并不是 current 这个 soft link 的目录。而是 releases/[version] 这个目录。

目录名变化后,构建出的镜像就不一致了,这就导致无法重复的在一个目录下进行多次构建。

compose 构建后的镜像是用 目录名+service 名。

同时也会引发无法销毁的问题,端口被占用。

解决办法也有,就是把releases/[version] 物理复制到另一个 current 一样的固定的位置。起名叫 deploy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.
|-- current -> releases/20170228072117
|-- deploy
| |-- app
| |-- bin
| |-- config
| |-- docker-compose.yml
| |-- Dockerfile
| |-- lib
| |-- package.json
| |-- process.yml
| |-- REVISION
| `-- yarn.lock
|-- releases
| |-- 20170228062744
| `-- 20170228072117
`-- shared
`-- config

这样,每次在 published 后,都将最新的 releases 版本复制到 deploy。然后在 deploy 下执行 docker-compose up -d --build

没有做成单独的 npm,直接放在 shipitfile 中即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = function (shipit) {
// Docker dislike soft link
// So make a physical copy (deploy) instead of softlink (current)
shipit.blTask('deploy-clean', function () {
console.log('cp -R ' + shipit.releasePath + ' ' + shipit.config.deployTo + '/deploy');
return shipit.remote('rm -rf ' + shipit.config.deployTo + '/deploy');
});
shipit.blTask('deploy-duplicate', function () {
return shipit.remote('cp -R ' + shipit.releasePath + ' ' + shipit.config.deployTo + '/deploy');
});
shipit.on('published', function () {
shipit.start(['deploy-clean', 'deploy-duplicate']);
});
}

完美。


REF::

Shipit Node App with PM2

在上一篇中,已经将项目放置在 Remote Server 上了。

在如何启动时,我们有多个选择,现在,看下如何直接用 pm2 在目录下直接启动。

服务器上的目录如下:

1
2
3
4
5
6
7
.
|-- current -> releases/20170228072117
|-- releases
| |-- 20170228062744
| `-- 20170228072117
`-- shared
`-- config

配置

有了上面两个插件的配合,就省力了很多。

在项目中 config 下有两个文件,需要被忽略,所以这里通过 shipit-shared 来配置。

在这之前还有几个问题要被解决:

shiptit-shared

项目中有一些配置文件,里面会存有服务器,DB 的相关安全信息,而且这些信息是跟环境相关,也就是说在不同的环境,它的内容是不一样的。

shipit-shared 就是帮我们做这件事情的。

它可以,在 Remote Server 上建一个公共的目录,手工在里面建立起上述的文件。再在 shipitfile.js 中加入这些文件或目录的配置。

每次 deploy 时,就会自动的将这些文件或目录软链到 current 下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = function (shipit) {
require('shipit-deploy')(shipit);
require('shipit-shared')(shipit);
shipit.initConfig({
default: {
shared: {
overwrite: true,
files: [
'config/application.yml',
'config/database.yml'
],
}
}
});
};

shipit-pm2

如果项目是在代码发布完之后,直接通过 pm2 来启动的,那这个插件就很适合。

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = function (shipit) {
require('shipit-deploy')(shipit);
require('shipit-pm2')(shipit);
shipit.initConfig({
default: {
pm2: {
json: '/data/repos/app-koa2boil/process.json'
}
}
});
};


REF::

使用 Shipit 来自动化部署 Node 应用

之前一直想为 node 的发布整理出一个流程,但一直没有太多实践,后来就忙给忘却了,不过最近做了几个小东西,每次发布都要登陆服务器,终于下决心自动化这个流程。

项目结构

Node 的项目结构是这样子的,可参考 github: Koa2-Boilerplate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
├── app
│   ├── apis
│   ├── models
│   └── services
├── bin
├── config
│   ├── application.yml
│   └── database.yml
├── lib
│   └── middleware
├── Dockerfile
├── docker-compose.yml
├── process.yml
├── shipitfile.js
└── package.json


整理现在的发布流程

目前仍有 ES Module 不是 Node 支持,所以发布时需要 build 生成发布代码,然后将发布用的代码放到服务器,通过 pm2 启动,或构建 Docker 镜像。

为此,我们构建了两个 repo:

  1. 项目的源码,编译后,生成 dist 为发布用的代码
  2. 编译后的代码,包含各种配置文件,dockerfile, docker-compose 文件。

流程:

  • 源码项目更新,然后 build 出 dist 目录
  • 将 dist 复制到 发布项目,然后迁入 git
  • 服务器拉取发布 git
  • Docker build
  • Docker run

小的项目中,如果不需要对 docker 进行版本说明,以上流程将是一个很简单的事。

如果想要自动化的话,就需要考虑以下两个构建步骤:

  • 代码构建服务器:因为是小的项目,可以不需要中间的构建服务器,直接由本机的另一个路径,或者是服务器的一个路径来承担,建议放在本机,这样服务器就不需要 node 相关的软件了。
  • Docker 构建服务器:docker image 一定要在远程服务器本机处理的,不然传输成本就太高了,这就要求构建服务器,


什么是 Shipit?

Shipit 是一个用 Node 写的自动化引擎,也是一个发布工具。

说白点就是 Universal automation and deployment tool,通用自动化部署工具而已。

和 Capistrano 对比

作为 Capistrano 的 Node 版,有什么区别:

Capistrano

  • Ruby 语言(这个对我来说没问题)
  • 在服务器端拉代码,然后进行 build 的。
  • 插件多,社区完善。

Shipit

  • Pure JavaScript,在 Node 上体验会更好。
  • 本地拉取 git repo,本地打包(好处是服务器上不需要配置 node.js 了),然后 rsync 指定目录到 Server
  • 3个月未更新。
  • 支持的插件少,但可以自己写,很简单。

对比完这些,觉得还是 Shipit 更适合一些。


Shipit Configuration

接下来,就在本机尝试安装和配置 Shipit。

安装

1
2
$ npm install --global shipit-cli
$ npm install --save-dev shipit-cli shipit-deploy shipit-shared

Create a shipitfile.js

Shipit 的运行依赖于配置文件,在项目的根目录,创建 shipitfile.js 就可以开始了。

一个简单的示例(为 staging 环境配置一台远程服务器,并新建一个叫 pwd 的 task):

1
2
3
4
5
6
7
8
9
10
11
module.exports = function (shipit) {
shipit.initConfig({
staging: {
servers: 'root@project.com'
}
});
shipit.task('pwd', function () {
return shipit.remote('pwd');
});
};

这时,就可以通过以下命令 shipit+服务器+task 来运行了。

1
$ shipit staging pwd


发布实战:

基于 shipit-deploy 的发布流程

当然一个完整的发布流程,会有多个 task 进行顺序执行,而 shipit 自身也只是定位于一个编排引擎,它提供了 task 的组合能力(基于: Orchestrator)同时,还提供了钩子的能力,能在一些 task 前后加入自己的task(event),这称为 Emit,接下来会用到这些功能。

我们完全有能力基于这些编排组合能力和钩子实现发布的所有流程,但重复从来都是应当被吐槽的。社区也早有一些最佳实践,shipit-deploy 就是 shipit 自己做的一个发布实践。

利用它可以很快速的完成自己的发布流程,同时,它也提供了大量的 Emitter,供我们进行扩展。

更多的可以查看官方文档:

实际项目 deploy 的扩展

对比下 shipit-deploy 的 task flow,我们需要的是在 fetch 完代码后加入以下流程:

  • npm install
  • npm run build

通过 emit 就可以实现,代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
shipit.blTask('npm-install', function () {
shipit.log('yarn install.');
return shipit.local('yarn install', { cwd: '/tmp/app-koa2boilerplate' })
});
shipit.blTask('npm-build', function () {
shipit.log('npm build start.');
return shipit.local('npm run build', { cwd: '/tmp/app-koa2boilerplate' })
});
shipit.on('fetched', function () {
console.log('itis npm build');
shipit.start(['npm-install', 'npm-build']);
});

运行以下命令,就能完成代码获取,构建,发布代码到 Server 上的流程。

1
$ shipit staging deploy

真实的启动流程

经过上面的步骤,可用于线上发布的代码已被放置在服务器上了。那项目中的一些被 gitignore 的配置文件呢。

请看下面两篇:


REF::

逛街引发的数码购物单

今天陪 LD 去逛街,本想去 Line Friends 里转转,但队伍实在是太长了,瞬间没了兴趣,还没有吃到好吃的东西,感觉淮海路是为数不多的不适合吃饭的地方。

期待新 iPad Pro

新开了一家 Apple 店,是之前没有转过的,刚好转去看了一下, LD 是一位艺术家,随手画了几笔,立即把我打动了,本着每一个爱好都应被呵护的想法,准备送一个 iPad Pro + Pencil,回家做了下功课,感觉三月新品发布会应该有新款发布,取消 Home 键,更快的处理器,更大的内存,买新不买旧,那就再等等 😄😂

iMac 5K

说话,前天没有开车,坐地铁时带上了 Kindle,原来放了一年还有电,厉害。中间看了一路的书,快到 站时收起书,换上手机,竟然被 iPhone 的细腻感动到了。

这就是我对 iMac 5K 的期待吧,别挤牙膏了,出个让人满意的吧。真的想入了。

Apple-3月春季发布会-预测::Devices

设备 更新介绍 价格 上市时间
MacBook Pro 小更新 Kabylake CPU -.– 2017.03.21
iMac 27 KKK,今年终于赶上 Intel 的节奏了,KabyLake,DDR 4,USBC,AMD显卡 -.– 2017.03.21
iPad Pro 2 据说更新三款 iPad Pro 2 (12.9/10.5) 去除Home键,同时采用极窄边框。 -.– 2017.03.21
iPad Mini 应该也会更新一下。 -.– 2017.03.21

LG UltraFine 5K

除了旧例体验 iMac 27外,还多看了一眼边上的 LG 5K,比 DELL 5K 便宜了一半,效果和 iMac 27 上的一样,其实就是同一块屏。

可以上下,左右调节。不支持 DELL 那种竖屏,不过也从没有竖起用过。外观,有点太一般了,边框很宽,看起来没精神,不像 U2717d 那般好看。

相对于 iMac 的好外是,可以调节,方便外接,想想之前的 TDM 模式,真难用。
缺点就是没有 iMac 的金属边框的质感,价格也不便宜。7638。额,,有点小贵。

更多 LG UltraFine 5K 看官网:

DELL U2717d

说到 2717d,上周,我把它出掉了,原因是入了 OSMO+ 运动套件,资金有不小压力。当然不是了,只是显示器多,2515 也没怎么用到,就想出一个。

出之前,经常把笔记本背回家,现在没了显示器,也再没背过了,又开始了研究如何同步的问题。

OSMO+

话说,年前放假前两天,入了一个 OSMO+ 运动套装,本想去日本时用,结果今年临时决定在上海过年。

一直说要评价一下 OSMO+ 的,毕竟这一块没人做过,我也是用了好久,才有一些经验的。

所以,就不在这里讲了,回头有机会,专门长篇去测评一下。

如果非要给个一句话总结,就是有钱想玩,真的挺好玩,如果想干专业的事,拍照,一般,拍视频,也一般 。