UNPKG

gulp-nui-concat

Version:
210 lines (183 loc) 6.04 kB
'use strict'; var through = require('through2'); var path = require('path'); var fs = require('fs'); var replacePath = function(path){ // a\b\c => a/b/c path = path.replace(/\\/g, '/'); // a///b///c => a/b/c path = path.replace(/([^:])\/{2,}/g, '$1/'); // a/b...../c => a/b../c path = path.replace(/\.{2,}/g, '..'); // a/b../c => a/c // a/../c => c var replace = function(str){ if(/([\w]+\/?)(\.\.\/)/g.test(str)){ str = str.replace(/([\w]+\/?)(\.\.\/)/g, function(a, b, c){ if(a == b+c){ return '' } return a }) return replace(str) } return str } path = replace(path); // a/b./c => a/b/c // a/./c => a/c return path.replace(/([\w]+)\/?(\.\/)+/g, '$1/') } var isEmptyObject = function(obj){ var name; for(name in obj){ return false; } return true; } var inArray = function(str, arr){ var len = arr.length; var i=0; for(i; i<len; i++){ if(arr[i] == str){ return true } } return false } var unique = function(arr){ var newarr = []; var temp = {}; arr.forEach(function(val, i){ if(!temp[val]){ temp[val] = true newarr.push(val) } }) return newarr } module.exports = function(options){ options = options || {}; //模块别名,值一定要用绝对路径 options.alias = options.alias || {}; //忽略的模块名,模块不会追加到合并的文件中 options.ignore = options.ignore || []; return through.obj(function(file, enc, cb){ if(file.isNull()){ return cb(); } var dirname = path.dirname(file.path)+'/'; var content = file.contents.toString(); var matchs = content.match(/Nui.load\(['"][^'"]+['"]/g); var cacheModules = {}; if(!matchs){ return cb(); } function Module(id, name, deps){ var mod = this; mod.id = id; mod.name = name; mod.deps = deps; mod.depmodules = {}; mod.uri = mod.id.substr(0, mod.id.lastIndexOf('/')+1); } Module.prototype.load = function(){ var mod = this; if(!/_module_\d+/.test(mod.name)){ mod.url = mod.id + '.js'; try{ var buffer = fs.readFileSync(mod.url); mod.content = buffer.toString(); mod.content = mod.content.replace(/Nui.define\((['"][^'"]+['"]\s*,)?/, "Nui.define('"+ mod.name +"',"); mod.deps = mod.getdeps() } catch(e){} } return mod.resolve() } Module.prototype.getdeps = function(){ var mod = this; var content = mod.content; var deps = []; var depsMatchs = content.match(/Nui.define\((['"][^'"]+['"]\s*,)?\s*\[([^\[\]]+)\]/); var requireMatchs = content.match(/require\(['"][^'"]+['"]\)/g); if(depsMatchs){ var match = depsMatchs[2].split(','); match.forEach(function(val, i){ val = val.replace(/^\s+|\s+/g, '').replace(/['"]/g, ''); if(!inArray(val, options.ignore)){ deps.push(val) } }) } if(requireMatchs){ requireMatchs.forEach(function(val, i){ val = val.replace(/(require)|[\(\)'"]/g, ''); if(!inArray(val, options.ignore)){ deps.push(val) } }) } return deps } Module.prototype.resolve = function(){ var mod = this; if(isEmptyObject(mod.depmodules)){ mod.deps.forEach(function(val, i){ var module = Module.getModule(val, [], mod.uri); mod.depmodules[val] = module.load() }) } return mod } Module.prototype.getContents = function(contents){ var mod = this; if(!contents){ contents = []; } if(mod.content){ contents.unshift(mod.content) } if(mod.deps.length){ for(var i in mod.depmodules){ contents = mod.depmodules[i].getContents(contents) } } return contents } Module.setId = function(id, uri){ var name = id.replace(/(\.js)?(\?[\s\S]*)?$/g, ''); id = uri + name; if(options.alias[name]){ id = options.alias[name].replace(/(\.js)?(\?[\s\S]*)?$/g, ''); } return [replacePath(id), name] } Module.getModule = function(id, deps, uri){ var arr = Module.setId(id, uri); id = arr[0]; return cacheModules[id] || (cacheModules[id] = new Module(id, arr[1], deps)) } Module.id = 0; Module.load = function(id, callback){ var mod = Module.getModule('_module_'+Module.id++, [id], dirname); callback(mod.load()) } matchs.forEach(function(val, i){ var id = matchs[i].replace(/Nui.load\(/, '').replace(/['"]/g, '').replace(/-debug|-min/g, ''); Module.load(id, function(mod){ var contents = unique(mod.getContents()).join('\r\n'); var url; for(var i in mod.depmodules){ url = mod.depmodules[i].url; break; } if(url){ url = url.replace(/(\.js)$/, '-debug$1'); fs.writeFile(url, contents) } }) }) cb(); }) }