CMD usage
// sea.js define('a', function(require, exports, module){ console.log('a load'); exports.run = function (){ console.log('a run') } }) define('b', function(require, exports, module){ console.log('b load'); exports.run = function (){ console.log('b run') } }) define('main', function(require, exports, module){ console.log('main run'); var a = require('a'); a.run(); var b = require('b'); b.run(); }) seajs.use('main'); // main run // a load // a run // b load // b run
seajs简略实现
const modules = {};const exports = {};const sj = {}// 获取地址// dep -> a -> a.js -> http:xxx/xx/xx/a.jsconst __getUrl = (dep) => { const p = location.pathname; return p.slice(0, p.lastIndexOf('/')) + '/' + dep + 'js';}// normal scriptconst __load = (url) => { return new Promise((resolve, reject) => { const header = document.getElementsByTagName("header")[0]; const script = document.createElement('script'); script.async = true; script.src = url; script.type = 'text/javascript'; script.onload = resolve; script.onerror = reject; header.appendChild(script); }) }const __getDepsFromFn = (fn) => { let matches = []; // require('a') // (?:require\() -> require( (?:) 非捕捉性分组 // (?:['"]) -> require(' // ([^'"]+) -> a 防止回溯 -> 回溯 状态机 let reg = /(?:require\()(?:['"])([^'"]+)/g let r = null; while((r = reg.exec(fn.toString())) !== null){ reg.lastIndex; matches.push(r[1]) } return matches;}// 依赖呢?// 提取依赖:1. 正则表达式 2. 状态机const define = (id, factory) => { const url = __getUrl(id); const deps = __getDepsFromFn(factory); if(!modules[id]){ modules[id] = {url, id, factory, deps}; }}const __exports = (id) => exports[id] || (exports[id] = {});const __module = this;// 这里才是加载模块中央// 这个写法是promise的 所以在 var a = require('a') 时 须要加 async/await 形式const __require = (id) => { return __load(__getUrl(id)).then(() => { // 加载之后 const {factory, deps} = modules[id]; if(!deps || deps.length == 0){ factory(__require, __exports(id), __module); return __exports(id); } })}sj.use = (mods, callback) => { mods = Array.isArray(mods) ? mods : [mods]; return new Promise((resolve, reject) => { Promise.all(mods.map(mod =>{ return __load(__getUrl(mod)).then(() => { // 加载之后 const {factory} = modules[mod]; factory(__require, __exports(mod), __module); return __exports(mod); }) })).then(resolve, reject); }).then(instance => callback && callback(...instance));}