分类目录归档:技术

silver mercedes benz emblem on blue surface

OneInStack 下部署 WordPress Multisite 的 Nginx 转发规则

在 OneIn Stack 下如果需要配置一套 WordPress MU 的话,需要配置 Nginx 相应的转发规则。具体的规则如下:

 if (!-e $request_filename) {            
 	rewrite /wp-admin$ $scheme://$host$uri/ permanent;            
 	rewrite ^(/[^/]+)?(/wp-.*) $2 last;            
 	rewrite ^/[^/]+(/.*.php)$ $1 last;    
 }    
 location / {        
 	try_files $uri $uri/ /index.php?$args;    
 }
Code language: PHP (php)

将上述规则放置在 /usr/local/nginx/conf/rewrite/wordpressmu.conf ,并在创建 VHost 时选择对应的主机即可。

programming language

TailwindCSS 下的响应式设计

前言

我自己在最近的一段时间里,整体是比较喜欢 TailwindCSS 这类样式框架的,它可以非常灵活的定义样式,从而可以十分方便的进行创意类的 UI 设计,实现一些独特的 UI 特性。不过,由于我并非一个专业的前端,也不曾研究过响应式设计。这让我在进行前端开发过程中,吃尽了苦头。

痛定思痛,认真的学习了一下 TailwindCSS 下的响应式设计,为以后的开发做好准备。磨刀不误砍柴工嘛。

正文

设计理念

在进行 TailwindCSS 下的响应式设计时,需要考虑到其整个设计系统的基础 —— Mobile First(移动优先)。

基于移动优先的理念并不新奇,诸如 Bootstrap 之类的框架早已经教会我们移动优先。

Mobile first, responsive design is the goal.

Bootstrap

在这种设计理念上,我们应该做的是先设计移动端的样式,并根据屏幕的不断扩张,变成一个更加丰富的 UI 和界面。

这一点对于做研发的我来说,是一个非常反直觉的事情:在绝大多数场景下,我在开发产品的时候,都是看到的桌面端的样式 & 功能,我下意识的以为,桌面端才是应该首要设计的界面。但无论是 Bootstrap,还是 TailwindCSS,其实都是首要设计移动端的

d2b5ca33bd970f64a6301fa75ae2eb22 7

理念的变化没有跟上,导致我对于 TailwindCSS 的类样式的理解不到位,在设计时会出现错误。

断点(breakpoint)的作用

在进行响应式开发的时候,断点是非常重要的,借助于 CSS 3 提供的 Media Query,我们得以在不同的样式尺寸下应用不同的样式设计。

而在 TailwindCSS 当中,根据最小屏幕宽度(为什么是最小而不是最大?因为默认应用在移动设备上,更大的尺寸使用 Media Query 来控制)默认提供了 5 组不同的断点,分别是 sm(640px)、md(768px)、lg(1024px)、xl(1280px)、2xl(1536px),以及不加任何断点情况下的 default 样式。

对于绝大多数的应用来说,处理好 default(手机)、md(平板)和 lg(PC),就已经足够,对于一些面向更 Geek 的场景(比如开发者),他们使用的设备性能和参数更高,可以再定向配置 xl 和 2xl 的样式。

自定义断点

在实际开发过程中,根据用户的场景的不同,TailwindCSS 的默认断点可能并不能满足你的诉求,这种情况下,你还可以根据自己的需要,修改默认的断点的配置(甚至是将其从移动优先调整为 PC 优先:将 min-width 模式调整为 max-width 即可)。

具体可以参考 TailwindCSS Customize Screen Size

总结

在 Tailiwind CSS 下进行响应式开发时,切记从小到大,而非从大到小,不然会让你调试样式的时候十分痛苦。

延展阅读

person using black laptop computer

使用 Stylish 巧妙破解基于 CSS 的复制限制

本文内容仅用于学习和技术研究。请不要用此作恶。

白宦成

在一些网站上,出于版权或增长的诉求,一些网站会在站点内部加入防止复制内容的限制。作为一个内容创作者,我是支持(因为版权原因而不得不选择)这样的行为的。但另一方面,我自己也需要进行一定的笔记,对于长段的内容,显然,直接复制原作者的内容更适合我。因此,我也不得不研究一下,如何破解这种样式的限制。

为什么 CSS 能禁止复制?

CSS 当中提供了一个属性 user-select 可以用于设定文字是否可以被选中,对于非技术人员来说,无法被选中,自然无法使用 Ctrl + C 来复制内容。在这种情况下,对于非技术人员,就可以实现很好的防复制了。

不过,CSS 防复制不算多见,我见的最多的还是以 Javascript 的方式来禁用复制和 Devtools 的。

这个属性的值有以下五种,其中 none 是用于防止复制的,设定为 None 后,即使你的内容是文本内容,也无法被选中,就无法直接使用 Ctrl + C 来完成复制了。而 text 则是可以选择文本,其他的几个属性,你可以在 MDN 的语法说明中找到。

user-select: none;
user-select: auto;
user-select: text;
user-select: contain;
user-select: all;
Code language: HTTP (http)

使用 Stylish 来破解 CSS 的限制

类似油猴脚本可以在目标网页上加载 Javascript 文件,Stylish 可以在目标网页上加载 CSS ,并按照 CSS 的计算权重,让我们的代码可以得到执行。基于这个能力,我们可以覆盖原本网页上样式,来实现将 user-select 的值修改为我们需要的值。

1. 安装 Stylish

前往 Google Chrome Extension Store 安装 Stylish

2. 找到不能复制的文字对应的样式类

在浏览器中打开开发者工具,定位到你需要复制的文本元素,在右侧的调试工具中切换到「计算样式」,就可以在其中找到 user-select属性,并可以看到对应的样式类选择器,复制选择器。

d2b5ca33bd970f64a6301fa75ae2eb22 8

3. 在 Stylish 中新建一个样式文件,并在其中添加对应样式类的代码

因为我们只需要修改复制,所以只需要将对应的属性的值做一个简单的修改即可。

d2b5ca33bd970f64a6301fa75ae2eb22 9

4.设置生效网站

为了减少这段代码影响到的页面,你可以在下方的应用对象这里设定具体生效的网站,从而降低对于其他站点的影响。

d2b5ca33bd970f64a6301fa75ae2eb22 10

总结

本次针对 CSS 禁止复制的研究帮助我节省了大量的研究的时间,有效的提升了我进行研究的效率,真的不错!

silver mercedes benz emblem on blue surface

如何处理 Gutenberg 开发过程中的 Minified React error?

在开发 Gutenberg 插件时,经常会出现下面这样的提示:

Uncaught Error: Minified React error #231; visit https://reactjs.org/docs/error-decoder.html?invariant=231&args[]=onClick&args[]=object for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
Code language: PHP (php)

上述提示表示当前的编辑器中出现了一个错误,但由于 React 的 Minified 设置,这些错误没有办法被打印出来。

在这种情况下, React 接管了默认的报错,让应用不至于崩溃,但另一方面,也让我们失去了处理这些问题的可能。因此,在本地的开发环境,最好还是将这个功能给关掉。

如何关闭默认的错误处理?

wp-config.php 文件中添加如下代码即可。

define('SCRIPT_DEBUG', true);
Code language: JavaScript (javascript)
26a5088bedce6368203d40ac619ac827

从头梳理,看看中国的 ICP 备案制度

对于生活在中国互联网环境中的开发者来说,ICP备案(后称「备案」)是一个很难绕过去的话题,但凡你需要正经的建设一个网站,那么备案就是一个必须要做的事情,不然可能会出现各种奇奇怪怪的问题。但,你是否思考过,为什么我们需要备案?你是否了解过备案二字背后的深层含义?

为什么我们需要备案?

备案的要求和历史,可以追溯到 2000 年 9 月 20 日国务院第 31 次常务会议通过的一个管理办法 —— 《互联网信息服务管理办法》(后称信息管理办法),由时任总理朱镕基先生签发。后续我们所进行的一切备案工作,其实都是这个信息管理办法的延展。

在《互联网信息服务管理办法》当中,第二条说明了什么样的情况才需要进行备案:在中国境内从事互联网信息服务活动。

第二条 在中华人民共和国境内从事互联网信息服务活动,必须遵守本办法。

互联网信息服务管理办法, 2000 年 9 月 20 日

这一条也解释了,为什么 Facebook、Google这些网站也可以正常运转,因为他们严格意义上来说,并不算在中国境内从事相关的信息服务活动(但也没保证你一定能够访问)。同样的,如果你自己的网站托管在海外的服务器上,一样不需要备案(但同样不保证你一定能访问,毕竟你不在境内提供服务,网络出现波动啥的非常正常)。

圈定了范围之后,第三条规定了不同的互联网信息服务都是什么样的类型,进行了定性操作。

第三条 互联网信息服务分为经营性和非经营性两类。经营性互联网信息服务,是指通过互联网向上网用户有偿提供信息或者网页制作等服务活动。非经营性互联网信息服务,是指通过互联网向上网用户无偿提供具有公开性、共享性信息的服务活动。

互联网信息服务管理办法, 2000 年 9 月 20 日

而在完成了定性操作后,紧接着在第四条声明了不同服务类型应该执行的策略:经营性采取许可制度,非经营性采取备案制度。

第四条 国家对经营性互联网信息服务实行许可制度;对非经营性互联网信息服务实行备案制度。

互联网信息服务管理办法, 2000 年 9 月 20 日

至此,我们熟悉的 ICP 备案走上了台前。而我们现在了解到的各种具体的备案的细节,则是在管理办法内容的延展,如果你对于这些内容感兴趣,可以详细的阅读这个信息管理办法。

在 2005 年 1 月 28 日,在《互联网信息管理办法》之上的细分管理办法《非经营性互联网信息服务备案管理办法》(后称非经营性管理办法)也相应出台,对于非经营性互联网信息服务进行了更加明确的安排和说明。我们所熟悉的备案登记表、省级通管局、网站底部公示备案编号等描述也出现在了非经营性管理办法当中,网站的备案事项,也正式被推行。

备案到底在备案什么?

备案对于很多人来说,最麻烦的不是搞不清楚怎么备案,而是搞不清楚如何处理域名、网站、 服务器、个人之间的关系。而所有的这些关系,其实可以用一个词来说明 —— 「双绑定制度」。

现行的网站备案制度其实是一种“双绑定制度”,一方面将网站和所有人绑定在一起,另一方面,将网站和它的接入商绑定在一起。一旦某个网站出现了问题,则需要能够在第一时间找到网站的所有人和接入商。

阮一峰,《关于网站备案,》,2009年 9 月 9 日

备案并非一个阻拦性措施,而是一个监管性措施(对比经营性互联网信息服务的许可制),希望大家可以积极踊跃的进行互联网信息服务的同时,避免恶劣影响的网站持续提供服务。找到接入商来第一时间拔网线,缩小影响范围;找到所有人来进行相应的处罚。

备案过程中的五个关键角色

当我们搞清楚了备案的核心理念和目的之后,我们重新回过头来看看备案当中的五个关键角色:备案主体省通管局接入服务提供商域名注册商域名管理机构

d2b5ca33bd970f64a6301fa75ae2eb22 6
各关键角色之间的关系

当我们真正开始进行备案时,就会面临三个元素:域名、服务器、所有人。这五个关键角色与三个元素,依次发生关系。

域名管理机构和域名

当我们开始思考建设一个网站时,必然会涉及到域名的问题。而实际上自 2017 年 11 月 30 日颁布的《工业和信息化部关于规范互联网信息服务使用域名的通知》正式实行之后, 并不是每一个域名都能够完成备案。在该通知中,要求互联网域名注册服务机构要在我国进行相应的注册和审批,才能够让对应的后缀进入到备案的流程。如果对应的域名注册服务机构没有在我国进行注册,则对应的域名无法在我国进行备案。

从而,也就出现了现在很多时候我们在购买域名时候需要考虑的一些问题 —— 域名能否完成备案?

目前所有完成了相应注册机构的审批都可以在工业和信息化部域名行业管理信息公示网站找到。如果你需要购买域名且有打算在国内进行备案,则一定记得确认你所购买的域名是否可以在国内完成备案的流程。

此外,如果你感兴趣的话,还可以在这里找到一些你可能从来都没听说过、没见过的后缀,比如.baidu

对于已经进行的域名注册服务机构,因为工信部有了相应的沟通方式,则可以在出现问题后,下发公函,要求对应的服务机构协助调查和配合。而对于没有注册的管理机构,无法完成相应的配合,干脆不予后缀备案。

这也解释了为什么现在你购买的 .io 域名不能备案,因为对应的注册管理机构没有在我国注册,不符合备案的要求。至于你看到的那些有备案号的 .io 域名,则是在相应的通知发布之前完成的备案,故而可以正常使用。

域名注册商和域名

当你选择了一个可以进行备案的域名后缀(比如 .com)之后,就可以进行域名的注册了。域名的注册需要到对应的域名注册商来完成。这个时候,也会涉及到不同的域名注册商可能会影响你的备案流程。

按照新的管理办法,你的域名需要在购买的时候完成实名认证。因此,你如果域名想要备案,则要求你的域名注册商支持进行实名认证。

比如,目前你可以在阿里云(万网)、腾讯云(新网)、西部数据等域名注册服务提供商这里购买域名并进行实名认证,在实名认证完成后,再进行后续的域名备案操作。

相应的,对于域名注册服务机构,也采用了审批和注册的限制,不同的服务商能够支持的域名实名认证也是不同的,企业需要根据「互联网域名注册服务机构审批」来进行提交,等待审批通过后,才能提供相应的域名注册和实名认证服务。

目前通过审批的域名注册服务机构也可以在工业和信息化部域名行业管理信息公示网站找到。

这也解释了为什么你在 Godaddy 、Namesilo、Namecheap 之类的域名注册机构注册的域名无法在国内进行备案,因为他们并没有在国内注册,接入相应的实名认证流程,自然无法为你提供后续的备案服务。

域名和所有人

当你选择好了域名后缀和域名注册服务商,进入了详细的域名注册流程当中时,会涉及到域名的实名认证的环节。

在这个时候你需要注意,备案要求域名实名认证和备案的主体是保持一致的,因此,如果你后续打算以哪个主体(个人或者企业)进行备案,在这里进行实名认证时,就要选择对应的信息来进行实名认证。

你提交信息后,域名注册服务机构(域名注册服务商)就会将你的域名和对应的实名信息提交到工信部。一般 1 ~ 2 个工作日后,你的信息就可以在工信部的内部系统可查,这个时候才能进行下一步的备案。

接入服务提供商和域名

域名购买好了,接下来就是选择接入服务提供商。由于备案实际上是个人与网站、网站与接入服务商进行的「双向绑定」,因此,能够提供备案服务的服务商都是在工信部进行了相应的注册的服务商(需要持有互联网数据中心业务经营许可证)。

在进行备案时,会要求你的域名已经完成了实名认证,然后再提交信息进行相应的备案,这里会要求域名的实名认证和接入服务提供商的实名认证信息保持一致,进行审核。

这也解释了为什么你购买的 DigitalOcean 的服务器无法进行备案,因为 DigitalOcean 并不持有互联网数据中心业务经营许可证。当然, DigitalOcean 的服务器也不需要进行备案。

所有人和通信管理局

当你进行备案时,会让你选择一个备案的所在地,备案的所在地决定了你的网站归属于哪个省份的通信管理局来进行管理。

一般来说,大家会选择身份证所在地。当然,如果按照惯例办法中的说明了,其实你还可以选择你的当前所在地(因为管局在乎的是能否联系到你)。选择了对应的省份,需要你提交相应的信息(需要能够精确到门牌号),基于对应的信息来进行备案。不过需要注意的是,不同的地区可能有所不同,比如基于当前所在地的备案可能会要求你提供居住证来进行备案。

理论上,你可以拥有多个不同的备案号,一个身份证所在地的备案号,和多个居住地所在的备案号

接入服务提供商和通信管理局

当你准备好所有信息,接入服务商帮你进行了基本的审核后,就会将你的信息提交至你备案的对应的通管局。而 ICP 备案本身是备案制度,因此,审批其实大部分情况下都是能够通过的,只是说需要一点时间,不同的省份在备案的审批上所需的时间也不同,根据《非经营性互联网信息服务备案管理办法》的要求,会在 20 个工作日内完成审核。不过某些特定的省份是比较快的(比如上海、浙江,据说是可以 1个工作日完成审批)。

当你完成审批后,就会获得一个备案号,将对应的备案号放置在你的网站底部,并加上前往通管局的链接即可。

拿到备案号之后的注意事项

新增备案网站

当你完成了第一个网站备案和建设后,你可能会需要进行第二个网站的备案和建设,这个时候,你需要注意:

  1. 你的第一个网站的用途应该符合备案时申报的类目(不然可能无法进行第二轮)
  2. 你应当按照规定放置了各项备案号等信息。
  3. 进行第二轮备案时,你的第一个网站应该是可以打开的。后续每新增一个网站,就会要求你之前的网站是可以正常打开的。

这就要求你如果某个域名不再使用,尽快将其关闭,并注销域名和相应的备案。

备案号、域名和接入服务商

当你拿到域名备案号之后,你就可以在你办理备案的接入服务商进行网站的建设和开发工作了。但需要注意的是,你仅能使用当前办理了接入服务商的服务,如果想要使用其他家的服务,则需要再次办理接入,新增一个接入,以使用对应服务商的产品。毕竟,备案的核心诉求是「双向绑定」,绑定用户和网站、网站和接入商。你虽然完成了备案,解决了用户和网站的绑定,但如果你没有完成网站和接入商的绑定(做接入备案),接入商同样会拒绝为你提供服务。

此外,需要注意的是,你的名下应当始终至少有一个网站,对于一个网站都没有的(比如你注销掉了所有的网站)人,在备案系统中被称为「空壳主体」,通管局会定期清理空壳主体,所以为了保住你的主体和备案号,尽量保证你的名下有网站。如果需要迁移服务商,也在完成了新的服务商接入之后,再注销之前服务商的接入。

独特的 CDN

在备案体系中,有一个很独特的产品 —— CDN 。和云主机不同,云主机会要求进行接入后才能使用,而 CDN 则没有相应的要求,你只要完成了备案,无需再进行接入即可使用 CDN 。

CDN 作为一个分布式的产品,因为没办法统一进行接入,故而只做了备案的限制,而不再要求你的域名必须在对应的服务商进行接入。

如果网站出现了问题,可能会怎么处理?

其实前面说了那么多,都是一些知识性的内容,接下来,我们来面对一个真实世界的问题 —— 如果某个网站出现了问题。可能会怎么处理

前面说过,备案本质上是为了能够在出现问题后快速找到你,解决网站中的问题。但真正在执行时,可能会有哪些操作?

  1. 如果有备案,直接联系备案时提供的联系电话(这也是为什么你备案的时候会有一个联系电话和一个备用联系电话),取得联系后,由网站负责人进行整改。
  2. 如果备案电话打不通,则可以联系服务接入商,通过接入商来暂停网站的接入服务,从而让网站无法访问。
  3. 如果服务商接入暂停后,依然可以访问(即你虽然备案了,但你的网站其实在其他服务器),那就通知你的 DNS 解析服务提供商停止解析。
  4. 如果你的 DNS 也是自己解析的,那就可以联系你的域名注册服务提供商,直接停止域名的服务状态。
  5. 如果你甚至域名注册服务商都是自己搞的,那可以联系域名管理机构,停掉你这个域名的使用。
  6. 当上述的所有办法都无法解决问题后,那就直接给你拉入黑名单,成为我们过去常说的被「墙」了的网站。

后记

这篇文章写完了,让我心头一松。我从 2012 年开始建立个人网站,2013 年、2014 年开始备案第一个域名,后续在 2016 年,在网易实习时以接入服务商视角看待了备案,再到在线,备案的政策不断的变化,我自己从某种意义上也经历了备案从松到严的一段历程(虽然没有经过最松的那段时间)。

备案机制从很多从业者的角度来看,觉得是繁文缛节,但换个角度来看,也是为我们的互联网提供了一定的基本保障制度。互联网上的信息良莠不齐,备案虽不能以黑名单的机制保证我们所看的信息“绝对干净“,但却也以白名单的方式给了一些建议。

不过,这篇文章也有遗憾,因为篇幅限制,我未能介绍关于公安备案相关的信息,这部分就留作后续再独立成文来介绍吧。

turned on black Android smartphone

如何在阿里云上申请免费的 SSL 证书

在进行网站建设的时候, SSL 证书是一个可以有效的提升网络数据传输过程安全性的手段。而一般来说,大家可以选择直接购买 SSL 证书或使用 Let’s Encrypt 提供的免费证书。但 Let’s Encrypt 的证书问题在于往往是短期证书(比如三个月),如果要使用在 CDN 上,就会需要经常替换,非常的麻烦。

目前各家云厂商大多都提供了免费的 SSL 证书,方便大家使用,不过有些时候入口比较深,所以大部分人找不到,只能购买付费的证书。写这篇文章就是希望帮助那些希望使用云服务厂商免费证书的同学快速找到入口。

操作步骤

1. 进入阿里云控制台

打开 console.aliyun.com 了,登录进入阿里云控制台。

2. 进入「SSL 证书(应用安全)」页面

在阿里云控制台找到 SSL 证书(应用安全)这个产品,点击进入产品控制台页面。

d2b5ca33bd970f64a6301fa75ae2eb22

3. 点击控制台左侧的 「SSL 证书页面」,进入到 SSL 证书页面

4. 在 SSL 证书页面点击上方 Tab,进入到免费证书 Tab

d2b5ca33bd970f64a6301fa75ae2eb22 1

5. 点击「创建证书」按钮,创建新的空白证书

d2b5ca33bd970f64a6301fa75ae2eb22 2

6. 点击操作栏中的「证书申请」,申请证书

d2b5ca33bd970f64a6301fa75ae2eb22 3

这部分需要注意的是:

  1. 证书绑定域名:阿里云免费证书只支持单个域名。不支持多域名和泛域名。
  2. 域名验证方式:如果你的域名使用了阿里云提供的 DNS 服务,就可以使用自动 DNS 验证方式。如果不是用阿里云的 DNS,就需要手动配置 TXT 记录来进行验证。
  3. 联系人:填写具体的信息,如果证书申请过程中有疑问,会联系这个电话。
  4. CSR 生成方式:你可以自己创建 CSR,也可以让系统生成。如果不是特别关注,使用系统生成就行。

7. 下载证书

当你配置完成后,稍等片刻,证书就会生成成功,此时点击操作栏的「下载」即可下载到证书文件,你根据自己的实际情况,下载对应格式的证书即可。

d2b5ca33bd970f64a6301fa75ae2eb22 4

总结

虽然阿里云的免费证书一年只有 20 个证书的名额,但对于绝大多数人来说,已经足够,在你需要 CDN 或其他更新不方便的情况下,使用云厂商提供的免费一年证书还是挺好的。

javascript

在 Pug 中实现类似 get_sidebar() 全局方法

在开发 WordPress 主题时,我们会用到一些全局方法,来帮助我们快速加载特定的区域的代码。如果我们在设计和开发主题的时候,也可以实现类似的功能,则在开发对应的页面和应用的时候,我们就可以根据自己的需求来进行特定区域的代码的封装。这样我们在进行后续的开发的时候,就可以简化自己的代码,同时还可以按照 WordPress 的规范提前拆分代码,在实际进行项目开发的时候,提升效率。

原理

本次实现主要是基于 Pug 自带的 Mixins 机制来实现在主题中提供自定义的函数,从而实现我们想要的内容。在原理上,和 WordPress 的 get_sidebar 之类的方法不完全一样。所以,在体验上还没有做到像 WordPress 那么方便。

实现方式

1. 创建 Mixins

在项目的根目录下创建一个 mixins 目录,并在其中创建一个 includes.pug 文件和一个 getHeader.pug 文件。

includes.pug 文件中添加如下代码

include getHeader
Code language: PHP (php)

getHeader.pug 文件中添加如下代码

mixin getHeader
    p header

2. 引入 includes.pug

在你的 layouts.pug 文件中加入 includes.pug 的引入。需要注意的是,要加在 doctype 之前。

include ../mixins/includes
doctype html
html
  head
Code language: PHP (php)

3. 在需要的地方调用

当你完成上述的配置后,即可在需要的地方进行调用。

extends layout

block content
  +getHeader
  h1= title
  p hi to #{title}
Code language: PHP (php)

调用的效果如下:

d2b5ca33bd970f64a6301fa75ae2eb22 39

如果你希望实现更加强大的功能(比如参数),可以参考 Pug 官网的 Mixins 页面。

javascript

为 Express 项目添加文件变更自动刷新

我最近在准备开发新的 WordPress 的主题的工具,为了方便自己开发主题,正在准备一个脚手架,本文是开发过程中的经验总结。

白宦成

在进行主题开发的时候,一个很好的体验是来自于变更能够实时生效。过去我们想要实现这样的功能需要自己手动刷新浏览器。但随着前端技术的进步,我们可以借助诸如 browser-sync 这样的工具来完成自动的刷新,从而实现无需手动刷新,代码修改后自动刷新。此外,除了 browser-sync, 你还可以选择 webpack-dev-server

原理分析

此类工具的工作模式是比较简单的,一般而言,会要求你设定一个代理的端口,他会将对应端口的请求进行转发,并在其中加入 BrowserSync 的 JS 文件,从而实现可以无需手动操作来刷新。

d2b5ca33bd970f64a6301fa75ae2eb22 37
browser-sync-client.js

而其刷新的能力则是源自于 BrowserSync 本地提供的 WebSocket Server。嵌入的 JS 文件中加入了 WebSocket 的相关链接代码, 从而实现从 Command Line 当中获取刷新指令,前端则在获取到指令后进行刷新。

d2b5ca33bd970f64a6301fa75ae2eb22 36
WebSocket 请求

具体步骤

1. 安装 BrowserSync

首先在项目中引入 browser-sync ,执行如下命令

npm install browser-sync --save-dev

2. 修改启动文件

我是使用 express generator 生成的项目,需要修改 bin/www 文件,如果你是自己建设的项目,则需要自行修改。

在启动文件中找到监听端口的代码, 并在其回调函数中添加如下代码

# 添加前
server.listen(port)
# 添加后
var bs = require('browser-sync').create();
server.listen(port, () => { 
  bs.init({
    open: false,
    ui: false,
    notify: false,
    proxy: 'localhost:' + port,
    files: ['./views/**', './routes/**'],
    port: 8080
  });
});
Code language: PHP (php)

上述配置中,可以根据你的需要修改 proxy 、files、port 等选项,实现自定义配置。

关于配置的更多信息,你可以参考 https://browsersync.io/docs/options

3. 启动服务,并测试

在命令行中执行 npm start ,在浏览器中打开对应的页面,当可以看到内容后,可以修改文件,等待页面的自动刷新,如果成功刷新了,则表示你已经完成了相关能力的配置。

silver mercedes benz emblem on blue surface

在开发 Gutenberg 插件时,如何处理防抖?

在开发 Gutenberg 插件时,如果你需要对编辑器的内容进行处理,则需要为其加入防抖措施,避免你的函数被频繁调用。

思路

由于编辑器需要高频处理,因此需要采用防抖策略,避免将多次输入视为不同的事件。这里可以使用 WordPress 提供的 useDebounce 来实现控制。需要注意的是,WordPress 自动的 Debounce 函数传入的参数应当采用 useCallback 来进行包裹。

参考代码

import {subscribe} from "@wordpress/data";
import {useDebounce} from  "@wordpress/compose"
import {useCallback} from "@wordpress/element";

const debounced = useDebounce(
        useCallback(() => {
            // do some thing
        }),500
    );
subscribe(debounced);
Code language: JavaScript (javascript)
029a1f00793d00a4a88e458d5cdfebb0

针对 WordPress 开发配置 Sublime Text 4

最近在开发两个自己用的 WordPress 的插件,所以就把 Sublime Text 配置成了适合 WordPress 的开发的状态。以下是我的一些记录。

加入代理

因为 Package Control 在境内访问不是那么的流畅,所以,针对 Package Control 进行相应的 Proxy 配置,你只需要找到相应的配置界面,在其中加入 Proxy 配置即可。

d2b5ca33bd970f64a6301fa75ae2eb22 16
{
  "http_proxy": "http://127.0.0.1:7890",
  "https_proxy": "http://127.0.0.1:7890"
}
Code language: JSON / JSON with Comments (json)

代码格式化

Sublime 自带 Reindent

Sublime Text 4 自带缩进格式化的工具,因此,可以不需要安装第三方插件来实现。

在 Sublime Text 4 的 Line — Reindent 当中可以完成相应的操作。

d2b5ca33bd970f64a6301fa75ae2eb22 17

为了更好的使用这个功能,我自己添加了一些配置来简化这个功能的使用:

  1. 安装 Package​Resource​Viewer 用于修改系统配置。
  2. 使用 Package Resource Viewer: Open Resource 命令,打开 Default 包中的 Context.sublime-menu文件,
  3. 在其中添加一行代码 { "command": "reindent","caption":"格式化选中部分" },即可实现在上下文菜单中加入自动的格式化能力。效果见下图
d2b5ca33bd970f64a6301fa75ae2eb22 18

代码辅助编写

Tabnine

由于我使用的是 Sublime Text ,所以 VSCode 才有的 GitHub Copilot 自然是无法使用的,但不代表你不能使用机器来帮助你快速生成代码。这里我选择的是 Tabnine

由于我目前还没有为 Tabnine 付费,所以他只能基于我本地的代码进行学习。

文档快速生成

DoxyDoxygen

虽然是给自己用的插件,还是希望代码写的足够清晰。一个更加简单的插件,可以帮助我更好的去写批注。