分类目录归档:技术

text

为 wxa.js 构建的小程序移除 scss 依赖

wxa.js 默认使用的样式语言是 scss,所以其默认创建的项目就会要求安装 node-sass,但由于 node-sass 依赖了 binding.node 等包,导致常常会出现 node-sass 安装失败的问题。

如果你并没有在项目中使用 scss ,则可以考虑将你项目种的 node-sass 移除,从而缩小项目的依赖体积,提升项目安装成功的概率。

思路

由于 wxa 默认使用了 scss,因此,我们需要移除项目中针对 scss 的配置,并移除代码中的 scss ,这样才能保证后续在编译的过程中,不会调用 node-sass 的依赖。

步骤

  1. 移除 wxa.config.js 中关于 scss 的配置

在 wxa 的默认配置中,配置了 sass/scss 的依赖,我们如果不移除这个依赖,就会导致后续在构建的时候,自动安装相关依赖。

nv0iy

因此,我们需要在 wxa.config.js 中添加 use 相关配置,且仅保留 babel 作为依赖,具体修改如下:

module.exports = {
    plugins: [
        new ReplacePlugin({
            list: envlist,
        }),
    ],
    // 你的其他配置
    use: [
        {
            test: /\.js$/,
            name: 'babel',
        },
    ],
    // 你的其他配置
};
Code language: JavaScript (javascript)
  1. 移除项目中标记为 Scss 的语言

在移除了 wxa.js 的构建依赖后,接下来需要移除代码中关于 scss 的标示,从而使我们的代码可以被正确的渲染工具所渲染。具体修改如下所示,右侧为修改后的结果

uqzjy
  1. 移除 package.json 中的 相关依赖。

当我们完成了上述的操作之后,就可以放心的移除系统中关于 sass 的依赖了,从而减少整个项目的体积和对 node-sass 的依赖。

你只需要执行如下的命令,就可以移除项目中关于 sass 的依赖了。

npm uninstall @wxa/compiler-sass
// 或者
yarn remove @wxa/compiler-sass
Code language: JavaScript (javascript)

总结

scss是一个好的语言,但 node-sass 却不是一个好的工具,如果你不使用它,不妨将其移除,提升你的项目构建速度。

text

wxa.js 引入 tailwindcss

TailwindCSS 是我最近一段时间使用比较多的 CSS 框架,相比于传统我们习惯的前端框架,它的限制更少,你可以根据自己的需要来编写样式。如果你配置了清除没用到的 CSS,TailwindCSS 的体积甚至可以远小于其他框架。

也因为上面的这些因素,我也自然而然的会选择将其放在小程序中来使用。而由于我使用的是 wxa.js ,所以这里也是一个对应的 wxa.js 的教程。

安装

1. 安装 TailiwndCSS 到你的项目中

由于 Taildwind 默认推荐使用的是 PostCSS,但其需要的是 PostCSS 7 或者 8 ,但 WXA.js 提供的 PostCSS 插件使用的是 6 ,所以这里我就选择不将其作为 PostCSS 插件来安装。

在 WXA 项目根目录中执行如下命令,会在你的项目根目录中生成一个 tailwindcss.config.js,它会作为后续你的项目配置的配置文件。

npx tailwindcss-cli@latest init
Code language: CSS (css)

随后,在你的项目根目录创建一个 tailwind.css 文件,并在其中加入如下代码,这个文件作为你后续样式基础文件。

@tailwind base;
@tailwind components;
@tailwind utilities;
Code language: CSS (css)

添加完成后,你就可以执行如下命令,来生成一个默认的 tailwindcss 样式文件。

npx tailwindcss-cli@latest build ./src/tailwind.css -o ./src/tailwind.css
Code language: CSS (css)

生成的效果如下,可以看到,未任何处理的情况下,整个 CSS 文件足足有 3.81 MB,不过不用担心,我们可以清除其中的样式。

未做清理

如果你希望后续不输入这个命令,可以将其添加到你的项目的 package.json 中。

2. 移除默认的浏览器自动添加的 prefix

由于不同浏览器在不同的样式上可能有所不同,tailwindcss 会在生成的时候帮助我们生成一些特定的前缀。但小程序不涉及到浏览器的兼容性问题,所以我们可以关闭 taildwindcss 的 autoprefixer。

将刚刚的生成命令中加入 --no-autoprefixer 的参数,就可以生成不含 prefix 的 CSS 文件

npx tailwindcss-cli@latest build  --no-autoprefixer  ./src/tailwind.css -o ./src/tailwind.css
Code language: CSS (css)

可以看到,去除 prefix 后,我们的文件缩小至 3.46MB。

去除 prefix

3. 移除不用的样式

tailwindcss 提供了根据页面结构分析使用样式的功能,从而可以实现在构建生产版本之时,移除没有使用的样式,从而可以达到缩小样式的目的。

在项目中的配置 purge 属性,就可以实现 tailwindcss 自动分析 wxa 文件,从而移除没有用到的样式。

module.exports = {
    purge: ['./src/**/*.wxa'],
    darkMode: false, // or 'media' or 'class'
    theme: {
        extend: {},
        screens: [],
    },
    variants: {
        extend: {},
    }
}
Code language: JavaScript (javascript)

配置了 purge 属性后,可以看到,样式文件锐减到 9.93KB (因为我使用的样式很少)

移除后的效果

4. 在 wxa.js 中引入

修改生成文件的命令,使生成的文件的后缀为 wxsss,从而可以继续使用微信小程序的 @import 语法。

npx tailwindcss-cli@latest build --no-autoprefixer  -o ./src/tailwind.wxss
Code language: CSS (css)

重新生成样式文件后,只需要在 app.wxa 文件中的 style 块中加入如下引入代码,在项目中引入 tailwindcss。

因为 tailwindcss 只生成一个样式文件,因此,只需要在 app.wxa 中引入,即可确保所有页面都可以正常使用 tailwindcss

@import "./tailwind.wxss" 
Code language: JavaScript (javascript)

优化

实际上,taildwindcss 的体积还可以进一步优化,你可以完全移除掉那些你没有用到的属性,从而让你的 css 文件特别小,从而控制小程序样式的大小。

turned on flat screen monitors

用好 Mixins

一直以来,我都没有使用过 Mixins 这个功能,因为一直以来,我都会倾向于在不同的页面承载不同的功能。

但最近在做 NESHouse Pro 的时候,也确实遇见单个页面承载了大量的逻辑,因此,我决定使用 Mixins 来分割逻辑。

9gy0h

我将页面的逻辑和功能按照模块,拆分成了三个不同的 mixins。之所以这样拆分,是因为这三个模块都有一些跟随函数的变量,我不希望这些变量出现在主要的页面逻辑中,而是以抽象出函数的方式来调用,因此,通过 Mixins 来组合 Methods 和 Data 是一个不错的方式。

MacBook Pro with images of computer language codes

MySQL 遭遇 Out of sort memory, consider increasing server sort buffer size 怎么办?

当你将线上数据拖到本地进行执行的时候,可能会出现 mysql Sort aborted: Out of sort memory, consider increasing server sort buffer size 的错误,出现这样的错误,是因为你的 MySQL 的 SortBufferSize 太小导致的。你可以在 my.cnf 中添加配置。

sort_buffer_size=3M

参考文献

https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_sort_buffer_size

MacBook Pro with images of computer language codes

如何在服务器和本地互传 SQL?

在本地开发模拟线上数据的时候,难免需要从线上服务器上拉取数据到本地进行导入。

这个时候,你可以在执行 mysqldump 的时候加入 where 参数来筛选数据,

但依然会遇见文件比较大的情况。

在这种情况下,你可以选择使用 gzip 来压缩你导出的 SQL 文件,命令也非常简单

gzip xxx.sql
Code language: CSS (css)

执行完成后,你会获得一个 xxx.sql.gz 文件,接下来只要使用 scp 之类的软件,将文件拖回本地即可。

通过 Gzip 压缩,可以将一个原本 1.5G 的 SQL 文件压缩到 100M 左右,大大的提升了数据的传输速度。

green and black digital device

用 Docker 解决端口错误的问题

在进行嵌入式设备的编写的时候,一个很大的问题是重新刷写应用程序的成本较高,因此,在一些场景下, 我们尽可能通过修改服务端的应用,来解决嵌入式端的错误问题,而尽可能避免对嵌入式设备重新刷写。

我是在处理 Awtrix 2.0 的时候想到这个办法的。

Docker 在启动应用的时候,可以设置端口监听,通过 docker -p host_port:container_port 来创建容器,可以指定容器内部端口和主机监听端口的映射。

假设业务监听的是 80 端口,你可以通过 -p 81:80 将容器的 80 转发到宿主机的 81 端口上。同样的,你可以在遇见端口问题的时候,通过修改相应的宿主机端口,在外层加一层转发,从而解决掉端口编写错误的问题。

不过,需要注意的是,毕竟是加了一层应用程序的转发,相应的,性能会有所损耗,如果可以的话,尽可能还是修改嵌入式设备,减少性能损耗的点。

red and whites logo

宇宙条面试体验总结

为什么要面试宇宙条?

主要是因为轻服务的负责人给我发邮件,说希望我加入,并给出了还不错的工作环境的条件(但没有谈钱),我觉得人家能够给出这样的让步,确实用心,所以就答应来面试。

一面:技术面

一面是技术面,问的是一些常见的技术问题

其中我有印象的:

  1. LocalStorage 和 SessionStroage 的区别?在不同场景下的表现
  2. Cookie 的应用场景?服务端如何设定 Cookie?
  3. 数据库优化的思路
  4. 数据库索引的底层机制

具体的编程题目

  1. 实现 retry(fn, times) {} ,实现这样的函数,重试返回一个 Promise
  2. 设计一个 Person 类设计,支持链式调用,Person 包含 sleep\eat 函数,支持 person()->eat()->sleep() ,或person()->eat()->sleep()

二面:技术面 & 经历介绍

二面问的是过去的经历,面试官问了一下我为什么会从研发刻意的转了一下运营岗位;又讨论了一下,我在运营岗位获得到的经验等信息。

编程题就做了一道

  1. 设计实现一个 EventListener 类,包含 on、off、emit 三个方法

三面:技术面 & 经历介绍

三面是产品。

技术题目做了两道:

  • 设计一个爬虫,爬取某网站的数据
  • 设计一个爬虫,反向组织爬虫爬取数据

四面:HR面

四面就是 HR 面了,聊了一些关于,我为什么要投这个岗位(其实是我被邀请投的,根本不是我自己主动投的)、我怎么看待字节跳动之类的。

kdc5t
面试结果

最终 HR 面试也过了,就是等 HR 和我谈钱。这里就不更新了。

text

HOWTO: 如何学习 Alpine.js

什么是 Alpine.js

Alpine.js 是由开发者 Caleb Porzio 开发的一款响应式前端框架。和过去人们所熟悉的 Vue.js、React、Angular 不同的是,Alpine.js 不需要你对于现有的应用进行高成本的改造,也没有 VDom 的概念,直接可以在现有的系统中加入并使用

快速学习指南

Alpine.js 在国内的使用并不多,因此,相应的学习内容大多是英文写就的,不过 Alpine.js 涉及到的概念不会像 Vue、React 之类那么多,你可以很轻松学会它。

推荐学习路线

Alpine.js 没有那么多的概念,因此,学习路线也非常简单,你只需要掌握以下一些内容就可以了

  1. Alpine.js 基础语法和使用;
  2. Alpine.js 的magic helper; (非必需)
  3. Alpines.js 的状态管理工具 Spruce(非必需)

基础语法的了解可以让你使用 Alpine.js 开发自己的应用。而后面两者可以简化你的整个开发工作流,提升自己的开发效率。

推荐学习文档

1. 查阅官方文档,学习基础语法

学习 Alpine.js ,首先离不开的是官方文档,Alpine.js 的官方文档在其项目主页

https://github.com/alpinejs/alpine

如果你的英语不够好,可以看中文版本的 Readme

https://github.com/alpinejs/alpine/blob/master/README.zh-TW.md

具体的语法层面,我建议你按照如下的逻辑来学习

第一梯队,学习:

  • x-data:教你如何组织你的 Alpine.js 代码
  • x-on:事件绑定
  • x-if:逻辑处理
  • x-for:列表渲染
  • x-bind:数据绑定
  • x-model:双向数据绑定

这六个语法让你可以基本开始使用 Alpine.js。

第二梯队,学习:

  • x-show:控制是否显示
  • x-spread:将 Alpine.js 对象属性绑定到 Object 上
  • x-text:控制元素内文字
  • x-html:控制元素内 Html
  • x-transition:控制转场渐变动画

这五个语法让你的 Alpine.js 项目拥有更多的功能

第三梯队,学习:

  • x-cloak:控制组件初始化完成
  • x-ref:绑定父组件对象
  • $el:获取元素
  • $refs:获取父组件对象中标注的 x-ref
  • $event:事件对象
  • $dispatch:触发事件
  • $nextTick:下次 DOM 更新
  • $watch:监听数据变化

上述这些语法可以让你更加深入的使用 Alpine.js,不过在很多场景下可能你都用不到,所以也无需担心。

2. 查看常用逻辑的实现方式,比对不同

Hugo 是 Alpine.js 的开发团队成员之一,除了开发以外,Hugo 还在自己的网站上给出了一个 Playground ,你可以在这里看到一些 Alpine.js 的常见用例,比如:数据绑定、 for 循环、抓取数据等。

c7gdc

你可以访问 https://alpinejs.codewithhugo.com/ 来查看 Hugo 准备的一些案例,从而快速的了解你熟悉的功能在 Alpine.js 中的应该如何实现。

3. 在线练习 Alpine.js

当你了解了一些基本的使用后,你就可以开始打开一个网页,开始自己练习使用了。

这里有两个可以在线使用的调试环境,你可以基于他们来进行练习,直接看到效果。

Alpine.js 作为一个工具,需要多练才能熟悉它的使用,配合前面看的文档和案例,现在你就可以在这两个练习环境中练习 Alpine.js 的使用。

4. 查看真实项目,了解 Alpine.js

一个工具从测试到落地到真实环境,需要的是来自真实项目的参考。而 Awesome 中就提供了不少这样的案例。

n8o10

通过了解这些项目和工具,你可以看到别人是怎么使用 Alpine.js 的,从而学习 Alpine.js 的开发。

Alpine.js 的学习资源汇总

Alpine.js 的学习资源不多,但有一些比较适合国内开发者看的,我也再列举一下,具体如下:

视频教程

  • Building AlpineJS:由 Alpine.js 开发者 Caleb Porzio 开设在 Laracasts 上的一门课程,介绍如何从 0 打造一个 Alpine.js, 这个课程会让你对于 Alpine.js 更好更快的理解。

个人博客

  • Code With Hugo: Alpine.js 核心开发者的博客,会更新一些关于 Alpine.js 的技术文章
  • Alpine.js之一步一腳印:台湾同胞写的 Alpine.js 入门教程,有一个系列。完整的一共有30篇,可以一点点看看。

邮件列表

  • Alpine.js Weekly:Alpine.js Weekly 由 Alpine.js 的核心开发者 Hugo 维护,每周五发送一封邮件,介绍最新的 Alpine.js 社区的资源,十分值得订阅。

讨论区

一些常见问题

1. Alpine.js 依赖 Webpack / Alpine.js 不支持 Webpack?

答:并不是,Alpine.js 可以在 webpack 中使用,也可以不在 Webpack 中使用。即使通过 webpack 构建,Alpine.js 也会自动绑定对象,方便你使用。

2. Alpine.js 是为前端/后端设计的技术方案

答:Alpine.js 并不是为某一类人设计的技术方案。虽然在我看来,他对于后端十分友好,因为不需要 webpack 之类的前端构建工具就可以使用,但如果你是前端,且不太喜欢 React 的 JSX 或者是 Vue 的template ,那依然可以选择使用 Alpine.js。

3. Alpine.js 学习门槛如何?

Alpine.js 的学习只需要掌握一些核心的语法,就可以正式开始使用了。相比于 Vue、React, 我认为学习成本还是要低一些的。Vue 有完整的工具链,放平缓了学习曲线,但需要学习的概念依然不少,只是上手难度低而已。

我自己的使用感受

Alpine.js 在我看来,是对于后端开发者的利器。他的语法足够简单, 也不需要打包,因此对于后端开发者来说,可以十分方便的在系统中接入。同时,Alpine.js 可以很好的与传统的服务端渲染的逻辑结合,使用服务端渲染内容,使用 Alpine.js 来控制内容,从而可以很好的完成页面的构建,实现在不过多提升项目复杂度的同时,提升了页面的动态效果和逻辑编写难度,对于后端开发者来说,是一个不错的工具。

对于前端开发者来说,如果你厌恶了每次写项目都需要构建、打包,那么 Alpine.js 也是一个不错的选择。

white paper plane on white background

开了一个 HOW-TO 目录

HOW-TO 类目主要会介绍一些我自己熟悉/经常使用的技术栈,并将这些技术栈的学习路径等,整理出来,提供给需要的人。

HOW-TO 子目录放置在“技术“目录目录下,所以内容大体上是和技术有关的。如果有一些别的内容,可能也会分享出来。

比如我自己倒腾的一些硬件产品之类的。

purple and blue light digital wallpaper

屏蔽爬虫请求的四种方式

在进行应用开发的过程中,难免会遇见爬虫爬取数据的。正常情况下,爬虫的数据爬取不应影响业务系统的正常运行。但毕竟都是人写的代码,难免会出现 Bug ,在 Bug 的情况下,爬虫可能会对业务系统发起超出日常水平的请求,从而使业务系统开始出现故障。在这种情况下,就需要对爬虫进行屏蔽。

屏蔽爬虫,由内而外,可以分为四个不同的方式来屏蔽。

1. 屏蔽 UA

爬虫一般而言,都会有特殊的 User Agent ,比如 Baiduspider 就是百度的爬虫;Googlebot 就是 Google 的爬虫。

在第一阶段,你可以针对 User Agent 进行屏蔽,这部分只需要在 HTTP Server 层面加入相应的屏蔽代码即可。

以最常用的反向代理服务器 Nginx 为例,你可以在站点的配置文件中添加如下代码来屏蔽百度和 Google 的爬虫访问。

if ($http_user_agent ~* "Baiduspider|Googlebot")
{
    return 403;
}
Code language: PHP (php)

上述这段代码可以实现在 Nginx 检测到访问者的 User Agent 包含特定的字符的时候,返回 403 报错,拒绝访问服务。

2. 在主机层面屏蔽 IP

除了针对 User Agent ,有些时候是特定的来源的 IP 疯狂的访问,那也可以考虑针对 IP 进行封禁。

考虑到这部分,最常见的是使用主机自带的防火墙机制,来屏蔽来自特定来源的 IP。以 Linux 为例,可以通过 iptables 来完成相应的功能。

在 Linux 下,输入如下命令,来添加 iptables 屏蔽

iptables -I INPUT -s 8.0.0.1 -j DROP
Code language: CSS (css)

上述命令,就可以在 iptables 中添加针对 8.0.0.1 的请求,所有来自 8.0.0.1 的请求都会被抛弃。

3. 在安全组层面屏蔽 IP

在如今的业务模式下,大家大多使用的是云服务器。如果你使用的是云服务器,则可以在用户的请求到达主机之前,直接在云服务商的内部网关层面直接丢弃。

你只需要在现有的安全组规则中新增一条屏蔽特定来源 IP 的规则,就可以实现在安全组层面上屏蔽特定的 IP。

ktz0r

4. 在 CDN 层面屏蔽 IP

现在我们的业务大多会使用 CDN 来完成数据的分发。在这种情况下,服务器获取到请求不是来自我们要屏蔽的 IP,因此,我们可以直接在 CDN 层面屏蔽掉爬虫的 IP。

现在的云服务商的 CDN 大多提供了 IP 白名单/黑名单的功能,你只需要将需要屏蔽的 IP 放在黑名单中,就可以实现在 CDN 层面屏蔽 IP。

qm1qk

总结

屏蔽爬虫的方式有多种多样,不过最为常见的主要就是这四种。当你找到了爬虫的特征,便可以很轻松的屏蔽它。