UNPKG

gulp-xtpl

Version:

Gulp XTpl (XTemplate) for TMall Biz

204 lines (173 loc) 7.76 kB
// ┌────────────────────────────────────────────────────────────────┐ \\ // │ 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. 'use strict'; 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(); }); };