分类: 技术

各种开发心得,包括语言、软件工程、开发工具等

  • 在 Pug 模板中使用变量

    在 Pug 模板中使用变量

    我厂使用 Pug 作为 HTML 的预编译工具,写久了发现回不去了……Pug 写起来很高效,看久了习惯了阅读效率也很高,读了读文档,发现还有很丰富的可编程特性。于是我决定抛弃 Handlebars,以后都用 Pug 写模板了。

    这次我厂官网改版,我就用 Pug 替换了 Handlebars,于是 build 脚本一下少了几十行,非常爽。其实我早就想这样做,不过卡在一个点:使用变量。

    在 Pug 里可以这样使用变量:

    - var name = 'meathill'
    
    h1 hello #{ name }

    以上代码将输出 <h1>hello meathill</h1>。这种用法比较简单,不过在 extends模板的时候,把变量放到哪里就不知道了,官方文档也语焉不详,我反复试了很多次无果,最终还是靠搜索找到了答案,原来要这样:

    // Layout.pug
    html
      block vars
        p 注意,这个 block 是重点,它出现在前面,用来注入变量
      head
        title #{ title } | My site
      body
        block content
    
    // page.pug
    extends Layout
    
    block vars
      - var title = 'A blog'
      
    block content
      h1 Blog title
      p blog content
  • 文档的最佳实践

    文档的最佳实践

    指导群里的小伙伴做小项目 应用创意:Chrome 共享首页,有两位同学主动领命,分开前后端就开做。结果我发现他们对文档的处理非常幼稚……所以便有了这样一个分享。

    我的观点:

    1. 文档当然要写,但不要用自然语言这样写一大篇
    2. 文档如果不好好维护,将来表现和实际代码不一致,会造成更大的问题
    3. 所以开发者应该用更强的方式约束文档和代码,而不是大家主观协作
    4. 所以我们——尤其在前后端协作的时候——应该写格式化数据结构描述,然后通过编译的方式,用数据结构描述输出文档、测试、Mock Data

    下面是视频:

  • \n 与 \r 的区别

    \n 与 \r 的区别

    近期的需求用到命令行输出的解析,在解析类似进度条的内容时,遇到一些问题。经过反复的搜索询问,大概得到答案:主要在于 \r 和 \n 的区别。StackOverflow 的一个答案是这么解释的:

    As indicated by Peter, CR = Carriage Return and LF = Line Feed, two expressions have their roots in the old typewriters / TTY. LF moved the paper up (but kept the horizontal position identical) and CR brought back the “carriage” so that the next character typed would be at the leftmost position on the paper (but on the same line). CR+LF was doing both, i.e. preparing to type a new line. As time went by the physical semantics of the codes were not applicable, and as memory and floppy disk space were at a premium, some OS designers decided to only use one of the characters, they just didn’t communicate very well with one another ;-)

    所以 \r 换行之后,光标移到此行的 0 位,继续输出,于是新的一行会替代旧的一行,形成的效果就是进度条在更新;而 \n 则会另起一行,形成多行输出的效果。

    所以类似我这个需求,直接 line.split('\r').pop() 即可。

    另外,new TextDecoder('utf-8').decode(binaryData) 返回的文本都是用 \r\n 做换行的。

  • 解决 PHP 7.2.8 + MySQL 8.0.12 连接失败的问题

    解决 PHP 7.2.8 + MySQL 8.0.12 连接失败的问题

    这两天又反复遇到这个问题,先写解决方案:

    1. 使用 caching_sha2_password  插件

    修改用户密码,并且用插件生成,可以解决 WordPress 的问题。

    ALTER USER 'user'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'password';

    2. 修改 my.cnf,使用原生密码

    使用 Laravel + MySQL 8.0 的时候,遇到

    SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client

    修改 /etc/mysql/my.cnf (我是 Ubuntu 16.04),添加下面一行:

    [mysqld]
    default_authentication_plugin= mysql_native_password

    然后重置密码:

    ALTER USER 'user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
    (更多…)
  • 服务器备份工具

    服务器备份工具

    目前维护着几个服务器,所以需要一个备份工具帮忙备份。因为都是 wordpress,所以

    1. 可以访问 wordpress 的安装路径
    2. 可以部署在服务器上
    3. 最好是 PHP,方便 require wp-config.php

    备份的内容:

    1. 备份数据库,直接访问 wp-config.php 就行
    2. 备份 wp-uploads,这里要支持差异化备份了
    3. 备份服务器配置,包括:
      1. php 配置
      2. nginx 配置
      3. crontab 配置

    备份的处理:

    1. 每次备份的内容打一个压缩包,命名为 服务器-站名-日期-时间.zip
    2. 将备份后的内容上传到指定服务器
    3. 还需要开发一个本地工具,用来从制定服务器上下载备份文件到本地(服务器存储有点贵)
    4. 自动删除半年前(可配置)前的备份文件

    差不多这样,想起来随时补充

  • Vue 代码校验工具

    Vue 代码校验工具

    写 Vue 的时候,时不时会发生一些笔误,出的错并不会被编译器和运行时发现,但确实会影响工作,所以想写一个工具把它跑出来。我目前遇到的问题有:

    1. :v-model
    2. attr="false"
  • Failed to start php-fpm.service: Unit php-fpm.service is masked.

    Failed to start php-fpm.service: Unit php-fpm.service is masked.

    周末手一抖把服务器从 17.10 升级到了 18.04,然后博客就挂掉了。

    根据提示信息,nginx 应该正常工作,问题多半出在 PHP 上。service --status-all 之后,果然 php7.1-fpm 没有启动。然后照常 service php7.1-fpm start,咦,奇怪,报错了:

    Failed to start php7.1-fpm.service: Unit php7.1-fpm.service is masked.
    

    换用 service php-fpm start 也一样,区别就是 service 名字不太一样。然后 Google 之,没找到很靠谱的说法,但是找到一个类似的情况,发生于使用 do-release-upgrade 升级到 16.04 时,php5-fpm 启动不了,报类似的错误,解决方案是升级到 php7。

    如此一来我也试试好了,因为直接 apt install php-fpm 会解析出来 php7.2,所以我尝试 service php7.2-fpm start,果然可以。既然如此,干脆升级到 7.2 好了,反正我也没啥特殊要求。

    于是修改站点配置文件,把 php 接口指向 7.2 的 socket,然后安装几个欠缺的模块,终于又把博客跑起来了。

  • 使用 Pug 和 Stylus 开发小程序的 watch 脚本

    使用 Pug 和 Stylus 开发小程序的 watch 脚本

    首先,我试用了 Wepy,丑的一逼,遂放弃。

    小程序开发有两点比较蛋痛:

    1. 每个页面必须有3个文件,wxml,js,wxss
    2. 使用 wxml 替代 html,使用 wxss 替代 css,使得默认的编译失效

    Webpack 在这里不太适用,因为 1,我们并非要把所有代码打包到一起。WebStorm 的 File Watcher 也不适用,因为它输出的文件扩展名是固定的(跟 pug 和 stylus 源程序有关)。于是我经过摸索了,使用 gulp 脚本解决了这个问题,代码如下:

    import gulp from 'gulp';
    import pug from 'gulp-pug';
    import rename from 'gulp-rename';
    
    const pugFiles = 'pages/**/*.pug';
    
    // 通用的 pug 处理,可以把 pug 转译并改名为 .wxml 文件
    async function doPUG(path) {
      gulp.src(path)
        .pipe(pug())
        .pipe(rename({
          extname: '.wxml',
        }))
        .pipe(gulp.dest('./pages'));
    }
    
    // 将所有 pug 进行转译
    gulp.task('pug', async () => {
      return doPUG(pugFiles);
    });
    
    // 侦听 .pug 文件的变化,并转译被修改的
    gulp.task('watch', ['pug'], () => {
      gulp.watch(pugFiles, ({path}) => {
        doPUG(path);
      });
    });
    

    接下来,开发的时候,只要运行 gulp watch 即可。

    用类似的方式,我们还能处理 stylus -> css,这里就不详述了,大家可以自己试一试。

    完整的 gulpfile 在 GitHub 仓库里,请自行取用。

  • 网站抓取工具 website-scraper

    网站抓取工具 website-scraper

    临时需要抓一个网站,搜索了一下,发现 website-scraper,用了一下感觉不错。它有如下优点:

    1. 基于 Node.js 和 NPM,系统无关
    2. 可以根据链接抓取整个网站
    3. 文档齐全,仓库还有人维护
  • 2018年计划

    2018年计划

    辞旧迎新,一年一度的许愿还愿时间又到了,你准备好了么?

    (更多…)