Skip to content
This repository has been archived by the owner on Jul 28, 2022. It is now read-only.

feilongDisplay concat

feilong edited this page Jun 25, 2018 · 17 revisions

CSS/JS合并及版本控制 的自定义标签

1 描述(Description):

HttpConcatTag 一个 css/js合并及版本控制自定义标签

可以:

  1. 生成 http concat形式js/css链接,很好的和 tengine / apache mod_concat 协调工作
  2. 支持版本控制
  3. 简化js,css写法,统一js/css输出的格式,避免手写出错以及不符合html规范的代码
遵循Yahoo!前端优化准则第一条:减少HTTP请求发送次数
	如果开启合并开关(见附录1),生成的连接:
• 以两个问号(??)激活combo
• 多文件之间用半角逗号(,)分开
• 用一个?来辨识时间戳

示例1:

<%@ taglib prefix="feilongDisplay" uri="http://java.feilong.com/tags-display"%>
<feilongDisplay:httpConcat type="css" version="${version_css}">
	js/payment/memberAddress.css
	js/payment/order.css
</feilongDisplay:httpConcat>

渲染结果:

<link rel="stylesheet" type="text/css" media="screen" href="??js/payment/memberAddress.css,js/payment/order.css?20140514" />

示例2:

since 1.10.4 , 支持包裹原生态的写法,参见 #18

<%@ taglib prefix="feilongDisplay" uri="http://java.feilong.com/tags-display"%>
<feilongDisplay:httpConcat version="2017" type="css" httpConcatSupport="true" domain="http://css.feilong.com:8888/">
	<link rel="stylesheet" href="http://css.feilong.com:8888/res/feilong/css/feilong-all.css" type="text/css"></link>
	<link rel="stylesheet" href="res/feilong/css/common.css" type="text/css"></link>
	<link rel="stylesheet" href="res/feilong/css/taglib.css?version=123456" type="text/css"></link>
</feilongDisplay:httpConcat>

渲染结果:

<link rel="stylesheet" type="text/css" media="screen" href="http://css.feilong.com:8888/??res/feilong/css/feilong-all.css,res/feilong/css/common.css,res/feilong/css/taglib.css?2017" />

示例 3:

since 1.11.2 , 支持无参格式,全部属性使用全局配置

<%@ taglib prefix="feilongDisplay" uri="http://java.feilong.com/tags-display"%>
<feilongDisplay:httpConcat>
	<link rel="stylesheet" href="http://css.feilong.com:8888/res/feilong/css/feilong-all.css" type="text/css"></link>
	<link rel="stylesheet" href="res/feilong/css/common.css" type="text/css"></link>
	<link rel="stylesheet" href="res/feilong/css/taglib.css?version=123456" type="text/css"></link>
</feilongDisplay:httpConcat>

2 参数(Parameters):

参数 说明 类型 Since 默认值 required 示例
type 资源类型, 可用值 js或者css, 忽视大小写 String 1.0 false 1.11.2 改成非必须参数 js
version 版本号,不建议直接使用时间戳,容易被黑客CDN攻击,建议使用md5参数或者随机数 String 1.0 true j16b3adc77c0d3e9df617d3178fe43445
domain 域名,某些商城有子域名 String 1.0 false http://image.nikestore.com.cn ,也可以写成 http://image.nikestore.com.cn/ (最后带/)
root 目录 String 1.0 false 设置root为'/script' 会拼成http://staging.nikestore.com.cn/script/??jquery/jquery-1.4.2.min.js?16b3adc77c0d3e9df617d3178fe43445
httpConcatSupport 是否支持 http concat(如果设置这个参数,本次渲染,将会覆盖全局变量). Boolean 1.0.7.1 false true

3 关于block 块:

3.1 示例:

<feilongDisplay:httpConcat type="js" domain="${staticbase}/" version="${version_js}">

	<!-- 我是html行注释--!>
	<%-- 我是jsp注释	--%>

	<%-- 注意js 加载顺序,有依赖关系	--%>
	scripts/pdp/pdp-common.js
	scripts/pdp/sub_salesProperties.js

	<%--
		sub-*.jsp里面不放 js,统一在主页面进行加载
		非核心js放下方 ,这样核心内容能优先加载
		-- by feilong
	--%>
	scripts/pdp/sub_sns.js

</feilongDisplay:httpConcat> 

3.2 要典:

  1. 每行一个css/js元素
  2. block里面的元素要一致,暂不支持css和js混写
  3. 每行开头结尾可以有空格 tab,程序会自动去空
  4. 可以有重复元素(不建议),程序会自动去重,
  5. 按照书写的顺序,进行拼接
  6. 可以有空白行,程序会自动忽视空白行
  7. 如果block里面没有任何元素,那么直接输出空白字符
  8. 可以只有一条元素,不会使用concat,程序会直接输出原生链接
  9. 可以写注释,支持JSP 的注释格式<%--xxx --%>,以及HTML单行注释 <!---->

    关于JSP注释,详见:http://roseindia.net/jsp/simple-jsp-example/comment.shtml

4 配置文件:

配置文件有1个,config/httpconcat.properties

文件路径 默认读取config/httpconcat.properties

4.1 config/httpconcat.properties 内容:

#是否支持httpconcat
httpconcat.support=false

#---------------------------------------------------
# domain config since 1.11.2
#---------------------------------------------------

# 如果没有配置或者是空,不会解析
httpconcat.domain=

#---------------------------------------------------
# version config since 1.11.2
#---------------------------------------------------

# httpconcat version 作用域里面变量名字
# 如果没有配置或者是空,那么不会去作用域中查找
httpconcat.version.nameInScope=httpconcatVersion

# version 名字在哪个作用域
# 如果没有值那么会依次从系列作用域中去找值 page request session application
httpconcat.version.search.scope=request

# version值的加密格式,值可以是 md5 或者sha1 (忽视大小写)
# 如果没有配置, 那么显示原样内容
# 如果需要这个功能, 需要依赖 feilong-security jar

# 第一次解析会执行encode ,以后调用从缓存中取结果
httpconcat.version.encode=md5

# 当version 值是 指定value的时候, 每次自动变
httpconcat.version.autoRefresh.value=default_Version_Maven_Install_Will_Replace
#---------------------------------------------------

#---------------------------------------------------
# cache config
#---------------------------------------------------

#设置缓存是否开启
httpconcat.defaultCacheEnable=true

#cache size 限制,仅当 {@link #DEFAULT_CACHEENABLE}开启生效, 当cache数达到 {@link #DEFAULT_CACHESIZELIMIT},将不会再缓存结果
#经过测试
#<ul>
#<li>300000 size cache占用 内存 :87.43KB(非精准)</li>
#<li>304850 size cache占用 内存 :87.43KB(非精准)</li>
#<li>400000 size cache占用 内存 :8.36MB(非精准)</li>
#</ul>
#
#对于一个正式项目而言,http concat的cache, size极限大小会是 <blockquote><i>页面总数(P)*页面concat标签数(C)*i18N数(I)*版本号(V)</i></blockquote><br>
#如果一个项目 页面有1000个,每个页面有5个concat块,一共有5种国际化语言,如果应用重启前支持5次版本更新,那么计算公式会是 <blockquote><i>1000*5*5*5=50000</i></blockquote>
#<b>注意:此公式中的页面总数是指,VM/JSP的数量,除非参数不同导致VM/JSP渲染的JS也不同,另当别论</b>
httpconcat.defaultCacheSizeLimit=300000

#---------------------------------------------------
# template config,dont need change
#---------------------------------------------------

httpconcat.template.css=<link rel="stylesheet" type="text/css" media="screen" href="{0}" />\n
httpconcat.template.js=<script type="text/javascript" src="{0}"></script>\n

4.2 参数说明

4.2.1 httpconcatSupport

#是否支持httpconcat
httpconcat.support=false

httpconcatSupport用来全局控制是否使用 http concat

开发环境或者没有tengine / apache mod_concat等环境的可以把这个参数设置为false,这样生成的均为原生的css或者js链接

4.2.2 httpconcat.domain

#---------------------------------------------------
# domain config since 1.11.2
#---------------------------------------------------

# 如果没有配置或者是空,不会解析
httpconcat.domain=http://css.feilong.com:8888/

如果 feilongDisplay:httpConcat 标签没有设置domain属性, 那么会使用此处配置的全局值

<feilongDisplay:httpConcat>
	<link rel="stylesheet" href="http://css.feilong.com:8888/res/feilong/css/feilong-all.css" type="text/css"></link>
</feilongDisplay:httpConcat>

4.2.3 httpconcat.version.nameInScope 和 httpconcat.version.search.scope

#---------------------------------------------------
# version config since 1.11.2
#---------------------------------------------------

# httpconcat version 作用域里面变量名字
# 如果没有配置或者是空,那么不会去作用域中查找
httpconcat.version.nameInScope=httpconcatVersion

# version 名字在哪个作用域
# 如果没有值那么会依次从系列作用域中去找值 page request session application
httpconcat.version.search.scope=request

当 feilongDisplay:httpConcat 标签没有设置 version 属性, 那么会从指定的scope (httpconcat.version.search.scope)里面找指定的参数(httpconcat.version.nameInScope)值

<feilongDisplay:httpConcat>
	<link rel="stylesheet" href="http://css.feilong.com:8888/res/feilong/css/feilong-all.css" type="text/css"></link>
</feilongDisplay:httpConcat>

4.2.4 httpconcat.version.encode

#---------------------------------------------------
# version config since 1.11.2
#---------------------------------------------------

# version值的加密格式,值可以是 md5 或者sha1 (忽视大小写)
# 如果没有配置, 那么显示原样内容
# 如果需要这个功能, 需要依赖 feilong-security jar

# 第一次解析会执行encode ,以后调用从缓存中取结果
httpconcat.version.encode=md5

#---------------------------------------------------

如果httpconcat.version.encode 配置了值 (值只能是 md5 或者sha1 (忽视大小写))

那么 version值将会经过 md5 或者sha1 处理

4.2.5 httpconcat.version.autoRefresh.value

#---------------------------------------------------
# version config since 1.11.2
#---------------------------------------------------

# 当version 值是 指定value的时候, 每次自动变
httpconcat.version.autoRefresh.value=default_Version_Maven_Install_Will_Replace
#---------------------------------------------------

当version 值是 指定value的时候, 每次自动变, 解决开发环境version值不会自动刷新的问题

4.2.6 cache config

#---------------------------------------------------
# cache config
#---------------------------------------------------

#设置缓存是否开启
httpconcat.defaultCacheEnable=true

#cache size 限制,仅当 {@link #DEFAULT_CACHEENABLE}开启生效, 当cache数达到 {@link #DEFAULT_CACHESIZELIMIT},将不会再缓存结果
#经过测试
#<ul>
#<li>300000 size cache占用 内存 :87.43KB(非精准)</li>
#<li>304850 size cache占用 内存 :87.43KB(非精准)</li>
#<li>400000 size cache占用 内存 :8.36MB(非精准)</li>
#</ul>
#
#对于一个正式项目而言,http concat的cache, size极限大小会是 <blockquote><i>页面总数(P)*页面concat标签数(C)*i18N数(I)*版本号(V)</i></blockquote><br>
#如果一个项目 页面有1000个,每个页面有5个concat块,一共有5种国际化语言,如果应用重启前支持5次版本更新,那么计算公式会是 <blockquote><i>1000*5*5*5=50000</i></blockquote>
#<b>注意:此公式中的页面总数是指,VM/JSP的数量,除非参数不同导致VM/JSP渲染的JS也不同,另当别论</b>
httpconcat.defaultCacheSizeLimit=300000

4.2.7 template

#---------------------------------------------------
# template config,dont need change
#---------------------------------------------------

httpconcat.template.css=<link rel="stylesheet" type="text/css" media="screen" href="{0}" />\n
httpconcat.template.js=<script type="text/javascript" src="{0}"></script>\n

css js 模板, 通常不需要改

4.3 关于配置文件区分多环境

项目区分多环境是大部分项目的共有特征,文件存放方式可能是下面的情况

文件存放方式可能是以下情况

该情况下,需要在maven install期间,使用插件将文件自动移动到 config目录下面 参见代码片段:

...
<build>
	...
	<plugins>
		...
		<plugin>
			<artifactId>maven-antrun-plugin</artifactId>
			<executions>
				<execution>
					<phase>compile</phase>
					<configuration>
						<target>
							<move todir="target/classes/config" file="target/classes/config/${spring.profiles.active.value}/httpconcat.properties" overwrite="true" verbose="true"
								includeEmptyDirs="true" />
						</target>
					</configuration>
					<goals>
						<goal>run</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
		...
	</plugins>
	...
</build>
...

4.4 规范js/css输出

在没有使用 concat标签的时候,大家都是手写链接,比如

会出现写法不统一

会出现写法不统一, 比如有人不写 type="text/css", 有人script标签关闭,使用 xxxx.js"/>

有人多写了</script>

有人多写了</script>

等等不一而足

concat使用统一的配置模板,详见配置文件部分,生成的链接统一整齐

如果是mobile项目,还可以自定义模板,以便支持手持等设备

5 最佳实践

5.1 数量过多,报错

http://s.mp2.com/??static/public/js/jquery.jqzoom-core.js,static/public/js/jquery.json-2.4.js,static/marketplace/js/item/memberFavorite.js,static/marketplace/js/buyNow/addShoppingCart.js,static/marketplace/messages/messageDetail_en_US.js,static/marketplace/js/item/itemPDPDetail.js,static/marketplace/js/item/itemPDPDetail_subData.js,static/marketplace/js/item/itemPDPDetail_paging.js,static/public/js/cascading/jquery.cascading.data.js,static/public/js/cascading/jquery.cascading.js,static/marketplace/js/item/youMayLikeItemForPDP.js,static/livechat/js/livechat.js,static/trade/js/tradeFeedbacks/rating.js,static/public/components/faceBook/faceBookInit.js,static/member/messages/message_dialogSignIn_en_US.js?16b3adc77c0d3e9df617d3178fe43445

提示 400 Bad request

提示 400 Bad request

原因:tengine 默认文件连接最大值 是 10

可以通过配置 concat_max_files 来更改

默认:concat_max_files 10

上下文: http, server, location

定义最大能接受的文件数量。

由此也可以看出,在文件数量上,如果文件多,尽量分成两个或者多个链接,也不建议一个页面上有过多的js 

5.2 css合并最佳实践

<feilongDisplay:httpConcat type="css" domain="${staticbase}/" version="${version_css}" root="/static/public/css">
default.css
font.css
loxia_table.css
</feilongDisplay:httpConcat>
<feilongDisplay:httpConcat type="css" domain="${staticbase}/" version="${version_css}" root="/static/">
managementsystem/css/op.css
</feilongDisplay:httpConcat>

建议只合并同目录的css,不同目录的css不建议合并

避免合并带来的相对路径图片样式问题

5.3 kindeditor js合并出错

有些插件不能参与js合并,比如原代码

原代码

但是测试环境,tengine下,富文本编辑器出不来

富文本编辑器出不来

路径里面会自动增加一个default.css

路径里面会自动增加 一个default.css

看了下 kindeditor-all.js,js记载的时候会自动加载两个css

会自动加载两个css

因此富文本编辑器这样的插件,不要参与合并,单独起来,更改成

不要参与合并,单独起来

两个文件单独引用,合并引用会仍然会加载不了css,kindeditor语言包依赖于kindeditor.js,由于可能自定义的js会操作kindeditor对象,尽量将kindeditor依赖引用在前

这么一来也可以看出,不管是css还是js尽量按照同目录合并,不同目录不合并的原则,可以减少很多麻烦

6.参见

--完