UNPKG

s94-require

Version:

可以在浏览器中直接使用CommonJS的模块,书写语法和nodejs一样

212 lines (210 loc) 7.99 kB
(function( window, factory) { "use strict"; if (typeof require === "function" && typeof module === "object" && typeof module.exports === "object"){ module.exports = factory(window, true); } else { factory(window); } })(typeof window !== "undefined" ? window : this, function(window, isRequire){ "use strict"; if(isRequire) return require; var _s94={}; _s94.__stack = function(index){ try{''.join();}catch(err){ var stack = err.stack.split('\n'); if(stack[0].indexOf('.join is not a function')!=-1) stack.shift(); var flc = /((?:https?|file)\:\/\/[^\040]+):(\d+):(\d+)/; if(typeof index == 'undefined'){ for (var i = 0,res=[]; i < stack.length; i++) { var m = stack[i].match(flc); if(!m) continue; res.push({'file': m[1], 'line': m[2], 'column': m[3]}) } return res; }else{ var m = stack[index].match(flc); return m ? {'file': m[1], 'line': m[2], 'column': m[3]} : {}; } } }; _s94.dirname = function(path){ var mt = path.toString().match(/^([\s\S.]+)[\/\\][^\/\\]+[\/\\]?$/); return mt ? mt[1] : ''; }; _s94.url = function(str, base){ var base = /^(http|file)/.test(base) ? base : window.location.href; return new window['URL'](str, base); } _s94.encode = function(data){ var strmap = '0123456789abcdefghijklmnopqrstuvwxyz'; var cache = strmap; var res=''; function encode(str){ var res=''; for (var i = 0; i < str.length; i++) { res += str.charCodeAt(i).toString(36); } return res; } function char_code(char, i){ return strmap.indexOf(char[i]) } var str = encode(data); for (var i = 0,j=0; i < str.length; i++) { j = i%36; if(j==0) { res = cache;cache = ''; } var v = (char_code(str,i) + char_code(res, j)) % 36; cache += strmap[v]; } return cache + res.substring(cache.length); } _s94.cache = function(name, value, timeout){ if(typeof(value) == 'undefined'){ var cache_name = 's94_cache-'+_s94.encode(name); try { var data = JSON.parse(window.sessionStorage.getItem(cache_name)); if(!data) return undefined; return data['main']; } catch (error) { return undefined; } }else{ var cache_name = 's94_cache-'+_s94.encode(name); var data = JSON.stringify({main: value, name:name}); window.sessionStorage.setItem(cache_name, data); } } _s94.cache.remove = function(name){ var cache_name = 's94_cache-'+_s94.encode(name); window.sessionStorage.removeItem(cache_name); } _s94.getFile = function(setup){ setup.async = false; var cacheData,cacheRes; if(setup.cache && typeof(cacheData = _s94.cache(setup.url))!='undefined'){ try { //缓存获取的数据不可信,需要谨慎运行,防止报错后中断正常请求 cacheRes = typeof(setup.success)=="function" ? setup.success.call(setup, cacheData) : undefined; setup.async = true; //执行缓存后,强制使用异步,避免阻断 } catch (error) { _s94.cache.remove(setup.url); cacheData = undefined; } } function iseq(a, b){ if(a==b) return true; try { if(typeof(a)!='string') a = JSON.stringify(a); if(typeof(b)!='string') b = JSON.stringify(b); return a==b; } catch (error) { return false } } var xhr = new XMLHttpRequest(); xhr.open('get', setup.url, setup.async); var ac = function(xhr){ if(xhr && xhr.readyState == 4) { if (xhr.status == 200) { var resType = xhr.getResponseHeader('Content-Type'); var data = resType && resType.indexOf('/json')>0 ? JSON.parse(xhr.responseText) : xhr.responseText; cacheData = _s94.cache(setup.url); if(!iseq(cacheData, data)){ _s94.cache(setup.url, data); if(typeof(cacheData)=='undefined') setup.success(data); } }else{ setup.error(); } } }; xhr.onreadystatechange = function(){ac(xhr)}; xhr.send(); } function s94_require(engine){ function Module(id, parent, loaded){ this.id = id; this.exports = {}; this.parent = (parent instanceof Module) ? parent : null; this.filename = id; this.loaded = !!loaded; } function _require(name, executeFile){ if(_require.cache[name] instanceof Module) return _require.cache[name].exports; executeFile = typeof(executeFile)=='string' && /^(http|file)/.test(executeFile) ? executeFile : engine.__stack(2)['file']; var _url, paths = [], path_index=0; function _load(){ _url = paths[path_index] if(!_url || _require.cache[_url] instanceof Module) return; engine.getFile({ url: _url, global: false,async: false,cache: true,refresh: false, success: function(txt){ if(/package\.json$/.test(_url)){ if(!txt['main']) return path_index++,_load(); paths[path_index] = engine.url(txt['main'], _url).href; _load(); }else{ var parent = _require.cache[executeFile] || _require.cache[window.location.href]; _require.cache[_url] = new Module(_url, parent); if(/\.json/.test(_url)){//普通json文件 _require.cache[_url].exports = txt; }else{ var str_url = _url.replace('"','\\"'); txt = `var _r=window.require;var require=function(n){return _r(n,"${str_url}")};require.cache=_r.cache;var module=require.cache["${str_url}"];var exports=module.exports;if(_r.debug)console.log(module.id);\n`+txt; (new Function(txt)).call(window); } _require.cache[_url].loaded = true; } }, error: function(){path_index++;_load()} }); } //解析模板文件路径 var is_file = /\/.+\.(js|cjs|json)$/.test(name); //是否为文件地址 var is_path = /^(\/|\.\/|\.\.\/|http:)/.test(name); //是否为路径 var path = is_path ? engine.url(name, executeFile).href : _require.dir+'/'+name; //没有前导 '/'、'./'、'../' 则在模块目录查找 //[path]、[path].js、[path].json、[path]/package.json、[path]/index.js paths.push(path+'.js'); //4 paths.push(path+'.json'); //5 //从模块目录加载或者以“/”结尾的优先按目录加载,否则优先按文件加载 if(!is_path || /\/$/.test(path)){ paths.unshift(path+'/index.js'); //3 paths.unshift(path+'/package.json'); //2 }else{ paths.push(path+'/package.json'); //6 paths.push(path+'/index.js'); //7 } //模块名称疑似文件的最先按当前名称查找文件,否则最后按当前名称查找文件 if(is_file){ paths.unshift(path); //1 }else{ paths.push(path); //8 } //加载 _load(); if(_require.cache[_url] instanceof Module){ if(name != _url) _require.cache[name] = _require.cache[_url]; return _require.cache[_url].exports; } throw new Error( 'require:模块'+name+'不存在'); } _require.cache = {}; _require.dir = engine.dirname(engine.dirname(engine.filename)); if(!window.require || typeof(window.require.cache)=="undefined"){ _require.cache[window.location.href] = new Module(window.location.href, false, true); Object.defineProperty(window, 'require', { value: _require }); try{window['global'] = window['GLOBAL'] = window;}catch(e){} console.log('自定义require'); } return Module; } _s94.filename = _s94.url(_s94.__stack(1)['file']).href; //自定义require,同时创建root(window.location.href)模块 var Module = s94_require(_s94); //注册当前模块 window.require.cache[_s94.filename] = new Module(_s94.filename, window.require.cache[window.location.href], true); window.require.cache[_s94.filename].exports = window.require; window.require.cache['s94-require'] = window.require.cache[_s94.filename]; })