用 Prettier 处理 Pug 文件

Prettier 是一个新兴的代码格式化程序,但目前支持的语言相对有限,特别对于混合文件的处理仍在比较初级的阶段。

因此,针对 Riot 这种 HTML/Pug 中混合了 JavaScript 和 CSS 的文件,要对其中的代码进行格式化,必须先将文件分解,分别用 Prettier 处理后,再重新合并。

相比 HTML,处理 Pug 这种由缩进决定包含关系的文件倒是更简单,很容易通过一些简单粗暴的方法进行分解。

Prettier 本身也是一种广受欢迎的粗暴解决方案。它的主要动机就是通过将一种固定格式强加给代码,消灭不同风格间的优劣之辫,节约程序员在争辩中浪费的时间,集中精力办实事。因为大多数时候,主流风格间并没有明显的好坏,只是个人喜好不同。

文件分解

const split = (tag) => {
    var pug, script, style;
    [pug, script] = tag.split(/\n    script.*\.\n/);
    [pug, style] = pug.split(/\n    style.*\.\n/);
    if (style) {
        return [pug, script, style]
    }
    [script, style] = script.split(/\n    style.*\.\n/);
    return [pug, script || '', style || ''];
};

最初的版本是将文件切分成行后,找出 script 和 style 所在的行,然后进行分割。相对现在的版本,理论上更容易理解,但由于实际代码量大很多,在没有注解的情况下反而没个这个版本思路清晰了。

由于约定了缩进是 4 个空格,并要求显式包含 script 标签,riot 文件基础格式相对固定。

tagname
    // 标签

    script.
        // 脚本
    style.
        // 样式

另有几个变种,比如忽略 script 部分、忽略 style 部分、script 和 style 上下互换等,用上面这个函数都能处理,同时里面用到的正则表达式也能处理 script.script(type="text/es6"). 等指定或不指定类型的情况。

格式化

[pug, script, style] = split(tag);
script = prettier.format(script, {tabWidth: 4, singleQuote: true, trailingComma: 'all', arrowParens: 'always'});
style = prettier.format(style, {parser: 'css', tabWidth: 4});

Prettier 具备对 JavaScript 文件和 CSS 文件的格式化能力,并允许少量参数调整,此处只要根据官方接口文档提供的信息,按照自己的项目需要进行配置即可。最主要是明确按照什么文件类型进行处理,并指定缩进宽度。

合并

const join = (pug, script, style) => {
    script = script
        ? '\n    script.' + ('\n' + script.trim()).replace(/\n/g, '\n        ') + '\n'
        : '';
    script = script.replace(/\n\s+\n/g, '\n\n');
    style = style
        ? '\n    style.' + ('\n' + style.trim()).replace(/\n/g, '\n        ') + '\n'
        : '';
    style = style.replace(/\n\s+\n/g, '\n\n');
    return pug + script + style;
};

const result = join(pug, script, style);

在合并的时候,我也采用了粗暴的方案,无论原来代码中脚本和样式哪个在前,我总是将脚本放在前面,并且统一丢弃了类型说明。在拼接前,先将每行代码缩进 8 个空格,再去除对空行的缩进和多余的换行。

简单的性能测试和后续工作

格式化执行的频率越高,每次代码的变化就越少,也就越不容易影响编码者的思路。为了能使格式化的频率提高,单次的开销就必须尽可能降低,否则会影响编码者的体验。

Node 中有一个简单的性能测试方法,就是使用 console.timeconsole.timeEnd,这两个方法能方便的计算出两次调用间耗费的时间。

经过简单测试后,发现即便是固态硬盘,加载文件(主要是 node_module 中的文件)的时间仍是明显大于实际的格式化处理,可见将 watch 内置到脚本中是非常必要的,使格式化服务保持在线,相比“冷启动”可以起到明显的提速效果。

相关文章

npm script

更多

12KB的Excel导出库sheetex是怎么来的

这是一个关于前端 Excel 导出库 sheetex 的故事:我为什么要做这个库,它为什么会这么小,以及你是否值得一试。 如过你问我“为什么非要在前端导出”,那将是另一个故事。 我的数据导出史 不知道你是否还记得自己是从什么时候开始接触数据导出的? 我对自己的“数据导出史”还算有些印象:在还没有正式工作的时候,如果有人问我要数据,我会在数据库管理工具里写个查询语句,然后视对方的用途,导出成SQL 语句、CSV 文件或者Excel 等;待到工作了,需要开发面向最终用户的系统,就不能再这么手工处理,导出功能成为系统标配,用户点击一个按钮,就要下载到相应的文件。 最早是 CSV 格式,因为其生成相对容易,而且也可以通过 Excel 软件进行查看,加上主要是内部用户,偶有无法打开也只要简单培训就能解决。 但随着用户类型变得广泛起来,这种“偶尔”也逐渐变成无法忍受,那么干脆直接导出 Excel 文件吧,反正开源库也已经成熟,于是使用 SheetJS

By 熊立丁
用 Aria2 & AriaNg 搭建离线下载平台

用 Aria2 & AriaNg 搭建离线下载平台

环境 硬件:Mac Mini 2014 4C4G 操作系统:Debian 12 IP地址:192.168.2.2 流程 1. 切换到管理员权限 su root 2. 安装 aria2 apt install aria2 3. 以服务的形式运行 aria2 aria2c --enable-rpc --rpc-listen-all=true --rpc-allow-origin-all --enable-rpc 启动 rpc 服务 --rpc-listen-all=true 允许从任意 IP 访问 --rpc-allow-origin-all 允许浏览器跨域访问 4. 配置 nginx 增加站点用于放置前端界面

By 熊立丁
浙ICP备15043004号-1