jdists(<>) 前端代码块预处理工具

什么是 jdists 项目地址:https://github.com/zswang/jdists 关于命名 j dist s 就是 js 里插入了一个 dist (分发),避免和其他...
什么是 jdists
项目地址:https://github.com/zswang/jdists
关于命名
j dist s 就是 js 里插入了一个 dist (分发),避免和其他组件命名冲突,同时特殊好记。 本工具专注于前端代码块(js、css、html)预处理。
起因
一个页面从开发到上线基本会经历三个阶段:
  • 本机开发调试
打印一些变量和执行状态、模拟数据接口
  • 内网测试
跳过某些步骤、使用内网环境
  • 公网上线
移除调试代码、使用线上环境。

其实前端代码和其他语言代码都需要编译,目前已经有很多成熟的工具来完成编译的事情。 比如:fis、grunt、gulp,基本都是依赖配置文件,将项目代码进行编译到相应版本。
问题
  • 代码和配置文件是分离的,这样开发维护起来不够直观。
  • 配置文件通常是基于 JSON,还是不够直观。
  • 调试代码容易遗忘,有导致线上**的风险。
思考
那有没有一种方法能将部分编译逻辑写在代码中,就像 C 语言预编译宏定义,代码本身就包含了编译逻辑不依赖配置文件就能执行:
#include "headfile"#ifdef DEBUGfprintf("variant=%d", variant);#endif

这样不仅利于维护也方便在本机开发时调试,那么接下来需求来了!
需求
  • 学习成本要很低。(使用 html 标记,这个大家再熟悉不过)
  • 支持 html、css、js 文件格式。
  • 本机开发调试时不依赖编译器。(编译逻辑写在注释中)
  • 不仅能 include 一个文件,还能 include 一个文件中的片段(代码块)。
  • 能引入当前文件的代码块。
  • 能够替换代码块的内容。
  • 能 include 二进制文件,变为 base64 字符串,方便转成 dataUri。
  • 自动合并 css 或 js 文件,能够输出合并文件并能打 md5 戳。
  • 能够处理 注释模板,避免被压缩工具移除
var render = jhtmls.render(function () {/*!<div title="#{title}">#{content}</div>*/});

  • 能够扩展替换规则。
设计思路
解决好如何定义代码块,其他问题基本就迎刃而解了。
用什么方式来定义代码块?
利用注释 + html 标记,并且又能和普通注释区分。
  • 在 html 中:
<!--debug--><div>测试版本</div><!--/debug-->

  • 在 js 中:
/*<debug>*/console.log('测试版本');/*</debug>*/
  • 在 css 中:
.version {  font-size: 12px;/*<debug>*/  color: red;/*</debug>*/}
一些代码未必默认启用,所以支持如下方式
在 html 中:
<!--release<div>线上版本</div>/release-->

在 js 中:

/*<releaseconsole.log('测试版本');/release>*/

在 css 中:
.version {  font-size: 12px;/*<release  color: red;/release>*/}

废弃的方式
<!--debug begin--><div>测试版本</div><!--debug end-->

  • 使用 being / end 的方式,主要的问题是容易遗忘,该前缀还是后缀

基本概念

标准代码块

代码属性(attribute)

编码(encoding)


  • original:原文
  • string:作为字符串
  • base64:base64 输出
  • md5:内容 MD5 戳(小写)
  • concat:合并本地 js 或 css 并可以知道输出

可以通过 jdists.setEncoding(encoding, processor) 扩展


使用限制


  • 代码块不能交叉,可以嵌套
  • 代码块引用不能出现循环


实战


开始使用


  • 依赖 npm 环境
  • 安装 $npm install jdists -g
  • 命令格式 $jdists input1 [input2] [-output output] [-remove debug,test]
  • 命令参数

处理 js 中的 注释模板


假设文件 js/base.js 内容为:

var render = jhtmls.render(function() {/*!

<ul>

forEach(function(item) {

  <li>#{item.title}</li>

});

<ul>

*/});


如上可以省去拼接字符串的工作,直观好维护。但经过带压缩后就变成:
var render=jhtmls.render(function(){});

怎么避免 注释模板 被替换?
$jdists js/base.js -o dist/js/base.js

生成的文件是:
var render = jhtmls.render('<ul>nforEach(function(item) {n  <li>#{item.title}</li>n});n<ul>');

jdists 默认会处理 注释模板
发布代码
假设文件 js/net.js 内容为:
var ajax = ajax || {};void function(exports) {/*<replace  exports.host = 'http://api.baidu.com/1.0/getuser';/replace>*/}(ajax);
$jdists js/net.js -o dist/js/net.js
生成的文件是:
var ajax = ajax || {};void function(exports) {  exports.host = 'http://api.baidu.com/1.0/getuser';}(ajax);

还有一种情况,是我们需要先编译一个局域网版本
假设文件 js/net.js 内容为:
var ajax = ajax || {};void function(exports) {/*<replace trigger="release"  exports.host = 'http://api.baidu.com/1.0/getuser';/replace>*//*<replace trigger="LAN"  exports.host = 'http://http://192.168.1.67:8000/1.0/getuser';/replace>*/}(ajax);

$jdists js/net.js -o dist/js/net.js -t LAN
生成的文件是:
var ajax = ajax || {};void function(exports) {/*<replace trigger="release"  exports.host = 'http://api.baidu.com/1.0/getuser';/replace>*/  exports.host = 'http://192.168.1.67:8000/1.0/getuser';}(ajax);

指定 trigger 的代码块,会检查是否命中配置的触发器,如果没有命中则不启用功能。
合并静态资源
还是依所见即所得的设计思路,开发期的 html 指明了依赖的静态文件,如:
index.html
<html><head>  <!--replace encoding="concat" js="dist/all.js" css="dist/all.css"-->  <link rel="stylesheet" type="text/css" href="base.css">  <link rel="stylesheet" type="text/css" href="button.css">  <script src="base.js"></script>  <script src="replace.js"></script>  <!--/replace--></head><body>...</body></html>

$jdists index.html -o dist/index.html
生成的文件是:
<html><head>  <script src="dist/all.js"></script>  <link rel="stylesheet" type="text/css" href="dist/all.css"></head><body>...</body></html>

同时将本地静态资源分别合并到 dist/all.js 和 dist/all.css
打包组件
通过 jdists 可以将零散的代码和静态资源,拼凑为一个完整的组件
void function() {  var bar = document.getElementById('jfpss-bar');  if (bar) {    return;  }
  /*<include components/jframes/src/jframes.js>*/  ;  /*<include components/jhtmls/src/jhtmls.js>*/  ;  /*<include src/jfpss.js>*/
  createStyle(function() {/*!<!--include src/tools.html style-->*/});
  var div = document.createElement('div');  div.innerHTML = function() {/*!<!--include src/tools.html html-->*/};  document.body.appendChild(div);
  /*<include src/tools.html js>*/}();

这样就可以用静态页面开发 UI 组件了。
参考实例:https://github.com/zswang/jfpss/blob/master/src/tools.jdists
后续
  • 加入自动内联代码。
  • 提供 fis、grunt、gulp 插件。
项目地址:https://github.com/zswang/jdists
作者:zswang (http://weibo.com/zswang)

更多 replace 相关内容

更多 var 相关内容