木头的博客

我是木头 有些想法 有点精力

0%

通信

容器间通信的一些 Q&A

  1. 如果不声明 network 字段, 在同一个 docker compose 之间可以通信吗?

    可以

    如果不指定一个特定的 network, docker 会指定容器在一个名为 docker0 的默认网桥中

  2. 如果不声明 expose 选项, 那么同一网络中的其他容器可以访问该容器吗?

    可以

    但如果启动docker守护进程时指定了--icc=false选项,则不可以。
    建议声明, 声明该选项有助于使用者了解容器内暴露了那些端口出来供使用。

  3. 在同一个网络中不同的容器使用了同一个端口会有冲突吗?

    不会

    不同的容器使用不同的 host, 所以哪怕两个容器使用了同样的端口,也不会与其他容器冲突。

  4. exposeports 字段有什么区别?

    如果容器内的端口需要在宿主环境访问,则需提供 ports 字段

    expose 字段在默认情况下是可选的,即使不声明也可以在同一个网络中使用该容器的端口

最近在使用 Cypress 作为前端项目的 E2E 测试,发布到 CI 环境时自动运行。

运行时发现在 Pipeline 测试报告中有生成 mp4 格式的视频,这才想起来 Cypress 自带生成视频快照的功能,结合 Jenkins 收集报告产物,不就可以拿到视频快照了吗?

哈哈,talk is cheap, show my code!

下面是 jenkins 配置

Jenkinsfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pipeline {
agent any

environment {
CHROME_BIN = '/bin/google-chrome'
}

stages {
stage('Environment') {
steps {
sh 'uname -a'
sh 'apt-get update'
sh 'apt-get install -y xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 ttf-wqy-zenhei'
sh 'fc-cache -v'
sh 'yarn install'
}
}
stage('Test') {
steps {
sh 'yarn test:e2e --headless'
junit 'reporter/output.xml'
archiveArtifacts 'tests/e2e/videos/*.mp4'
}
}
}
}

其中 ttf-wqy-zenhei 是用来解决 Ubuntu 系统中没有中文字体等问题,否则生成的视频报告中的中文都为方框乱码。

如果是在 CentOS 中,执行 yum -y groupinstall chinese-support 解决中文问题

如果不知道 Jenkins 所属运行环境,使用 uname -a 查看系统信息

archiveArtifacts 用来收集报告产物

junit 用来收集测试报告,但 Cypress 默认是不生成报告的,需要在 cypress.json 中增加以下内容

cypress.json
1
2
3
4
5
6
7
{
"reporter": "junit",
"reporterOptions": {
"mochaFile": "reporter/output.xml",
"toConsole": true
}
}
阅读全文 »

我们在写 shell 脚本时经常会遇到一些需要交互的操作,比如修改某个文件,或是使用 yum install ssh-keygen certbot --nginx 等操作时,需要输入一些指令如 “y”, “Enter” 和其他的一些信息。

我们写脚本就是为了自动操作,怎么可以等命令执行一会之后在按个回车进行下一步呢?既然我知道接下来要输入什么命令,我告诉你你帮我输入了不就得了?

聪明tōu lǎn的我们想到了一些办法来避免这种无谓的等待,记录下来分享给大家

阅读全文 »

最近在学习 Flutter 补充移动端开发的技术栈,刚好换电脑,特此从 0 开始重新搭建 Flutter 开发环境

整个安装环境是基于 macOS 操作系统的,如果你使用的是 Windows 操作系统,可以参考其他教程或本博文大致思路

1. 环境安装包下载

以下几个安装包体积较大,所以在观看本教程前需要提前进行下载

2. Flutter SDK 安装

下载好 Flutter SDK 后,解压到一个存放 SDK 的目录,我这里存放在 ~/.flutter-sdk

1
2
3
mkdir ~/.flutter-sdk
cd ~/.flutter-sdk
unzip ~/Downloads/flutter_macos_v1.7.8+hotfix.4-stable.zip

然后将 Flutter SDK 的安装目录暴露给环境变量,在 ~/.zshrc~/.bashrc 文件中增加以下内容

1
2
# Flutter
export PATH="$PATH:$HOME/.flutter-sdk/flutter/bin"

然后你还可以下载 Flutter 在未来会需要的二进制包(可选的,也可以在未来下载)

1
flutter precache

最后运行检查工具 flutter doctor ,来检查你的 Flutter 是否可以正常运行, 如果出现下面的信息,就说明你安装 Flutter SDK 成功啦

1
2
3
4
5
6
7
8
9
flutter doctor

➜ .flutter-sdk flutter doctor
[✓] Flutter (Channel stable, v1.7.8+hotfix.4, on Mac OS X 10.14.5 18F132, locale en-CN)
• Flutter version 1.7.8+hotfix.4 at /Users/yourusername/.flutter-sdk/flutter
• Framework revision 20e59316b8 (6 weeks ago), 2019-07-18 20:04:33 -0700
• Engine revision fee001c93f
• Dart version 2.4.0
...
阅读全文 »

前言

现手上有一个小型的 js 项目, 内容比较简单, 就是提供一个单页, 其中引用了 quill 富文本编辑器.

该页面需要嵌入到其他客户端(如 iframe 或 webview) 以提供统一的富文本编辑的用户体验.

项目内部使用 webpack 将 js / stylus 打包, 对外提供两个 html, 一个用于大屏的 iframe 显示, 另一个用于小屏的 Android / IOS 设备显示.

项目结构如下

file-tree

你可以参考此项目对自己的项目进行改造, 过程大致相同

阅读本贴, 你可能需要了解以下前置内容

  • typescript
  • webpack
  • yarn

本次改造所有改动可在 github 查看 commit 记录

阅读全文 »

“TypeScript 又是什么东西啊, 怎么又在出新语言, 求不要再出了, 学不动了!!”

场景1 – 检查类型

开心的撸代码中, 突然接到老大消息: xxx离职了, 现在你来接手他维护的项目.😳

拿到代码后, 看到了这段东西

1
2
3
4
5
/** 根据用户id获取用户信息 */
async function getUsers(id) {
const users = await fetchUsers(id)
return users
}

这个 id 是什么? 是 1 还是 "1" 还是 [1,2,3] 还是 "1,2,3" ???

这个 users 又是什么? 是普通权限用户? 还是管理员看到的用户?

全局搜索了一下调用该方法的地方, 发现这是个“万能”的方法, 传入 id 为 1 时会返回 1 号用户的不含私密信息的对象

传入 [1,2,3]"1,2,3" 时会获取一个数组

[掀桌]


如果上了ts

阅读全文 »

正则表达式是什么

正则表达式可以从一段文本中提取特定内容的功能, 几乎所有编程语言都支持. 使用在爬虫、检查用户输入合法性、XSS 过滤等.

在整个学习过程中, 给大家推荐一个可视化正则表达式的网站 https://jex.im/regulex/

他可以根据你输入的正则表达式动态的生成匹配图, 帮助你理解一个复杂的正则表达式. 像下面这样

语法

javascript 中支持 3 种正则表达式语法: 字面量、构造函数和工厂符号, 他们的签名如下

    /pattern/flags
    new RegExp(pattern, [, flags])
    RegExp(pattern, [, flags])
阅读全文 »

前段时间听说 Vue3.x 要使用 TypeScript 重构了, 本来一直都想研究一下 Vue 的源码, 这次带着夙愿来从头编写一个简单的、现代化的 Vue.

搭建好 TypeScript 开发环境后, 开始了一段 TypeScript 与 Vue 源码的探索之旅.

背景

我使用 ES6 class 创建了一个 Vue 类, 为了实现数据监听, 我使用了 ES2015 中的 proxy 方法来对数据进行封装, 并且将这个 proxy 返回给类的构造方法, 以便于获取 vm 实例.

代码如下

查看源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
interface IOptions {
data: () => Record<string, any>
}

class Vue {
private $options: IOptions = {
data: () => ({})
}

constructor(options: IOptions) {
this.$options = options
const proxy = this.initProxy()
return proxy
}

initProxy() {
const data = this.$options.data ? this.$options.data() : {}

return new Proxy(this, {
set(_, key: string, value) {
data[key] = value
return true
},
get(_, key: string) {
return data[key]
}
})
}
}

const vm = new Vue({
data() {
return {
a: 1
}
}
})

vm.a = 2
// ^ Property 'a' does not exist on type 'Vue'.

console.log(vm.a) // => 2
// ^ Property 'a' does not exist on type 'Vue'.

在线版本

如果你查看了在线版本, 可以看到, 我们在使用实例属性 vm.a 时报了一个 TS 错误 Property 'a' does not exist on type 'Vue', 意思是说 vm 实例上不存在属性 a.

阅读全文 »

在 js 中,将内容复制到剪贴板的原理是利用 document.execCommand() 方法进行操作.

document.execCommand()

document.execCommand() 的签名是这样的

1
bool = document.execCommand(aCommandName, aShwoDefaultUI, aValueArgument)

需要注意的是,该命令复制的内容是当前页面选中的内容.

阅读全文 »