UNPKG

lite

Version:

A cross platform template engine base on xml/html and javascript expression.

168 lines (160 loc) 5.07 kB
var configRootKey = '-lite-engine-child-process-root'; var pathModule = require('path'); var fs = require('fs'); exports.build = buildCompiler tryInitProcess(); function tryInitProcess(){ //node path -root root -filter path#name var argv = process.argv; var index = argv.indexOf(configRootKey); if(index<0){ return; } //var isChild = argv[2]==configRootKey;//child-process-compiler //{path:tplPath,action:'remove'} var root = argv[index+1].replace(/\/?$/,'/'); if(argv[index+2] == '-configurator' && argv[index+3]){ var configurator = argv[index+3]; } //console.log('ischild:',root); var compile = setupCompiler(root,function(cmd){ //console.log('compile:',cmd) process.send(cmd) },configurator); process.on('message', function(path){ compile(path); }); } /** * @param engine * @param configurator: modulename#configuratorMethod(compiler) */ function buildCompiler(engine,onAction,configurator){ var root = engine.root; try{//try build compiler on new thread! if(configurator instanceof Function){ throw new Error();//function can config can not post to sub process!! } throw new Error(); var args = [configRootKey,root] if(configurator){ args.push('-configurator',configurator); } var compiler = require('child_process').fork(__dirname + '/process.js',args); compiler.on('message',onAction); return compiler; }catch(e){ var setupCompiler = require('./process.js').setupCompiler; var sender = setupCompiler(root,onAction,configurator); return { send:sender } } } function setupCompiler(root,callback,configurator){ var LiteCompiler = require('./compiler').LiteCompiler; var templateCompiler= new LiteCompiler(root); /** * { * templatepath : { * resource1:true, * resource2:true * } * } */ var templateResourcesMap = { } /** * 允许脏数据,发现脏数据要通过templateMap重新确定 * { resourcePath -> {template1:watcher,template2:watcher} } */ var resourceWatcherMap = {} function addTemplateWatch(path,resources){ var templateInfo = templateResourcesMap[path]={}; //console.log('resource:',resources) for(var i = 0;i<resources.length;i++){ var resPath = resources[i]; templateInfo[resPath]=true; addResourceWatch(resPath,path); //tplWatcherMap[path] = true; } } function addResourceWatch(resourcePath,tplPath){ if(resourcePath.match(/[\\\/]$/)){//ignore dir return; } var file = pathModule.join(root,resourcePath); var options = { persistent: true, recursive: false }; var tplWatcherMap= resourceWatcherMap[resourcePath] || (resourceWatcherMap[resourcePath] = {}); var oldWatcher = tplWatcherMap[tplPath] if(oldWatcher){ oldWatcher.close(); } //console.log('add watcher:',file,tplPath) tplWatcherMap[tplPath] = fs.watch(file, options,function (event, filename) { //console.log('event is: ' + event,filename,tplPath,resourcePath); callback({path:tplPath,action:'remove'}) /* var tplWatcherMap = resourceWatcherMap[resourcePath]; for(var tplPath in tplWatcherMap){ var tpl = templateResourcesMap[tplPath]; if(tpl && tpl[resourcePath]){ delete templateResourcesMap[tplPath]; //console.debug('remove tpl evet:' ,tplPath); callback({path:tplPath,action:'remove'}) //process.send({path:tplPath,action:'remove'}) } } */ }); } templateCompiler.waitPromise = true if(configurator){ //console.log('filter:',configurator) try{ if('string' == typeof configurator ){ var args = configurator.split('#'); var path = args[0]; var name = args[1]; var configurator = require(path)[name]; configurator(templateCompiler) }else if(configurator instanceof Function){ configurator(templateCompiler) } }catch(e){ console.error('filter init error:'+e); } } //process.on('message', function(path) { return (function(path){ var tplFile = pathModule.join(root,path); try{ if(fs.existsSync(tplFile)){ var tplExist = true; var result = templateCompiler.compile(path); addTemplateWatch(path,result.resources); }else{ addTemplateWatch(path,[tplFile.replace(/[^\\\/]+$/,'')]); throw new Error("\nFile Not Found:"+path); } var message = { path:path, action:'update', code:result.code, config:result.config}; //process.send({path:path,action:'add',code:result.code,config:result.config,prefix:result[3]}) }catch(e){ console.error(e) var error = [path+" compile error",e.message,e.stack].join('\n'); var jscode = 'function(c,out){out.push("<pre>",'+JSON.stringify(error)+',"</pre>");return out.join()}' var message = { path:path, action:'error', code:jscode, config:{statusCode:'500',contentType:'text/html;encoding=utf-8'} } } callback(message) }); } exports.setupCompiler = setupCompiler;