0%

定个小目标 ⛳️:实现用 VS Code 编辑默认 vue cli 创建的 vue2 项目,对.vue, .js 等文件有错误检查与代码风格检查(lint)、保存时自动修复(autofix)、按照 Prettier 风格进行格式化。

上网搜索 vscode 的 vue 项目 lint 和格式化,大多文章介绍的是其团队自己一揽子规范,很多规则不通用,还有很多过时、无效的配置也一并贴出来(当前为 2021 年),看得我头都大了 🤯

我只想要一个 vue、eslint、prettier 三者结合的官方默认配置,怎么这么麻烦??
于是我决定痛下决心,分别查询各个官网以寻求最简配置 ⚙️

✅Tips: 只关心配置的朋友,直接拉到最后。

问题的解决思路

经过一轮探索与思考,要想实现上述目标,我们其实要解决三个问题:

  1. 代码检查(Lint),包括错误检查与风格检查
  2. 在 Lint 之后做代码自动修复(autofix)
  3. 使用代码格式化工具(formatter)去做 autofix

具体到 VS Code 这款编辑器的配置,我们需要搞定以下概念以及解决方案:

  • 概念
    • Linter 与 Formatter 的区别?
  • VS Code 相关
    • VS Code 如何识别 Vue SFC(.vue 单文件) 文件?
    • VS Code 如何识别项目的 eslint 配置,并在编辑器中提示错误?
    • VS Code 如何在保存时自动修复 eslint 错误?
    • VS Code 如何通过 Prettier 这款格式化工具,来自动修复 eslint 错误?
    • 如何解决 ESLint、Prettier 之间的规则冲突?
  • 项目配置相关
    • vue cli 创建的默认 eslint 配置到底包含了哪些规则?
    • 如何设置 Eslint 的代码错误规则?
    • 如何设置 Eslint 的代码风格 Prettier 的规则?

Linter 与 Formatter 的区别?

我们首先讲下什么是 Linter:
Linter 是语法检查/代码质量检查工具,不同语言都有自己的版本,比如 JavaScript 的 Linter 有 ESLint,JSLint,Python 有 pylint…而 JS 中目前最常用的就是 ESLint,通过配置规则+ESLint 的命令行工具(CLI),可以实现代码检错、风格检错、自动修复错误等能力。

然后是 Formatter:
Formatter 是指代码格式化工具,这类工具会帮你把代码按照规则进行统一的格式化,保证项目代码的美观、统一。前端有代表性的 Formatter 有 Prettier、Beautify 等,他们都可以规范 HTML、CSS、JS 等前端语言。

那么 Linter 与 Formatter 有什么区别呢?参考 Prettier 官网的解释:Prettier vs. Linters · Prettier,我们可以得知 Linter 主要有两类配置:

  • 代码格式化相关(Formatting rules) :
    • eg: max-len, no-mixed-spaces-and-tabs, keyword-spacing, comma-style…
  • 代码质量相关(Code-quality rules):
    • eg no-unused-vars, no-extra-bind, no-implicit-globals, prefer-promise-reject-errors…
      而 Formatter 如 Prettier,只关心代码格式化的规则,完全不关心代码质量的规则。

所以我们应该发挥各自所长,在项目中:

  • 使用 Linter 来做代码质量检查
  • 在 Linter 中配置 Formatter 的规则,使用 Linter 来做代码风格检查
  • 使用 Formatter 来做代码的格式化

💪 实战:从零开始配置

环境说明:

  • Mac OS 10.15.7
  • vs code 1.50.1
  • @vue/cli 4.5.12
  • 有 eslint 配置的 vue2 项目

初始化 vue2 项目

场景是这样的,通过 @vue/cli 创建一个默认的 vue2 项目,包括 eslint、babel 都是最基础的。
在这里插入图片描述创建之后,用没装什么插件的 vs code 打开项目:
在这里插入图片描述

安装必要 vs code 插件

看到.vue 后缀的文件默认是没有语法高亮的,我们需要安装 vetur 插件来支持

安装完之后,vscode 即支持 vue SFC 文件的语法高亮:
在这里插入图片描述
什么??居然没有错误提示,明明 vue/cli 默认帮我们创建了 eslint 配置的!

代码质量错误检测

其实这里要安装 vs code 的插件 ESLint,他能读取项目中的 eslint 配置,并告诉 vs code,vs code 才可以在编辑器中找到错误并提示出来!
在这里插入图片描述
安装完之后,回到App.vue,可以看到错误的代码有红色波浪线提示,鼠标悬浮还有具体错误原因,eslint(no-undef),这里说明 vscode 已经可读取项目的 eslint 配置,并按照 no-undef(不允许存在未定义的变量)这条规则定位错误!注意,这是属于代码质量类错误
在这里插入图片描述
对于 vue 的 template,代码质量类错误也是可以检测出来:
在这里插入图片描述
可以看到这里错误规则来源于eslint-plugin-vue,这是因为 vue cli 创建的 eslint 规则中,包含了两条继承的规则:

  • eslint:recommended: 负责检查 JS 错误(eslint),来自 eslint

  • plugin:vue/essential:负责检查 vue 的错误(eslint-plugin-vue),来自 eslint-plugin-vue
    在这里插入图片描述

代码风格类错误检测

接下来我们测试下 代码风格类错误 ,在 template 和 script 中都打上多余的空格:
在这里插入图片描述
好家伙,这么丑的代码都不报错,还有没有王法了?!为什么呢,我们不是有配置 eslint 规则吗?怀疑到了我们的两条规则:eslint:recommendedplugin:vue/essential,查阅资料发现:

List of available rules - ESLint - Pluggable JavaScript linter 告诉我们:eslint:recommended 只包含了必要的代码质量规则,对于风格规则,完全不在意。

User Guide | eslint-plugin-vue告诉我们:plugin:vue/essential只包含了 vue 在 ESLint 的解析、以及 vue 错误的检查,对于风格规则也是完全不 care。如果我们想加上 vue 的代码风格规范,应该使用 “plugin:vue/recommended” 规则集。
我们只需改一下 eslint 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
+ "plugin:vue/recommended"
- "plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},

再回到编辑器,可以发现 template 的代码风格校验告警了,而 script 中仍然没有提示。
在这里插入图片描述
其实也很容易想到,当前 eslint 的规则集里缺少 JS 的风格校验规则,是 Prettier 登场的时候了! 我们希望 eslint 里能写入 prettier 的规则,这里需要在项目里安装 eslint-plugin-prettier-vue NPM 依赖,根据其 NPM 文档指引,我们在项目里安装:

1
2
3
4
5
6
npm install --save-dev \
eslint-plugin-prettier-vue \
eslint-plugin-vue \
eslint-config-prettier \
eslint \
prettier
  • prettier: 是 prettier 的核心包
  • eslint: 是 eslint 的核心包
  • eslint-plugin-vue:是 vue 的 eslint 插件,包含多个规则集
  • eslint-plugin-prettier-vue:是 prettier fo vue 的 eslint 插件,包含 prettier 风格检测规则集
  • eslint-config-prettier:禁用 linter 与 prettier 之间会产生冲突的部分规则,保证 Prettier 与 ESLint 不冲突

安装完后我们再为 ESLint 添加风格校验规则集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/recommended",
+ "plugin:prettier-vue/recommended",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},

再回到编辑器,已经可以检测 template, script, style 所有的风格错误了!
在这里插入图片描述

开启 ESLint Autofix

检测出错误,我们该修复错误了,我们可以手动修复(太笨),也可以命令行执行 eslint --fix(太麻烦),有没有更舒服地方式,有,在保存文件时自动修复风格错误!

要开启此特性,我们在 vscode 中,打开 偏好设置preference,点击切换到 JSON 配置文件模式:
在这里插入图片描述
在配置中添加:

1
2
3
4
// 开启代码保存时,eslint执行fix动作
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},

保存后回到编辑器,按ctrl+s保存,可以发现代码根据prettier的规则,一口气格式化好了!
在这里插入图片描述
至此,ESLint 将怀揣 vue 与 js 的质量规则+prettier for vue 的风格规则,帮我们检测代码异常,并自动修复风格问题 🤩

正式宣布,我们完成了在 vscode 下,编辑有 eslint 配置 的 vue2 项目,拥有代码质量检测+代码风格检测以及自动根据 prettier 规则修复的目标了!

其他说明

autofix 的范围

能自动修复的只有代码风格类错误(缩进,换行),代码质量类是没法自动修复的(你当他 AI 吗?自动帮你修 bug)

在这里插入图片描述
如上图,输入 aaa 检测出一条质量问题(no-undef),一条风格问题(缺少;号),点击保存,只会帮你把分号加上 😥
在这里插入图片描述

关于 prettier 风格覆盖

在 eslint 配置中的 rules 字段配即可(更多字段查询https://eslint.org/docs/rules/),例如想覆盖 prettier 的双引号规则为单引号:

1
2
3
4
5
6
7
8
9
10
rules: {
'prettier-vue/prettier': [
'error', // 不符合规则的设为错误,好让eslint修复
{
// Override all options of `prettier` here
// @see https://prettier.io/docs/en/options.html
singleQuote: true,
},
],
},

疑问总结

  • VS Code 相关

    • VS Code 如何识别 Vue SFC(.vue 单文件) 文件?
      • 通过 vetur 插件
    • VS Code 如何识别项目的 eslint 配置,并在编辑器中提示错误?
      • 通过 Eslint 插件
    • VS Code 如何在保存时自动修复 eslint 错误?
      • 偏好配置中开启 :editor.codeActionsOnSave -> "source.fixAll.eslint": true
    • VS Code 如何通过 Prettier 这款格式化工具,来自动修复 eslint 错误?
      • 项目安装 prettier, eslint, eslint-plugin-prettier-vue, eslint-config-prettier
      • eslint 配置中继承 plugin:prettier-vue/recommended 规则
    • 如何解决 ESLint、Prettier 之间的规则冲突?
      • 安装 eslint-config-prettier 依赖,禁用冲突的规则,需要搭配其他包使用,如 eslint-plugin-prettier-vue
  • 项目配置相关

    • vue cli 创建的默认 eslint 配置到底包含了哪些规则?

      • eslint:recommended: 负责检查 JS 错误(eslint),不含风格检测,来自 eslint

      • plugin:vue/essential:负责检查 vue 的必要错误(eslint-plugin-vue),不含风格检测,来自 eslint-plugin-vue

    • 如何设置 Eslint 的代码错误规则?

      • 继承已有的规则集,或通过 rules 手动配置
    • 如何设置 Eslint 的代码风格 Prettier 的规则?

      • 通过plugin:prettier-vue/recommended继承 Prettier 的规则集

配置总结

VS Code 插件:

  • Vetur: 让 vscode 识别 vue SFC 文件,语法高亮、代码检测等
  • ESLint 让 vscode 读取项目 eslint 配置,并在编辑器中提示语法错误、应用 autofix 等

NPM 开发依赖:

  • prettier: 是 prettier 的核心包
  • eslint: 是 eslint 的核心包
  • eslint-plugin-vue:是 vue 的 eslint 插件,包含多个规则集
  • eslint-plugin-prettier-vue:是 prettier fo vue 的 eslint 插件,包含 prettier 风格检测规则集
  • eslint-config-prettier:禁用 linter 与 prettier 之间会产生冲突的部分规则,保证 Prettier 与 ESLint 不冲突

ESLint 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/recommended",
"plugin:prettier-vue/recommended",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {
"prettier-vue/prettier": [
"error",
{
"singleQuote": true
}
]
}
}

VS Code 配置

1
2
3
4
// 开启代码保存时,eslint执行fix动作
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}

以上就是 Vue 项目在 vscode 中 lint/autofix/format 的最简配置 🤓 装备好武器,开始撸代码吧 👨🏻‍💻

参考网站:
Prettier vs. Linters · Prettier: https://prettier.io/docs/en/comparison.html
ESLint rules: https://eslint.org/docs/rules/
eslint-plugin-vue: https://eslint.vuejs.org/user-guide/#usage
eslint-plugin-prettier-vue: https://www.npmjs.com/package/eslint-plugin-prettier-vue

读到博文Hexo常用插件介绍 hexo-symbols-count-time, 发现hexo-symbols-count-time这个好用的插件,能自动统计每篇博客的字数计算估计阅读时间 ,赶紧下载下来玩玩。

1
$ npm install hexo-word-counter

_config.yml 中配置

1
2
3
4
5
6
7
8
9
symbols_count_time:
symbols: true
time: true
total_symbols: true
total_time: true
exclude_codeblock: false
awl: 2
wpm: 300
suffix: "mins."

其中关键参数解释:

  • awl 平均字符长度
    • CN ≈ 2
    • EN ≈ 5
    • RU ≈ 6
  • wpm 每秒阅读的单词数
    • Slow ≈ 200
    • Normal ≈ 275
    • Fast ≈ 350
  • 更多参数

中文的话推荐配置 awl = 2, wpm = 300

在你的Next主题配置文件 _config.next.yml 中配置:

1
2
3
4
5
6
post_meta:
item_text: true

symbols_count_time:
separated_meta: true
item_text_total: false

最后启动博客前记得清除以前的构建数据:

1
2
$ hexo clean
$ npm run server

效果如图:

hexo-plugin-count-time

是不是很有用,继续鼓捣吧!

在网上搜索了一下文章标题,找到一篇博客:在 Next 主题中添加友情链接,这里记录一下步骤,也方便后来者~

找到你的 hexo next 配置文件,我的 next 配置文件是根目录下的 _config.next.yml,搜索 Blog rolls 注释,配置下方的 Links 即可:

1
2
3
4
5
6
7
8
9
10
11
12
# Blog rolls
links_settings:
icon: fa fa-user-friends
title: My friends
# Available values: block | inline
layout: block

# 这里添加友链~
links:
Airing的小屋: https://me.ursb.me/
Hedwig: https://hedwig.pub/
Wall-E Paradise: https://www.qirencloud.com/

效果如图:

hexo-add-friend-link.png

快去添加你的好友吧~

Ayy yo what’s up,这里是Brrruski aka. 搞程序的Gatsby👨🏻‍💻

作为第一篇正式对外的文章,想了很久要分享什么主题才会比较有意思,还要易上手,还要接地气🧐 那最近也是看到朋友的博客(基于Hexo搭建的),眼馋里面的markdown代码块、时间线timeline整理以及自动分类与标签词云呀🤩 (天知道我作为程序员是怎么忍受wordpress / ghost默认的markdown支持的🐶

于是我兴致勃勃地鼓捣了一番Hexo博客,在本地已经装饰的漂漂亮亮了✨ 。到了该部署的环节,我一拍脑袋💡,不如摒弃我的小水管server🚰,玩一次地道的云原生部署玩法吧?

经过一早上的踩坑,终于在云上建好属于自己的一亩三分地了,简直比在深圳买了房子装修完还开心呢(醒醒,你哪来的房子

所以我决定,不如就分享一下我是怎么把我的Hexo博客拎到云上去的吧☁️

网站托管(Serving)

让自己的网站能被大家访问到,我们需要进行名为网站托管的一系列操作。我们先简单回答一下关于上网冲浪🏄‍♂️ 的两个灵魂发问:

  1. 🧐 网页的本质是什么?
  2. 👨🏻‍💻 我们为什么能在浏览器上搜到并看到网页?

1. 网页的本质是什么?

网页的本质其实就是一堆按格式书写的字符,即我们常说的HTML(超文本标记语言),文本的内容大概长这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!doctype html>
<html>
<head>
<title>Bruski's Website</title>
</head>
<body>
<h1>My Intro</h1>
<p>Yo whatsup, this is Brrruski aka Coding-Gatsby</p>
<img src="/image/handsome-selfie.jpg" />
<audio src="/audio/handome-bgm.jpg" autoplay />
<video src="/video/me-skating.mp4" controls />
</body>
</html>

看到里面的标签了吗,我们通过书写这类浏览器能识别的标签,来创建内容、引用其他资源,经过浏览器处理后渲染到屏幕上,就变成我们看到的色彩缤纷、能够交互的网页啦。

2. 我们为什么能在浏览器上搜索并看到网页?

设想我们在网上买衣服,我们先按名字搜到某个牌子的衣服,如果找到了提供该衣服的商铺,购买下单,商家处理好之后发货,不久后你能穿上心仪的衣服啦。

同理,当我们在浏览器的地址栏中输入某个网址的时候,浏览器会发出寻找该网址对应服务的请求,如果找到了,提供该网站服务的服务器会把相应的网页内容返回给浏览器,浏览器解析后,网页内容就呈现在我们眼前了🤩

所以一个网页要想能被别人访问到,需要具备满足以下条件:

  1. 一个能找到你网页的地址(IP+端口或者域名)
  2. 一个能处理浏览器的请求,把资源返回去的服务(HTTP Web服务)

所以网站托管做的事情就是:

  1. 📦 把网页等资源上传到某个地方。
  2. 🤖 启动一个能对外提供服务的HTTP Web服务,把我们的网页内容发送给请求方。
  3. ⛳️ 设置这个服务的访问地址,可以是IP+端口,也可以起别名(域名)。

网站托管的方式

通过提供HTTP Web服务进行网站托管的方式大致可以分为:

  1. 借助能处理静态资源的Web Server,如Apache,Nginx。
  2. 由Web Server动态生成HTML内容,如JSP。

由于我们今天的主题是博客托管,我们只讨论第一种,只提供静态资源的方式。

云原生(Cloud Native)

cloud native

首先我们简单快速了解一下云原生这个概念,这里引用了掘金的文章《什么是云原生?这回终于有人讲明白了》——华为云开发者社区

云原生是一种基于云计算技术的构建和运行应用程序的方法,是一套技术体系和方法论。

云原生(CloudNative)是一个组合词,Cloud+Native。

  • Cloud表示应用程序位于云中,而不是传统的数据中心;
  • Native表示应用程序从设计之初即考虑到云的环境;

Pivotal公司的Matt Stine于2013年首次提出云原生(CloudNative)的概念,对云原生的定义总结为4个要点 DevOps + 持续交付 + 微服务 + 容器。一句话概括:原生为云而设计,在云上以最佳姿势运行,充分利用和发挥云平台的弹性+分布式优势。

图片来自掘金-华为云开发者社区的文章

其实结合实际理解,云原生已经具象化地存在于各大云服务厂商的官网中:云服务器、云存储、云容器、DevOps流水线等等,他就是一个船新的软件开发和部署的新生态,帮助开发者们更简单、更快地打造、发布与维护产品🔫

传统网站托管 VS 云原生网站托管

传统网站托管 VS 云原生网站托管

传统模式托管和云原生托管最大的不同在于:资源部署的维度不同

传统模式按硬件资源为单位部署,云托管按功能服务为单位部署,两者带来的服务架构设计、实际操作与效果都有着很大的差别。

传统网站托管: 我们需要自己维护服务器,把文件上传到服务器的具体路径,接着设置Web Server啊,安装证书 ¥&!# ,一顿操作之后才能完成网站托管。

云原生托管:文件打包后,上传到对象存储服务,设置一下存储桶为静态网站托管模式,嗯就可以了,什么域名啊、证书啊全部自动生成。什么,你想让你的网站在全国各地的访问速度都更快一点?那再到网页上点击配置一下CDN加速服务,让它将你的网页分发到全国各个边缘节点中,通过统一的加速域名来访问,用户访问速度杠杠的。

由此可见云原生托管不仅简单便捷、灵活按需、省心省钱,而且服务的效果和质量都比传统模式强😎 既然云托管这么香,那我们赶紧进入实操环节体验一把🤨

实战: 把这只Hexo博客拎到云上吧

⛳️ 明确我们的目标:将Hexo博客项目快速地部署,可以通过HTTPS域名访问。

注意:实战的云服务商选择腾讯云,其他云服务商操作同理

前置准备

  • 安装好gitNodeJS与Npm的环境
  • 一个hexo博客工程,并设置好github仓库关联(其他代码托管服务同理)
  • 一个腾讯云账户

Hexo博客工程可以下载示例工程:

1
2
3
4
# Github
git clone https://github.com/bruceeewong/hexo-demo.git
# Gitee码云
git clone https://gitee.com/bruceeewong/hexo-demo.git

安装npm依赖

1
npm install

预览页面效果

1
npm run server  

通过浏览器访问的本机地址 http://localhost:4000,查看效果:

最后测试打包命令是否正常:

1
npm run build

如果在当前目录下新增public目录,说明打包命令可用,就进入下一步。

开通网站托管相关的云资源

我们需要开通以下资源:

开通对象存储服务&上传静态资源

根据指引,为了存储我们的静态资源,我们需要创建一个存储桶资源。

注意存储桶的访问权限我们先设置为 公有读私有写,方便在没有接入CDN服务前直接访问网页。

接下里来两步直接按默认的来,点击创建。


存储桶创建好之后,我们找到文件列表>上传图片按钮,挨个把本地构建好的public下的文件夹&文件上传(好累,这里只是让你体会一下没有自动化工具的辛苦😂


到这里,我们已经把静态资源都传到存储桶中了,接下来就是设置其访问方式。

开启静态网站托管模式

到这里,网站的托管就完成了,是不是不敢相信?我们把访问节点的URL复制到浏览器试试:

怎么样,我们是不是已经完成了定下的目标:将Hexo博客项目快速地部署,并可以通过HTTPS域名访问。

你能做的,岂止如此

复盘一下刚才的操作,最费时的就是手动上传静态文件了(可能还不如 scp 传到服务器快呢)如何摆脱手动上传文件?解决的办法无疑就是将这部分操作自动化,让我们接入Coding CI DevOps服务,创建一条CI/CD流水线,来拉开跟手工部署的差距。

搜索Coding CI服务:

创建项目,这里只勾选 构建流水线 即可:

选择流水线模板 React + COS(我们要的只是对接COS上传的部分)

代码仓库选择 Github 或 码云(需完成授权),选中我们的仓库;关掉的单元测试选项(我们的hexo项目没有此命令)

接下来的上传COS Bucket配置部分参考下图。注意不勾选“创建后触发构建”,还有一些要配置的地方。


修改一下环境变量>产物的路径名(hexo的产物路径叫public

如果选择的是github,触发的分支注意有可能需要设置为 main(不知道微软为啥要改掉master)

最后点击构建,短短23秒流水线就执行完成了。

这意味着我们以后只需编辑与提交代码,构建和部署上传的工作交给流水线去做就好了😆

🚀 最后一步,配置CDN加速服务

CDN内容分发网络的工作方式大致如下,通过CDN服务的接入,把源站的文件分发至各个边缘节点。

为了能让用户能从最近的CDN节点获取资源,我们应该只对外开放CDN域名,隐藏存储桶的访问路径(可以设置为私有读写)

落到腾讯云这,有两种方案:

  • 使用COS提供的默认CDN加速域名
    • 优点:简单快捷,一键生成带ssl证书的域名
    • 缺点:域名太长
  • 配置自定义加速域名
    • 优点:可定制域名
    • 缺点:配置稍微复杂一些,需要前往CDN控制台配置

限于篇幅有限,就只介绍默认CDN加速域名的配置:

鉴于我们的hexo博客是将markdown生成html文件,为了防止因为缓存而导致用户不能看到最新更新的文章,我们还需要设置CDN的缓存配置。

配好默认CDN域名后,把html文件的CDN节点与浏览器缓存都设为 不缓存



最后,我们通过CDN加速域名 https://hexo-demo-1257249827.file.myqcloud.com/ 来访问一下我们的页面:

快速地打开了,没有任何问题 🚀

总结

至此,我们的Hexo博客就已经正式在云上托管了☁️,开罐啤酒庆祝吧,Hooray🍺

我们不仅完成了基础目标:快速地部署,并可以通过HTTPS域名访问,还通过添加devops服务与CDN服务,让我们的开发与访问速度都提升了🚀

其实能折腾的东西还有很多,像我还做了Hexo网站主题定制、自定义加速域名、强制HTTPS转换、SEO优化、ICP+公安备案等,这些操作留给你们去探索吧,我只是那个把你们带上云端的男人😆

今天就写到这了,还有更多有趣的云原生玩法,一边实践再一遍分享吧🔥

作为一个程序员,要是因为网络原因,不能享受全世界程序员的发展成果,那就真的太亏了=。=

比如 github 看到一个很棒的项目,激动地打下git clone,结果…

1
2
Cloning into 'awesome-project'...
fatal: unable to access 'https://github.com/god/awesome-project.git/': LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 60

由于网络连不通,又一位少年/少女失去了编程梦想,可惜!可惜!

本文就以作者实际探索,介绍 mac 设置命令行代理的 2 种方案:手动设置变量 与 使用proxychains工具 ,希望能帮到正在阅读本文的你,一起起飞 🚀

✅ 前置准备

首先,你的 mac 得有一个 socks 代理工具,以及可用的 socks 代理服务

本文重点不是这里,but sadly,这里又是全流程的重点,得靠你自己探索了,少年。

作者的 mac 有 socks 代理工具,它自动运行着两种协议的代理端口:socks5 代理端口与配套的 http 代理端口,都可用作请求的代理转发:

1
2
socks5 127.0.0.1 1086
http 127.0.0.1 1087

如果你的 mac 也满足条件,那么继续往下看吧 🤓

🚀 方案一:直接设置终端代理环境变量

这是最简便的方案,无需安装任何工具

每个终端会话都可以设置 $http_proxy$https_proxy环境变量,来控制终端的 http 请求代理。

首先保证当前终端会话没有设置代理:

image.png

我们来试下拉取一个别人分享的 mysql 命令行 gist(即文本笔记 📒),保存为 mysql_gist 文件。

链接:https://gist.github.com/hofmannsven/9164408

1
curl -o mysql_gist https://gist.github.com/hofmannsven/9164408

image.png

嗯,Connection refused,早已被拒绝习惯了 😢

擦干眼泪,我们接下来在命令行输入代理配置(=号左右不要有空格):

1
export http_proxy=http://127.0.0.1:1087; export https_proxy=http://127.0.0.1:1087;

我们再次检查 http 环境变量:

image.png

Yes,生效了,那再下载一遍试试看?

image.png

芜湖!成功把 github gist 下的配置下载下来了!不再是绝望的 Connection refused 或者 3kb/s 了 🚀

别急,还没完

上边的设置只是针对当前会话,如果关掉当前终端再开一个,悲剧依旧会重演 💔

我们可以把配置命令作为别名(alias),这里就叫 proxy 吧,写到.bash_profile里吧,方便以后取用:

1
alias proxy="export http_proxy=http://127.0.0.1:1087;export https_proxy=http://127.0.0.1:1087;"

那么以后在命令行,如果遇到下载不通的情况,可以在原始命令前加上 proxy 即可:

1
proxy curl -o mysql_gist https://gist.github.com/hofmannsven/9164408

image.png

Nicely done!

不建议在 bash_profile 中写死 export http_proxy=xxx,一是显示声明总比隐式声明好,二是节省你代理服务的流量,我们大多数场景使用直连就行了。

取消代理

当 export 了之后,当前终端会话的 http 请求都会走代理,如果要取消,需要手动输入:

1
unset http_proxy https_proxy

这样的方式可行,但还不够方便,不能按需使用,比如我只想某一条命令的请求走代理,而不是全局都走,我们把这个问题留在下面的方案解决吧。

方案总结

优点:

  1. 简单、无依赖:只需设置环境变量http_proxyhttps_proxy,即可为当前终端会话的 http 请求设置代理啦!

缺点:

  1. 无法做到按需使用:设置了代理后,当前会话之后的所有 http 请求都会走代理,如要取消需要手动 unset http_proxyhttps_proxy

🚀 方案二:使用 proxychains 工具

参考文章:

📚 Mac OSX 使用 proxychains-ng

📚 故事:试图不关闭 SIP 在 macOS Sierra 上使用 proxychains-ng

proxychains 是一个 UNIX 程序,可以帮助我们代理终端发出的请求,支持 http, https, socks4, socks5 的代理类型。

ProxyChains is a UNIX program, that hooks network-related libc functions in dynamically linked programs via a preloaded DLL and redirects the connections through SOCKS4a/5 or HTTP proxies.

📦 安装

macOS 可以通过 brew 来安装,不过巨慢(一个怪圈:慢是因为没配好终端代理,而配置终端代理又要到外网下载工具 🤪

1
brew install proxychains-ng

还可以尝试源码安装,这里参考 Mac OSX 使用 proxychains-ng 的安装步骤,我没试验过.

1
2
3
4
5
6
7
$ git clone https://github.com/rofl0r/proxychains-ng

$ cd proxychains-ng
$ ./configure --prefix=/usr --sysconfdir=/etc
$ make
$ make install
$ sudo make install-config # 安装proxychains.conf配置文件

注:mac 上 make install 会报错。因为 Mac 下用 Homebrew 安装的默认为/usr/local/etc/proxychains.conf

解决方法:

1
2
3
4
5
6
7
8
cd configure
vi config.mak
将:
bindir = /usr/bin
libdir = /usr/lib
修改为:
bindir=/usr/local/bin
libdir=/usr/local/lib

🔖 配置 proxychains

vim 打开 /usr/local/etc/proxychains.conf 配置文件:

在[ProxyList]下添加 socks5 代理 (115 行,vim 快捷跳转 :115回车 )

1
2
3
4
5
# 代理端口一定要和shadowsocks中的保持一致
# 如果有不明白的可以查看93110
[ProxyList]
socks5 127.0.0.1 1086 # 配socks5
# http 127.0.0.1 1087 # 也可以配为http

具体代理类型配了 socks5 和 http 有什么性能上的不同,我不清楚,有知道的大神可以在评论科普一下

🎼 使用前的小插曲

如果不是 macOS 10.11 或更新,则跳过本节 🤪

Mac OSX 使用 proxychains-ng 提到:

macOS 10.11 后下由于开启了 SIP(System Integrity Protection) 会导致命令行下 proxychains-ng 代理的模式失效,如果使用 proxychains-ng 这种简单的方法,就需要先关闭 SIP。

想想苹果设置这个策略肯定是有安全考虑,有没有更优雅地解决方案,网上冲浪找到这篇文章 故事:试图不关闭 SIP 在 macOS Sierra 上使用 proxychains-ng ,他提到 SIP 策略的细节:

根据苹果的 官方说明,以下路径受到保护:

  • /System
  • /usr (不包含 /usr/local)
  • /bin
  • /sbin
  • Apps that are pre-installed with OS X

于是解决方案是,将工具如 curlssh 的二进制文件拷贝到非受保护路径:

我们在当前用户目录下创建自定义目录:

1
mkdir -p ~/local/bin

~/.bash_profile中加入 PATH:

1
export PATH=/Users/xxx/local/bin:$PATH

接着拷贝要用的工具即可

1
2
cp $(which ssh) ~/local/bin/ssh  # 拷贝 ssh
cp $(which curl) ~/local/bin/curl # 拷贝 curl

🚀 使用 proxychains

使用方法巨简单,在原始命令前加上 proxychains4 即可:

1
proxychains4 curl -o mysql_gist https://gist.github.com/hofmannsven/9164408

image.png

成功,并且不污染全局代理配置,舒服。

同样我们为 proxychains 配置 alias,就可以简便地使用了!

1
2
3
# ~/.bash_profile

alias pc='proxychains4'

方案总结

优点:

  1. 使用简便,直接在原始命令前加 proxychains4 前缀即可
  2. 支持多种代理的类型
  3. 按需使用,不污染全局代理配置

缺点:

  1. 安装可能受阻,配置相对麻烦
  2. macOS 10.11 之后的版本需要用小聪明绕考 SIP 策略。

🍳 总结

两种方案都是作者亲测可行,如果有疑问可以下方留言,或者 📧 邮件我 bruskiwang@outlook.com

已经没有什么能阻碍你了,享受全世界的开源代码吧 🚀

明天就是儿童节咯,写篇五月总结作为自己的儿童节礼物吧~如果要给五月设一个关键词的话,我想大概是:浮躁地成长着。
2021 年还剩 1 个月就要过去一半了,虽然没有虚度光阴,但总觉冲劲不足,好多事说到没做到。怎么说呢,就感觉浮躁的心态又卷土重来,不太愿意慢下来做一些事,比如写作,比如反思。在这五月的尾巴,稍微给点时间自己。

五月开头是假期,过得相当开心,先是和 KTV 四少去长沙探店、美食、听说唱音乐节,再是前往武汉——度过我最灿烂的青春的城市,回母校和 KS 的老炮儿们再聚首,跳舞、跑卡丁车、校园电驴瞎逛,借用结扎的话:“好久没感觉这样放肆的开心了”。

去了趟武汉结果得了感冒,回来蓝瘦的雅痞,手头拍摄的长沙武汉旅游的素材一直没剪成 VLOG,过了感冒后,又不愿意花时间在 VLOG 上了…一面羡慕着国外的人该工作工作,该玩玩,多会享受生活;一面自己莫名地不愿把时间花一点在这些看起来浪费时间无意义的生活美好上,多奇怪哦。

五月中又是广州之旅,和弯弯、脑子&他朋友一起听 M_DSK 音乐节,同时打卡融创雪世界,继神农架后第二次滑雪。开着脑子的宝马顶配 530,一路吹 B 一路吃,尝试了单板滑雪,也算是好好陪弯弯玩了一次(话说跟我在一起真的会无聊吧?毕竟我是连自己都不愿意多给享受生活的时间的人)

其实这个月成长上倒是收获蛮多的,比如第一次完成了直播组的活动页+挂件需求,终于能说自己是“直播组”的前端了哈哈哈;比如理财上把微淼前十周的课学完了,初步建立了投资的框架,也把资金都聚拢,真正有计划地去在股票、基金、REITs、债券领域建仓;项目上也是独立完成了许多有意思的尝试:状态机在前端的应用、对 React Hook 的使用和封装有了更深的认识、尝试用数据结构去完成前端的组件能力;滑板上 Ollie 高度突破两立,并顺带练会了 50-50……其实成长还是可喜的。

困扰我的点在于,月初指定的目标是什么,现在已经忘了…并且每个周末的大好时光,我都有点迷茫该做什么,等到定好计划,又效率很低导致只能完成 10-20%…明明觉得时间紧,却把整块时间花在看视频、打游戏上…想努力又觉困乏,说搞个人 IP、小程序,也只是雷声大雨点小,最后不了了之。好讨厌的感觉。

究其原因,我觉得有几点吧:休息不好导致精神不好;心态变得浮躁,什么都想做,什么都做不好;注意力的弦不懂松弛有度,学不好、玩不好;计划不甚清晰,不好落地,甚至忘了自己最初的目标;最后就是,执行力太差了。

与其说一直绷着,什么都想做,不如在六月做减法,只专注不超过三个目标,给自己留时间思考、写作。像明天要上线的摩尔庄园的宣传片:“小时候,快乐很简单;长大后,简单很快乐”,或许我的不快乐,就是因为我把心态弄得太复杂了吧。

晚安,明天起,做一个简单的小孩,儿童节快乐。

今天玩了期待已久的本子《古木吟》,这个本由于出版时太火爆,以至于现在要找到拼车的只能是萌新了,经历几次换本的尴尬后,今天终于排到了,弯弯同学也算是了结一桩心愿 😄

剧透什么的就不搞了,就说说感受,一句话:感人,温润。看完剧本听完语音后,剧情基本已经摊明了,故事串联起来后,情感就如一股暖流,从紧张疲惫的大脑开始温润全身。每个人都会在结尾做评述,当分享完内心感受时,觉得意犹未尽,此本立意的确不错,悬疑设计也是合情合理,没有太跳脱。

我玩的是文弱男,可惜没有亲哥哥的我,没有收到太强的共鸣。弯弯还有其他两个妹子都被触动到,流泪了。

弯弯跟我说,她看到剧中情侣情投而意不能合,联想起生离,联想到我,就有一股触动,当然还有许多她的回忆。是呀,离别于我们,迟早要到来….既然无法避免,那不如享受当下的每一秒相处,不要太多期望也不要留下遗憾,当一对潇洒的都市情侣吧。

另外,游戏结束之时,cxy 给我发消息说,现任介意,于是要删掉我的联系方式。我愣了一下,笑了笑回复,祝好。时间可以把一切冲得很淡,以至于这般离别也变得风轻云淡。那就把这段回忆尘封起来吧。

anyway,这是一篇日记,也不能剧透,那用剧中的话来结尾吧:

“愿你心意坚韧,不被昔时梦魇所扰。愿你未来之路,不受追忆所拌。”

平淡的下午写着代码,突然系统弹窗:”/目录空间不足!!!”,一点 “检查”一看,原来还是自己刚学 linux 那会儿分配的 20G 可怜空间,而如今已经不想打开 windows 了,感叹到,该给 linux 涨涨地位了. 于是买来一张 250GB nvme SSD, 又不想重装系统, 想把系统盘一字节不落的 完美迁移 ,于是乎开始了迁移的折腾之旅~~~

环境说明

本人的环境信息如下:

  • 原 250GB nvme SSD 装了双系统: 200G 给到 win10, 20G 给到 Ubuntu20
  • 8Gx2 = 16G 内存
  • Ubuntu 分区情况
    • /: 根目录 17G 主分区
    • /boot: 引导分区 1G 逻辑分区
    • swap: 交换分区 2G 逻辑分区
    • /home: 存储于机械硬盘,单独拆分出来: 100G

先结论后细节

整趟下来,踩了不少坑,终于把流程和思路理顺了! 期间查阅了很多以前不懂的 linux 知识,也算饶有收获~
在这里插入图片描述

折腾记录

购买 SSD,安装 SSD

此处知识点:

  1. ssd 固态硬盘 sata 的好还是 m.2 好呢?
  2. 一篇文章讲清什么是 NVMe

如今 SSD 价格不算很贵,250GB 的西部数据 nvme 卡在某东上买花了 308+, 不得不说如今的硬件做的都很精致呀, m.2 接口的 SSD 小巧精致, 即插即用. 当然需要一颗专用螺丝固定在主板上 (螺丝是不随卡附赠的噢!) 一般主板支持几个 m.2 插槽就会配几个, 我的是 2 个插槽.

在这里插入图片描述

很快安装完毕,盖上机箱玻璃,嗯,有那种 强化+1 的满足感,哈哈哈.

制作 Ubuntu 启动 U 盘, 进入 live 环境

制作启动盘的原因是,我们需要一个能够操作硬盘的沙箱环境,相比 grub secure 那样纯命令行的环境,ubuntu 的 live 环境对于不那么熟练的人来说,还是很友好滴.

我是在 windows 环境下用 UltraISO 把下载的 ubuntu20 镜像文件写入 u 盘,这里直接看已有的教程吧:Ubuntu 20.04 LTS 桌面版详细安装指南

格式化新硬盘的分区

这里有很多选择:

  • fdisk
  • parted
  • Ubuntu 系统自带的 Disks 工具

在 linux 下给硬盘分区没搞过,于是了解一下 fdisk 和 parted,他们都是 linux 的磁盘管理命令,fdisk 只能操作 2TB 以下的分区,parted 是更新更强大的分区工具,支持 GPT 分区格式.

这里踩坑预警!! 如果想完美迁移系统盘,原来是什么分区类型,就按什么类型分.比如我原来是msdos分区,尝鲜使用gpt分区,在修复 grub 引导时就出错了...

第二个坑是手动设置分区时还会提示 4k 对齐警告(知乎:4K 对齐,让你的 SSD 飞上天! ),看起来硬盘存储不是从我们想象中位置 0 开始呢- .-

好吧,我不装了,老实用自带的 Disks 工具分区吧

在这里插入图片描述

分区方案参考文章
Ubuntu20.04 操作系统安装及重中之重:系统分区 > Linux 主分区,扩展分区,逻辑分区的联系和区别 > Linux / boot 分区的建议大小是多少?

经过思考,整张 250GB 卡都给到 ubuntu, 我的分区方案如下:

在这里插入图片描述

硬盘根目录数据完整拷贝

参考文章:迁移 linux 系统到新硬盘

首先要知道: Linux 一切皆文件, 所以拷贝系统其实就是拷贝文件!

那这里使用dd 命令来进行字节级别的迁移,我的根目录所在的分区是/dev/nvme0n1p5,新硬盘划分的是/dev/nvme1n1p2。

1
dd if=/dev/nvme0n1p5 of=/dev/nvme1n1p2

由于 dd 命令没有展示中间过程,因此使用另一条命令来让他输出中间过程:

1
watch -n 5 killall -USR1 dd

17G 的数据在 nvme ssd 之间传输没有什么压力,很快传完

在这里插入图片描述

这里要注意,dd 命令也会拷贝 uuid 过去,意味着,新分区与旧分区的 uuid 是一样的。后面修改挂载信息会再提到.

拷贝完之后,还要更新一下分区信息,否则挂载后还是会显示原来的分区大小和使用情况:

1
2
3
umount /dev/nvme1n1p2
e2fsck -f /dev/nvme1n1p2
resize2fs /dev/nvme1n1p2

BOOT 引导盘数据拷贝

同样 /boot 如果之前单独拆分出来,现在也要拷贝至新硬盘,但这里要避免 uuid 的重复,两个办法:

  1. 使用 dd 复制,然后修改 UUID
  2. 分区后自动产生新的 uuid,使用cp等文件拷贝方式拷贝引导盘数据

这里我选了后者.当然在 live 环境下,要学会自己用mount命令挂载盘符来操作噢.

更新新的根路径分区 uuid

参考文章:Linux 修改分区 UUID

由于不确定是否能成功,我想保留原有的盘符不动(方便回退),这样就会导致根目录的两个分区 uuid 相同,可能在引导时会错误,所以查阅资料,尝试改变新分区的 uuid.

其实也挺简单,使用系统自带的uuidgen命令产生 id, 然后作为参数更新新的分区,再写入新的根路径下/etc/fstab文件

1
uuidgen | xargs tune2fs /dev/nvme1n1p2 -U

执行命令查看最新盘符的 uuid

1
sudo blkid

在这里插入图片描述
复制最新根目录的 uuid,写入新根目录下的/etc/fstab,这里还是要先挂载盘符噢
在这里插入图片描述
到这里,数据复制就完成了

修改 Grub 引导

直接推荐使用 boot-repair 工具,安装方式如下:

1
2
sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt install -y boot-repair

安装完之后,运行命令会调起交互界面

1
boot-repair

这里注意要选择高级选项,手动指定新的引导盘,然后按提示修复引导.

在这里插入图片描述
修复完毕,重启再进,系统完全没变,但是容量已经变为舒服的 184G 了!
在这里插入图片描述

后记

一趟踩坑下来又花费了我美好周日的一下午,写文章花了一晚上,但是谁叫我们是 coder 呢,学了好多硬盘相关的硬件和 linux 知识,最后升级成功,就是爱折腾~~

最后,装备强化完毕,又可以愉快地写代码了,冲!

在这里插入图片描述

查看企业财报就像相亲,需要了解对方的基本情况。如何从企业财报里找到基本信息,课程以海天味业为例:

初次接触

  • 是谁?——公司信息
    • 佛山市海天调味食品股份有限公司
  • 住哪儿?——注册地址
    • 广东省佛山市文沙路 16 号
  • 成立/上市日期
  • 干啥的?——所属行业
    • 看所处行业情况
      • 年报-第三节:公司业务概要——行业发展现状 或 i 问财查看行业相关公司
      • 在调味品行业内实施相关多元化,产品涵盖酱油、蚝油、酱、醋、鸡精、味精、料酒等调味品
    • 看收入情况
      • 营业收入规模
  • 成长经历:近期重要动态、重要事件
    • 近期重要动态
      • 经营情况讨论与分析
    • 重要事件
      • 看分红
  • 家里几口人——家庭成员
    • 看股东
      • 普通股股份变动及股东情况
    • 看董监高

深入接触

  • 表面上是否靠谱:审计意见
  • 实质上是否靠谱:三表一注
    • 资产负债表
    • 利润表
    • 现金流量表

实操

  • 选股——i 问财
    • 2016年到2020年,roe大于15%,净利润现金含量大于80%,上市大于3年,行业
  • 搜索同行业龙头公司——萝卜投研
  • 下载五年的年报——巨潮资讯网
  • 查看年报
    • 审计意见
      • 重要提示
      • 第十二节 财务报告
    • 业务范围
      • 第三节 公司业务概要
      • 业务相似度
    • 行业信息
      • 第三节 公司业务概要
      • 第四节 经营情况讨论与分析

举例

浙江美大

  • 所属行业:家用电器-白色家电-小家电
  • 萝卜投研查询行业
    • 老板电器:强相关
    • 苏泊尔:一定相关
    • 九阳股份:弱相关
    • 新宝股份:弱相关
  • 行业发展情况
    • 2020 受新冠疫情的影响,厨电行业经历了严峻考验
    • 未来随着城镇化率的不断提高,我国厨房电器行业仍有较大空间。
    • 占比不高,增速很快
      • 2016 年至 2020 年集成灶行业零售额复合增速达 25%
      • 集成灶销量在烟灶产品总销量的占比分别为 3%、5%、9%和 11%
    • 继续领先于行业第二梯队企业,保持行业领军地位。