UNPKG

v-kitty

Version:

hello kitty

347 lines (311 loc) 10.6 kB
var path = require('path'); var util = require('util'); var strip = require('strip-comments'); var fs = require('fs'); var fse = require('fs-extra'); var Loader = require('./loader.js'); var ParseFile = require('./parseFile.js'); var gulpWatch = require('gulp-watch'); var moment = require('moment'); var nowTime = function (format) { return moment().format(format || "HH:mm:ss"); }; global.config = { cache: true,//是否开启缓存,默认开启,加速编译 watch: false,//开启监听模式 tag: '_include',//引入tag baseDir: __dirname.replace(/\/node_modules.*$/, ''),//项目根目录 cdnUrl: "",//cdn地址路径 resourceDir: "./build/static",//资源文件存放地址,必须有cdn调用才能生效 buildDir: "./build",//资源文件存放地址,必须有cdn调用才能生效 varTag: { open: '@@',//变量开始符 close: "@@"//变量结束符 } }; global.bufferFiles = {}; var Build = { init: function (file, content) { var destfile = path.resolve(config.baseDir,config.buildDir,file.replace(config.baseDir,'.')); ParseFile.beforeCompile = Loader.beforeCompile; this._reset(); this._build(file,content,destfile); this._setIsActive(); return content; }, _createBind:function(bufferFile){ //更新compile bufferFile.bindings.change = function(content){ var file = bufferFile.file; Object.keys(bufferFiles).forEach(function(key){ var bufferFile = bufferFiles[key]; var check=false; bufferFile.depends.forEach(function(depend){ if(depend.file === file){ Build._compileLoaders(bufferFile,depend,content); check=true; } }); if(check){ bufferFile._compileDep(); } }); }; //更新content bufferFile.bindings.update = function(){ Build._buildBack(); Build._setIsActive(); }; //删除文件 bufferFile.bindings.del = function(){ //判断有没有依赖 var result = []; Object.keys(bufferFiles).forEach(function(key){ var buffer = bufferFiles[key]; buffer.depends.forEach(function(depend){ if(depend.file===bufferFile.file){ result.push(buffer.file); } }) }); if(result.length){ throw 'Error source(05): '+result.join('\nError source: '); } //删除changes bufferFiles[bufferFile.file].depends.forEach(function(depend){ if(depend.file){ var changeSubs = bufferFiles[depend.file].bindings.changeSubs; delete changeSubs[bufferFile.file]; } }); delete bufferFiles[bufferFile.file]; }; }, /** * 开始构建 * @param file * @param content * @returns {*} * @private */ _build: function (file, content,destfile) { try{ new ParseFile({file: file, content: content,destfile:destfile}); Build._buildBack(); }catch (err){ console.log('Error source(04): '+file); console.log(err); process.exit(); } return content; }, /** * 构建回调 * @private */ _buildBack:function(){ Object.keys(bufferFiles).forEach(function (key) { var bufferFile = bufferFiles[key]; //isnew判断是不是已经监听 if(bufferFile.isNew){ Build._observe(bufferFile); Build._createBind(bufferFile); Build._compile(bufferFile); Build._watch(bufferFile); bufferFile.isNew = false; }else{ Build._compile(bufferFile); } }); }, /** * 充值构建文件 * @private */ _reset:function(){ //fse.removeSync(config.buildDir); //fse.removeSync(config.resourceDir); this._reset =function(){}; }, /** * compile * @private */ _compile: function (bufferFile) { var self = this; var timeout; bufferFile._compileDep = function () { clearTimeout(timeout); timeout = setTimeout(function () { var result = ''; bufferFile.depends.forEach(function (dep) { result += dep.content; }); bufferFile.compile = Loader.afterCompile(result,bufferFile); self._createCompileFile(bufferFile); }) }; }, /** * loaders compile * @private */ _compileLoaders:function(bufferFile,depend,newValue){ var compileContent = newValue; //loaders处理 depend.loaders.forEach(function(key){ try { compileContent = Loader[key](compileContent,bufferFiles[depend.file],depend); }catch (err){ console.log('Error source(03): '+bufferFile.file); console.log('Error on execute loader.'+key); throw err; } }); if(depend.options){ compileContent = Build._handleOptions(compileContent,depend.options); } //如果是js文件,引入后要使用单引号引入,但是require需要除外 if(bufferFile.type==='js' && depend.loaders.indexOf('_require')===-1){ compileContent = compileContent.replace(/\n\/\/.*?\n/g, '').replace(/\n/g, '').replace(/'/g, "\\'").replace(/\//g,'\\/'); compileContent = "'" + compileContent + "'"; } depend.content = compileContent; }, /** * 生成所需要的文件 * @param bufferFile * @private */ _createCompileFile:function(bufferFile){ var destfile = bufferFile.destfile; if(destfile){ fse.ensureFileSync(destfile); fs.writeFile(destfile,bufferFile.compile); console.log(nowTime() + ' compiled '+bufferFile.file); } }, _handleOptions: function(content,options){ var openTag = config.varTag.open; var closeTag = config.varTag.close; var regexp = new RegExp(openTag + '(.+?)' + closeTag, 'g'); content = content.replace(regexp, function () { var key = arguments[1] || ''; var val = options; key.split('.').forEach(function (k) { val = val[k]; }); return val || ''; }); return content; }, /** * 设置末尾isactive有效 * @private */ _setIsActive: function () { var self = this; clearTimeout(this._setIsActiveTimeout); this._setIsActiveTimeout = setTimeout(function(){ console.log('compiling'); var len = Object.keys(bufferFiles).length; Object.keys(bufferFiles).forEach(function(key){ var bufferFile = bufferFiles[key]; if(bufferFile.isActive){ bufferFile.depends.forEach(function(dep){ //如果修改的是中间文件,此时dep.content为空 //!bufferFiles[dep.file].isActive 是在反推的时候就可以编译 如果这里编译会变成多此一举 if(!dep.content && dep.file && !bufferFiles[dep.file].isActive){ Build._compileLoaders(bufferFile,dep,bufferFiles[dep.file].compile); } if(dep.file && bufferFiles[dep.file].isActive){ setTimeout(function(){ bufferFile.isActive=false; }) } }) } len--; if(len===0){ setTimeout(function(){ self._doIsActive(); }) } }) },22); }, /** * active 操作 * @private */ _doIsActive: function () { var self = this; Object.keys(bufferFiles).forEach(function (key) { var bufferFile = bufferFiles[key]; if (bufferFile.isActive) { var result = '',hasDepFile=false; bufferFile.depends.forEach(function (dep) { result += dep.content; }); bufferFile.compile = result; bufferFile.isActive=false; self._createCompileFile(bufferFile); } }) }, /** * 监听bufferfiles文件 * @private */ _watch: function (bufferFile) { if(!config.watch){ return; } var file = bufferFile.file; bufferFiles[file]._watch=gulpWatch(file, function (vinyl) { var event = vinyl.event; if (event === 'unlink') { bufferFiles[file]._watch.close(); bufferFiles[file].emitter.emit('del'); } else if(event==='change') { var content = vinyl.contents.toString(); content = Loader.beforeCompile(content); bufferFiles[file].emitter.emit('update',content); } }); }, /** * 观察compile * @param data * @private */ _observe: function (data) { var oldValue = data.compile; Object.defineProperty(data, 'compile', { get: function () { return oldValue; }, set: function (newValue) { //不能使用oldvalue===newvalue进行判断 因为编译后字符串很大可能相同 //if (oldValue === newValue) { // return; //} oldValue = newValue; data.emitter.emit('change',newValue); } }); } }; var include = function (file, content) { if(!bufferFiles[file]){ try{ Build.init(file, content); }catch (err){ throw err; } } return content; }; include.config = config; include.loader = Loader; module.exports = include;