用 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

更多

Quasar中的前端代码转译

使用 Quasar 时,如何完成浏览器兼容性的配置。 制定兼容范围 在进行实际配置前,首先必须确定要支持浏览器的版本,而确定浏览器版本则需要先明确业务对象的情况。 为什么不干脆把标准定的越高越好呢?比如支持100%的用户。这是因为支持率越高,可用的新语法越少,意味着更多的转译代码和 polyfill,这会带来额外的代码量,从而导致下载数据量增加,以及运行速度变慢的问题,为了0.01%影响99.99%用户的体验并增加他们的流量开销,是否合适呢?这就需要根据实际业务进行取舍和平衡。 比如我们的业务对象既有企业用户,也有公众用户,企业用户主要使用钉钉,并可对其PC浏览器进行要求,而公众用户主要使用微信。 确定常用浏览器版本 PC浏览器可以指定,那么对浏览器版本就不需要过多考虑,但是部分客户还有XP系统,那么也就确定了 Chrome 浏览内核的版本不可以超过 49; 微信用户可能在手机登录,也可能在PC登录,而PC中的微信内置是QQ浏览器9,其内核版本是 Chrome 53; 电脑端的钉钉内置浏览器已经是 Chrome 91; 手机端的话考虑到安卓手机使

By 熊立丁
浙ICP备15043004号-1