gulp-steel-amd-concat
Version:
174 lines (155 loc) • 5.8 kB
JavaScript
/**
* steel amd concat
* @author Finrila finrila@gmail.com
*/
;
var through = require('through2');
var gutil = require('gulp-util');
var extend = require('util')._extend;
var path = require('path');
var fs = require('fs');
module.exports = function(options) {
var moduleMap = {};
options = extend({
definePrefix: 'steel.d',
excModule: []
}, options);
var excModule = options.excModule;
var definePrefix = options.definePrefix
var moduleBasePath;
return through.obj(bufferContents, endStream);
function bufferContents(file, enc, cb) {
if (file.isNull()) {
cb();
return;
}
if (!moduleBasePath) {
moduleBasePath = file.base.replace(/\\/g, '/');
}
if (file.isStream()) {
this.emit('error', new gutil.PluginError('gulp-steel-amd-concat', 'Streaming not supported'));
cb();
return;
}
var filepath = file.relative.replace(/\\/g, '/');
var src = file.contents.toString('utf8');
var match = src.match(new RegExp(definePrefix + '\\(["\\\'](.*?)[\\\'"]'));
if (match) {
var moduleId = match[1];
moduleMap[moduleId] = {
src: src,
file: file
};
}
cb();
}
function endStream(cb) {
try {
for (var moduleId in moduleMap) {
requireModuleDeps.call(this, moduleId, moduleMap, excModule);
var file = moduleMap[moduleId].file;
var filepath = moduleMap[moduleId].file.path;
var src = moduleMap[moduleId].src;
file.contents = new Buffer(concatModule.call(this, moduleId, moduleMap, excModule));
this.push(file);
}
} catch (e) {
gutil.log(e);
}
cb();
}
function concatModule(moduleId, moduleMap, excModule) {
var deps = requireRegModuleDeps.call(this, moduleId, moduleMap, excModule);
var ret = [];
deps.forEach(function(mid) {
ret.push(moduleMap[mid].src);
});
return ret.join('\n');
}
function requireModuleDeps(moduleId, moduleMap, excModule, dealFilePath) {
var moduleObj = moduleMap[moduleId];
var _this = this;
if (!moduleObj) {
this.emit('error', new gutil.PluginError('gulp-steel-amd-concat', 'moduleId(' + moduleId + ') is not defined! In file (' + dealFilePath + ')'));
return;
}
if (moduleObj.deps) {
return;
}
var deps = [];
var fileFullPath = moduleObj.file.path;
var fileFolderPath = path.dirname(fileFullPath);
var src = moduleObj.src;
removeComment(src).replace(/\brequire\([ \t\n\r]*['"](.*?)['"][ \t\n\r]*\)/g, function(_, moduleId) {
if (/^\./.test(moduleId)) {
moduleId = path.join(fileFolderPath, moduleId).replace(/\\/g, '/').replace(new RegExp('^' + moduleBasePath), '').replace(/^[\\\/]/, '');
moduleId = moduleId.replace(/\.js$/, '');
}
if (excModule.indexOf(moduleId) != -1) {
return;
}
requireModuleDeps.call(_this, moduleId, moduleMap, excModule, fileFullPath);
if (deps.indexOf(moduleId) === -1) {
var _deps = moduleMap[moduleId].deps;
for(var i = 0, l = _deps.length; i < l; ++i) {
if (deps.indexOf(_deps[i]) === -1) {
deps.push(_deps[i]);
}
}
deps.push(moduleId);
}
});
moduleObj.deps = deps;
}
function requireRegModuleDeps(moduleId, moduleMap, excModule) {
var moduleObj = moduleMap[moduleId];
var deps = moduleObj.deps;
var moduleMiddleSrc = [moduleObj.src];
var all = deps.slice();
for(var i = 0, l = deps.length; i < l; ++i) {
moduleMiddleSrc.push(moduleMap[deps[i]].src);
}
moduleMiddleSrc = moduleMiddleSrc.join('\n');
var regList = [];
removeComment(moduleMiddleSrc, {
block: 1
}).replace(/\/\/\/require\([ \t\n\r]*['"](.*?)['"][ \t\n\r]*\)/g, function(_, moduleReg) {
regList.push('(' + moduleReg.replace(/^\^/, '') + ')');
});
var reg = regList.length && new RegExp('^' + regList.join('|'));
if (reg) {
if (reg.test(moduleId)) {
this.emit('error', new gutil.PluginError('gulp-steel-amd-concat', 'reg moduleId(' + moduleId + ') concat error://require("moduleReg") have circular reference->' + reg));
return;
}
for (var _moduleId in moduleMap) {
if (excModule.indexOf(moduleId) == -1 && reg.test(_moduleId)) {
if (all.indexOf(_moduleId) === -1) {
var _deps = moduleMap[_moduleId].deps;
for(var i = 0, l = _deps.length; i < l; ++i) {
if (all.indexOf(_deps[i]) === -1) {
all.push(_deps[i]);
}
}
all.push(_moduleId);
}
}
}
}
all.push(moduleId);
return all;
}
};
function removeComment(src, options) {
options = options || {
line: true,
block: true
};
if (options.line) {
src = src.replace(/(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/gm, '\n');
}
if (options.block) {
src = src.replace(/(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g, '\n');
}
return src;
};