express+gulp构建项目(五)swig模板
这里的文件负责配置swig模板引擎。
index.js
var jsonHash = require('./json_file'); var staticTag = require("./tag-static"); exports.init = function (swig) { swig.setExtension('static', function (input) { //swig.setExtension为自定义标签添加扩展。'static'为自定义标签的名字 //input是通过模板标签取到的值 var hashList = {}, output = input; var isJs = (/(\.js)$/).test(input); var isCss = (/(\.(scss|css))$/).test(input); if (isJs) { hashList = jsonHash.jsHash(); } else if (isCss) { hashList = jsonHash.cssHash(); input = input.replace(/(\.scss)$/, '.css'); // } else { hashList = jsonHash.imgHash(); } //根据文件类型获取相应的名单 if (hashList[input]) { output = '/' + STATIC_URL + hashList[input]; } else if (NODE_ENV === 'dev' && isCss || isJs) { output = '/' + STATIC_URL + input; } else { output = '/' + STATIC_URL + input; } //确定文件名和路径 return output; }); swig.setTag('static', staticTag.parse, staticTag.compile, staticTag.ends, staticTag.blockLevel); // parse自定义解析函数,compile自定义编译函数,ends是否需要结束标签,blockLevel如果是false,则它不会被编译到block外面当它继承一个父模板的时候 };
json_file.js
var jsonfile = require('jsonfile'); var csshashFile, jsHashFile, imgHashFile; var cssCompressed, jsCompressed, imgCompressed; var isDev = NODE_ENV === 'dev'; try { csshashFile = jsonfile.readFileSync('./hash/css_hash.json'); //读取hash名单,如果可以读取到json文件,说明已经执行过gulp build任务,在hash文件夹下生成相应的名单文件 cssCompressed = true; } catch (e) { csshashFile = {}; } try { jsHashFile = jsonfile.readFileSync('./hash/js_hash.json'); jsCompressed = true; } catch (e) { jsHashFile = {}; } try { imgHashFile = jsonfile.readFileSync('./hash/img_hash.json'); imgCompressed = true; } catch (e) { imgHashFile = {}; } exports.cssHash = function () { var file = isDev ? (cssCompressed ? jsonfile.readFileSync('./hash/css_hash.json') : csshashFile) : csshashFile; var json = {}; for (var key in file) { var l = key, r = file[key]; json['/' + l] = '/' + STATIC_FILES_OUTPUT + '/' + r; //取出名单存入对象并返回 } return json; }; exports.jsHash = function () { var file = isDev ? (jsCompressed ? jsonfile.readFileSync('./hash/js_hash.json') : jsHashFile) : jsHashFile; var json = {}; for (var key in file) { var l = key, r = file[key]; json['/' + l] = '/' + STATIC_FILES_OUTPUT + '/' + r; } return json; }; exports.imgHash = function () { var file = isDev ? (imgCompressed ? jsonfile.readFileSync('./hash/img_hash.json') : imgHashFile) : imgHashFile; var json = {}; for (var key in file) { var l = key, r = file[key]; json['/' + l] = '/' + STATIC_FILES_OUTPUT + '/' + r; } return json; };
tag-static.js
exports.parse = function (str, line, parser, types, options) { var matched = false; parser.on('*', function (token) { if (matched) { throw new Error('Unexpected token ' + token.match + '.'); } matched = true; return true; }); return true; }; exports.compile = function (compiler, args, content, parents, options, blockName) { return '_output += _ext.static(' + args[0] + ');'; }; exports.ends = false; exports.blockLevel = false;
swig模板经过这一系列的配置是什么样的效果呢?
原来在gulp任务里通过gulp-rev-all-fixed的处理后,给所有的静态文件的文件名加上了哈希值,并且如果文件有变化,哈希值文件名就就会变化。
就像这样,扩展名之前的六位就是哈希值的名字,会随文件的变动而变化。
然后我们自定义的static swig标签就是为了处理文件引用时文件名的问题,当我们写html的时候,引入的文件都用自定义标签来写。
<link rel="stylesheet" href="{% static '/css/base.scss' %}" /> <link rel="stylesheet" href="{% static '/widget/global/fonts/font-awesome/font-awesome.min.css' %}">
当swig编译html的时候看到自定义标签就会去找hash文件夹下的名单文件,名单文件里是一个对象,是源文件名对应改变后的哈希文件名,然后根据规则替换,引入的文件就不会因为名字不对而报错了。css样式里的背景图片的url也会被替换。做这样设置的原因是为了防止浏览器缓存静态文件。