# grunt-combohtml

> combine build html with ssi.

Latest version **0.2.10** (published 2015-08-22) · MIT license · 0 weekly downloads

## Install

```sh
npm install grunt-combohtml
pnpm add grunt-combohtml
yarn add grunt-combohtml
bun add grunt-combohtml
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.2.10 |
| Published | 2015-08-22 |
| First published | 2013-08-08 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >= 0.8.0 |
| Dependencies | 7 |
| Known vulnerabilities | 0 (+1 in 1 direct dependencies) |
| Install scripts | no |
| Author | bachi |
| Maintainers | bachi, wayfind, paulguo, gourdboy, enmaai, dickeylth, wylking2000 |
| Keywords | gruntplugin |

## Links

- npm: https://www.npmjs.com/package/grunt-combohtml
- Repository: git@gitlab.alibaba-inc.com:trip-tools/grunt-combohtml
- Homepage: http://gitlab.alibaba-inc.com/trip-tools/grunt-combohtml/tree/master
- Issues: http://gitlab.alibaba-inc.com/trip-tools/grunt-combohtml/issues
- npm.io page: https://npm.io/package/grunt-combohtml

## Dependencies (7)

- [async](https://npm.io/package/async.md) ^0.7.0
- [juicer](https://npm.io/package/juicer.md) ~0.6.10-stable
- [passme](https://npm.io/package/passme.md) ~1.0.7
- [request](https://npm.io/package/request.md) ^2.34.0
- [html-proxy](https://npm.io/package/html-proxy.md)
- [iconv-lite](https://npm.io/package/iconv-lite.md) ~0.4.11
- [joinbuffers](https://npm.io/package/joinbuffers.md) ~0.1.1

## Recent versions

- 0.2.10 (latest) — 2015-08-22
- 0.1.48 — 2014-12-20
- 0.1.46 — 2014-12-02
- 0.1.45 — 2014-11-21
- 0.1.43 — 2014-11-20
- 0.1.42 — 2014-11-12
- 0.1.41 — 2014-10-28
- 0.1.40 — 2014-10-28
- 0.1.39 — 2014-10-11
- 0.1.38 — 2014-10-11
- 0.1.37 — 2014-10-03
- 0.1.36 — 2014-09-24
- 0.1.35 — 2014-09-24
- 0.1.34 — 2014-09-15
- 0.1.32 — 2014-08-12
- … 31 more at https://npm.io/package/grunt-combohtml/versions

## README

# grunt-combohtml

by 拔赤 & 弘树

HTML代码的构建,合并SSI,并提取其中引用的本地css和js，执行动态和静态合并,并输出构建好的html

## Getting Started

依赖 Grunt 版本`~0.4.5`

安装

```shell
npm install grunt-combohtml --save-dev
```

安装后，在 Gruntfile.js 中载入任务

```js
grunt.loadNpmTasks('grunt-combohtml');
```

## 任务配置

### 步骤

在 `grunt.initConfig()` 中添加 combohtml 的配置：

```js
grunt.initConfig({
	combohtml:{
		options:{
			encoding:'utf8',
			replacement:{
				from:/src\//,
				to:'build/'
			},
			// 本地文件引用替换为线上地址的前缀
			relative:'http://g.tbcdn.cn/path/to/project/',
			// 配合relative使用,将页面中所有以CDN引用的JS/CSS文件名进行拼合
			combineAssets: true, 
			// KISSY Modules Maps File 地址
			comboMapFile:'http://g.tbcdn.cn/path/to/maps.js',
			tidy:false,  // 是否重新格式化HTML
			mockFilter:true, // 是否过滤Demo中的JuicerMock
			comboJS:false, // 是否静态合并当前页面引用的本地js为一个文件
			comboCSS:false, // 是否静态合并当前页面引用的css为一个文件
			convert2vm:false,// 是否将juicer语法块转换为vm格式
			convert2php:false, // 是否将juicer语法块转换为php格式
			comboExt:'-combo', // 静态合并后的js和css后缀
			combineExt:'-min',// 所有的脚本是否转换成带-min后缀的形式
			htmlProxy: '<%= pkg.htmlProxy %>',      // htmlProxy 配置，用于产出线上页面区块替换为本地模块页面
			htmlProxyDestDir: 'html-fragments'      // html 代理区块页面生成到的目标目录
			meta: {
				'pageid': '<%= pkg.name%>/${path|regexp,"pages/",""}'
			}
		},
		main:{
			files: [
				{
					expand: true,
					cwd:'build',
					// 对'*.php'文件进行HTML合并解析
					src: ['**/*.php'],
					dest: 'build/'
				}
			]
		}
	}
});
```

### 配置说明

#### 资源文件合并配置 

**说明:relative 和 comboJS与comboCSS 的配置互斥！**

合并文件提供两种模式：

1. 代码静态合并：即页面中相对路径引用的资源文件都会被抓取合并为一个:

	```
	options:{
		encoding:'utf8',
		replacement:{
			from:/src\//,
			to:'build/'
		},
		comboJS:true, 
		comboCSS:true,
		comboExt:'-combo'
	}
	```

如果html中引用js和css时带有`?nocombo=true`参数，则不合并

2. combo模式合并：若希望页面中引用的相对路径都编译为绝对路径并组成combo的模式`http://url/??a.js,b.js`,需要开始`relative`字段,这时`comboJS`和`comboCSS`字段不起作用

	``` javascript
	options:{
		encoding:'utf8',
		replacement:{
			from:/src\//,
			to:'build/'
		},
		// 本地文件引用替换为线上地址的前缀
		relative:'http://g.tbcdn.cn/path/to/project/',
		// 配合relative使用,将页面中所有以CDN引用的JS/CSS文件名进行拼合
		combineAssets: true, 
		// KISSY Modules Maps File 地址,根据需要添加
		comboMapFile:'http://g.tbcdn.cn/path/to/maps.js'
	}
	```

#### html-proxy html 区块代理配置

这个是一个非常小众但很有用的功能，当我开发的代码是一个html片段，这个片段是被include到另外一个线上页面的某个位置（通过选择器指定），这个时候我就可以通过grunt-combohtml构建出一个带有线上页面完整信息的html页面，同时，线上页面里对应的位置被替换成了我当前开发的代码片段。这样我就不用为了调试某个线上页面，而去把线上页面的环境给克隆下来，只使用我的本地代理即可，本地代理使用[html-proxy](https://www.npmjs.com/package/html-proxy)来实现，grunt-combohtml 依赖了 html-proxy

其中 `htmlProxy` 的配置在 `abc.json` 中指定，这里读取配置，示例配置如下：

```js
  ...
  ,
  "htmlProxy": [{
      "urlReg": "http://tiehang.demo.taobao.net/ksdemo/html-proxy.html", // 要匹配的 url 正则表达式/页面url
      "replacements": [{	// 需要替换的各个区块和对应的选择器
          "fragment": "mods/demo/index.html",
          "selector": "#demo"
      }]
  }, {
      "urlReg": "^http://www.baidu.com/$",
      "demoPage": "http://www.baidu.com",	// 当urlReg 为正则表达式时，给定一个遵循该正则的示例页面用于做 html 区块合并
      "replacements": [{
          "fragment": "mods/demo/index.html",
          "selector": "#lg"
      }, {
          "fragment": "mods/nav/index.html",
          "selector": "#nv"
      }]
  }, {
      "urlReg": "^http://www.taobao.com/$",
      "demoPage": "http://www.taobao.com",
      "replacements": [{
          "fragment": "mods/demo/index.html",
          "selector": "#J_Promo"
      }, {
          "fragment": "mods/nav/index.html",
          "selector": "#J_Nav"
      }]
  }]
```

#### Juicer Mock

页面中的 JuicerMock 片段可以通过`mockFilter`字段来配置,原理参照[grunt-flexcombo](http://npmjs.org/grunt-flexcombo)

#### Meta 标签嵌入

通过 `options` 中的 `meta` 配置，以键值对形式传入每个 `meta` 的 key 和 value，构建时会自动生成对应的一条条 `<meta>` 标签嵌入 `</head>` 前。

除了可以通过 `<%=pkg.attribute %>` 读取环境变量之外，还提供了额外的环境属性，在 `meta` 中可按需配置，使用时遵循 [`Juicer`](http://juicer.name/docs/docs_zh_cn.html) 语法：

- `path`：当前处理的文件路径（以 `src` 路径为起点，如 `"pages/search/index.html"` ）
- `ts`: 时间戳

此外提供一个 `Juicer` 辅助函数 `regexp`，按需对上面的环境属性通过正则表达式进行截取或替换，如上面配置中的：

``` javascript
meta: {
	'pageid': '<%= pkg.name%>/${path|regexp,"pages/",""}'
}
```

代表将 `path` 中的 `pages/` 正则表达式字符串替换为 ""，也就是拿掉。


## 执行任务

	task.run(['combohtml']);

## 功能说明

### SSI 

该服务依赖[jayli-server](https://npmjs.org/package/jayli-server)，支持标准格式的 SSI include

	<!--#include virtual="file.html" -->

### XSSI 

除了标准的 SSI 语法支持，0.2.0 还支持重复插入以及简单变量替换：

```
/**
 * 处理格式为<!--#include ...-->的ssi插入.
 * @param  {JSON}ctx
 * @return {String}
 * @private
 * @example
 *
 * 1. 路径
 * -------------------------------------------------
 * 通过file属性制定的路径若以"."或".."开头则视为相对
 * 路径，否则视为据对路径，当视为绝对路径时，以项目
 * 的src目录作为根目录. 所以上面的代码用绝对路径表示
 * 可以这样写：
 *    <!--include file="/page/foo/sub.html"-->
 * 或者
 *    <!--include file="page/foo/sub.html"-->
 *
 * 2. 重复
 * -----------------------------------------------
 * 可以通过repeat参数来指定重复次数比如:
 *    <!--#include file="../sub.html" repeat="5" -->
 *
 * 3. 简单变量插入
 * ------------------------------------------------
 * 可以通过添加以$开头的属性指定插入文件中可以使用的变量，比如：
 *    <!--#include file="../sub.html" repeat="5"
 *        $name="zhang-san"
 *        $gender="f"
 *        $age="20"
 *        -->
 *
 * 那么sub.html就可以以如下格式使用这些变量:
 *    index  : <%=$__index__ + 1%>
 *    colum  : <%=$__index__ % 3%>
 *    total  : <%=$__count__%>
 *    gender : <%=$gender == 'f' ? '男' : '女' %>
 *    name   : <%=$name%>
 *    age    : <%=$age%>
 *
 * 上面的例子中有两个变量:$__count__、$__index__,
 * 这两个变量是系统自动添加进去的，分别代表文件被
 * 重复的次数以及当前重复索引(以0为起始）.
 *
 *  在使用简单变量插入功能时可以使用如下运算符:
 *     +  -  *  /  %  >=  <=  !=  >  <  ?:
 *  注意： 不支持括号，不支持多个三目运算符的嵌套.
 *
 * 注意: 在本程序中凡是以双下划线* "__"开头的变量名都
 * 是系统自动注入的，在inc-vars中不要使用这样变量名，
 * 否则有可能会被覆盖掉.
 */
```

## 版本历史

- [0.2.7]
    - 加入 `options.combineExt`，默认为 `-min`，控制 js、css combo 时的 url  里资源路径是否带 `-min`
    
- [0.2.8]
    - bugfix for juicer render
    
- [0.2.9]
    - 解决 juicer 不指定版本号问题
    
- [0.2.10]
    - [+] 引入 xssi，支持引入文件的变量解析

---
_Source: https://npm.io/package/grunt-combohtml · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
