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.js
const __getUrl = (dep) => {
const p = location.pathname;
return p.slice(0, p.lastIndexOf('/')) + '/' + dep + 'js';
}
// normal script
const __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));
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。