gulp-xtpl
Version:
Gulp XTpl (XTemplate) for TMall Biz
204 lines (173 loc) • 7.76 kB
JavaScript
// ┌────────────────────────────────────────────────────────────────┐ \\
// │ Gulp XTpl (XTemplate) for TMall Biz │ \\
// ├────────────────────────────────────────────────────────────────┤ \\
// │ Authors koolc<1041860930@qq.com> │ \\
// ├────────────────────────────────────────────────────────────────┤ \\
// │ Copyright (c) 2014-2015 TMall F2E │ \\
// │ Licensed under the MIT license. │ \\
// └────────────────────────────────────────────────────────────────┘ \\
// Copyright (c) 2014 TMall F2E. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
;
var Buffer = require('buffer').Buffer;
var through = require('through2');
var XT = require('xtemplate');
var deepMerge = require('deepmerge');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
var pkg = require('./package.json');
var request = require('npm-request');
var path = require('path');
require('colors');
function merge() {
for (var args = arguments, l = args.length, i = 1; i < l; i++) {
args[0] = deepMerge(args[0], args[i]);
}
return args[0];
}
function isFunction(v) {
return typeof v === 'function';
}
function genModName(file) {
return (file.path || '')
.replace(process.cwd().replace(/(\/mui)?\/[\w\.-]+$/g, '/'), '')
.replace(/\/(src|build|test|doc|lib)\//, '/')
.replace(/\.js$/, '');
}
var requote_reg = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
function requote(s) {
return s.replace(requote_reg, "\\$&");
}
function substitute(str, obj) {
str = str || '';
obj = obj || {};
var keys = Object.keys(obj) || [];
if (!keys.length) {
return str;
}
var combo = requote(keys.join(',')).replace(/,/g, '|'),
reg = new RegExp('\{\{(' + combo + ')\}\}', 'g');
str = str.replace(reg, function ($, $1) {
return obj[$1];
});
return str;
}
function wrapper(content) {
// @formatter:off | Intellij IDEA Setting
return 'function (S, RT) {\n' +
' var instance;\n' +
' var compiled = ' + content + ';\n' +
' return function (d) {\n' +
' instance = instance || new RT(compiled);\n' +
' return instance && instance.render(d) || "";\n' +
' };\n' +
'}';
// @formatter:on
}
function log() {
var args = Array.prototype.slice.call(arguments, 0);
args.unshift('[' + 'gulp-xtpl'.gray + ']');
console.log.apply(console, args);
}
function checkVersion() {
var root;
if (process.platform === 'win32') {
root = process.env.USERPROFILE || process.env.APPDATA || process.env.TMP || process.env.TEMP;
} else {
root = process.env.HOME || process.env.TMPDIR || '/tmp';
}
request({
method: 'get',
path: 'gulp-xtpl/latest'
}, {
registry: 'http://registry.npm.alibaba-inc.com',
configFile: path.join(root, '.tnpmrc')
}, function (err, data) {
if (err) {
return; // ignore
}
if (data.version && pkg.version !== data.version) {
log('Warn'.yellow, 'gulp-xtpl:'.bold,
'latest version', data.version.bold.green, '(for XTemplate@' + data.dependencies.xtemplate.bold + '),',
'local version', pkg.version.bold.yellow, '(for XTemplate@' + version.bold + ').');
log('Warn'.yellow, 'You can execute', 'npm install gulp-xtpl --save-dev'.green, 'for upgrade.');
}
});
}
checkVersion();
var version = XT.version || pkg.dependencies.xtemplate/* no `XT.version` above XTemplate 3.3.3 */ || '0.0.0',
defaultOptions = {
extName: '.xtpl.js',
compileConfig: {
isModule: true
},
header: '/* ! Generated by node module \'gulp-xtpl\'(for XTemplate@{{version}}). The install command is `npm install gulp-xtpl`. */',
pkgCfg: '', // e.g. '!KISSY.Config.packages.kg && KISSY.config({packages:{kg:{base: "//g.tbcdn.cn/kg/",ignorePackageNameInUri:true}}});'
prefix: function (options, file) {
var name = genModName(file);
return 'KISSY.add("' + name + '", ';
},
suffix: function (options, file) {
return ',{requires: ["kg/xtemplate/{{version}}/runtime"]});';
},
before: function (content, options, file) {
return content;
},
after: function (content, options, file) {
return content;
}
};
module.exports = function (options) {
options = merge(defaultOptions, options || {});
return through.obj(function (file, encoding, callback) {
if (file.isNull()) {
return; // ignore
}
if (file.isStream()) {
return this.emit('error', new PluginError('gulp-xtpl', 'Streaming not supported'));
}
var header = options.header,
pkgCfg = options.pkgCfg,
prefix = options.prefix,
suffix = options.suffix,
before = options.before,
after = options.after;
// to fix variables' value.
header = substitute(header ? header + '\n' : '', {version: version});
pkgCfg = substitute(pkgCfg ? pkgCfg + '\n' : '', {version: version});
prefix = substitute(isFunction(prefix) ? prefix(options, file) : prefix || '', {version: version});
suffix = substitute(isFunction(suffix) ? suffix(options, file) : suffix || '', {version: version});
try {
log('Info'.green, 'Your XTemplate files are', 'compiled by'.bold,
'XTemplate'.bold.cyan, version.bold.cyan, '!');
var content = String(file.contents);
content = isFunction(before) && before(content, options, file) || '';
// strips dependent assets and templates resources(TMall femodule).
content = content.replace(/\{\{\s*(require|use)\s*\(.*?\)\s*\}\}/g, '');
content = XT.Compiler.compileToStr(merge(options.compileConfig || {}, {
name: genModName(file),
functionName: '_',
content: content
})) || '';
content = header + pkgCfg + prefix + wrapper(content) + suffix;
file.path = file.path.replace(/\.\w+$/, options.extName || '.xtpl.js');
content = isFunction(after) && after(content, options, file) || '';
file.contents = new Buffer(content);
this.push(file);
} catch (e) {
return this.emit('error', new PluginError('gulp-xtpl', e.message));
}
callback();
});
};