项目地址:https://github.com/zswang/jdists
j dist s 就是 js
里插入了一个 dist
(分发),避免和其他组件命名冲突,同时特殊好记。
本工具专注于前端代码块(js、css、html)预处理。
一个页面从开发到上线基本会经历三个阶段:
-
本机开发调试
- 打印一些变量和执行状态、模拟数据接口
-
内网测试
- 跳过某些步骤、使用内网环境
-
公网上线
- 移除调试代码、使用线上环境。
其实前端代码和其他语言代码都需要编译,目前已经有很多成熟的工具来完成编译的事情。 比如:fis、grunt、gulp,基本都是依赖配置文件,将项目代码进行编译到相应版本。
- 代码和配置文件是分离的,这样开发维护起来不够直观。
- 配置文件通常是基于 JSON,还是不够直观。
- 调试代码容易遗忘,有导致线上事故的风险。
那有没有一种方法能将部分编译逻辑写在代码中,就像 C 语言预编译宏定义,代码本身就包含了编译逻辑不依赖配置文件就能执行:
#include "headfile"
#ifdef DEBUG
fprintf("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>
*/});
jdists 处理后 --->
var render = jhtmls.render('<div title="#{title}">#{content}</div>');
比如:参数自识别
instance.get( /*,*/ function(a, b, c) {
// TODO
});
jdists 处理后 --->
instance.get(['a', 'b', 'c'], function(a, b, c) {
// TODO
});
- 能够扩展替换规则。
解决好如何定义代码块,其他问题基本就迎刃而解了。
利用注释 + 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 中:
/*<release>
console.log('测试版本');
</release>*/
- 在 css 中:
.version {
font-size: 12px;
/*<release>
color: red;
</release>*/
}
<!--debug begin-->
<div>测试版本</div>
<!--debug end-->
<!--start debug-->
<div>测试版本</div>
<!--end debug-->
- 使用
begin
|start
/end
的方式,容易遗忘:前缀还是后缀、begin
还是start
/*<release
color: red;
/release>*/
- 不能处理单行
<!--include file="base.html" block="b1"-->
<!--include file="base.html" block="b1" /-->
<!--debug file="base.html" block="b1" --><em>debug</em><!--/debug-->
<!--debug file="base.html" block="b1"><em>debug</em></debug-->
/*<include file="base.html" block="b1" >*/
/*<include file="base.html" block="b1" />*/
/*<debug file="base.html" block="b1">*/<em>debug</em>/*</debug>*/
/*<debug file="base.html" block="b1"><em>debug</em></debug>*/
名称 | 含义 | 例子 | 备注 |
---|---|---|---|
file | 文件 | 1.js,1.png | 包括二进制文件 |
block | 代码块 | 只能是文本文件 | |
block::tag | 标签 | <a> |
|
block::attribute | 代码块属性 | <a encoding="md5"> |
|
encoding | 编码器 | 将代码块进行编码处理 |
tag | 功能 | 示例 |
---|---|---|
include | 引入文件或代码块 | <!--include file="all.js" /--> |
replace | 将当前代码块替换成文件或代码块 | |
remove | 将当前代码移除 |
属性名 | 含义 | 例子 | 备注 |
---|---|---|---|
encoding | 编码 | encoding="base64" | 默认"original",可扩展 |
slice | 裁剪 | slice="1,-1" | 参考 String.slice() 函数 |
file | 文件名 | file="all.js" | 默认当前文件 |
export | 导出文件 | export="output.js" | 如何为 '#' 或 ':' 开头则输出到内存中 |
block | 代码名 | block="hello" | 引入的块名 |
type | 类型 | type="comment" | 默认"original","comment":去掉包裹代码块的注释 |
trigger | 触发器 | trigger="release,LAN" | 默认"release",存在这些触发器时才生效 |
js | js 文件 | js="all_{{md5,7}}.js" | 输出的 js 文件名 |
css | css 文件 | css="all_{{md5,7}}.css" | 输出的 css 文件名 |
{{md5,len}} 计算内容的 md5 值,len 指定长度
- original:原文【默认】
- string:作为字符串
- base64:base64 输出
- md5:内容 MD5 戳(小写)
- concat:合并本地 js 或 css 并可以知道输出
- inline:内链文件
- relative:静态资源相对路径
- require:AMD 自动依赖处理
- template:模板
- zero:零宽字符加密
可以通过 jdists.setEncoding(encoding, processor)
扩展
- 代码块不能交叉,可以嵌套
- 代码块引用不能出现循环
-
依赖 npm 环境
-
安装
$ npm install jdists -g
-
命令格式
$ jdists input1 [input2] [-output output] [-remove debug,test] [-tigger release]
-
命令参数
参数 | 简写 | 功能 | 备注 |
---|---|---|---|
-output | -o | 指定输出文件 | 默认输出到控制台 |
-remove | -r | 指定移除的代码块 | 默认 "debug,test" |
-trigger | -t | 指定触发器 | 默认 "release" |
-clean | -c | 清除空白行 | 默认 true |
-version | -v | 打印当前版本 |
假设文件 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/base.js
内容为:
instance.get( /*,*/ function(name, x, y, width, height) { ... });
我们可以通过函数声明中的参数列表判断需要获取的值,但是参数经过压缩后名字就变了,如:
instance.get(function(a,b,c,d){ ... });
jdists 同样可以帮我们处理
$jdists js/base.js -o dist/js/base.js
生成的文件是:
instance.get(['name','x','y','width','height'],function(a,b,c,d){ ... });
假设文件 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="all.js"></script>
<link rel="stylesheet" type="text/css" href="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 插件。