웹 페이지의 구조가 점점 더 복잡해지고 있습니다. 여전히 모든 코드를 이전처럼 하나의 파일에 넣으면 다음과 같은 문제가 발생합니다. 🎜>
var module1 = new Object({ _count : 0, m1 : function (){ //... }, m2 : function (){ //... } });
var module1 = (function(){ var _count = 0; var m1 = function(){ //... }; var m2 = function(){ //... }; return { m1 : m1, m2 : m2 }; })();
function add(a, b){ return a + b; } exports.add = add;
var math = require('math'); math.add(2,3);
require(['math'], function (math) {// require([module], callback); math.add(2, 3); });
define(function (){ // define([module], callback); var add = function (x,y){ return x+y; }; return { add: add }; });
최대한 게으르게!종속 모듈 처리 방식과 AMD의 차이점은
AMD가 미리 실행되고(종속 항목이 앞에 있음), CMD가 지연되어 실행되는 것입니다. 방식(종속성이 근처에 있음).CMD에서 모듈을 정의하는 방법은 다음과 같습니다.
define(function(require, exports, module) { var a = require('./a'); a.doSomething(); var b = require('./b'); b.doSomething(); });
onload를 설정하고 스크립트 태그를 생성할 때 src!실제로는 그렇긴 하지만 전부는 아닙니다! SeaJS 코드(sea-debug.js)부터 살펴보겠습니다. 모듈은 로드 프로세스 중에 다음 상태를 거칠 수 있습니다.
var STATUS = Module.STATUS = { // 1 - The `module.uri` is being fetched FETCHING: 1, // 2 - The meta data has been saved to cachedMods SAVED: 2, // 3 - The `module.dependencies` are being loaded LOADING: 3, // 4 - The module are ready to execute LOADED: 4, // 5 - The module is being executed EXECUTING: 5, // 6 - The `module.exports` is available EXECUTED: 6, // 7 - 404 ERROR: 7 }
개체는 모듈 정보를 유지하기 위해 메모리에서 사용됩니다. Modul
function Module(uri, deps) { this.uri = uri this.dependencies = deps || [] // 依赖模块ID列表 this.deps = {} // 依赖模块Module对象列表 this.status = 0 // 状态 this._entry = [] // 在模块加载完成之后需要调用callback的模块 }
메소드: seajs.use
seajs.use(‘./main’, function(main) {// 依赖及回调方法 main.init(); });
: Module.prototype.load
Module.prototype.load = function() { var mod = this if (mod.status >= STATUS.LOADING) { return } mod.status = STATUS.LOADING var uris = mod.resolve() // 解析依赖模块的URL地址 emit("load", uris) for (var i = 0, len = uris.length; i < len; i++) { mod.deps[mod.dependencies[i]] = Module.get(uris[i])// 从缓存取或创建 } mod.pass(); // 将entry传递给依赖的但还没加载的模块 if (mod._entry.length) {// 本模块加载完成 mod.onload() return } var requestCache = {}; var m; // 加载依赖的模块 for (i = 0; i < len; i++) { m = cachedMods[uris[i]] if (m.status < STATUS.FETCHING) { m.fetch(requestCache) } else if (m.status === STATUS.SAVED) { m.load() } } for (var requestUri in requestCache) { if (requestCache.hasOwnProperty(requestUri)) { requestCache[requestUri]() } } }
배열입니다. 인터넷에서 비교적 이해하기 쉬운 글을 찾을 수 없어서 코드를 보고 추측해봤는데 사실 그 목적만 기억하면 됩니다: _entry
모든 종속 모듈이 로드되면 콜백 함수를 실행하세요!즉,
array_entry는 현재 모듈이 로드된 후 로드될 수 있는 모듈 종속성의 목록을 저장합니다(종속성의 역관계) !예를 들어 모듈 A가 모듈 B, C, D에 종속되는 경우 통과 후 상태는 다음과 같습니다. At 이번에는
의 값이 3인데, 이는 아직 로드되지 않은 종속 모듈이 세 개 있다는 뜻입니다! 그리고 모듈 B가 모듈 E와 F에 의존하는 경우 A도 로드될 때 전달됩니다. remain
을 통해 모듈을 로드할 수 있습니다. :
importScriptsModule.prototype.fetch
sendRequest
메소드를 실행합니다. 결과를 바탕으로. 모든 종속 모듈이 로드된 후
메소드가 실행됩니다:Module.prototype.onload = function() { var mod = this mod.status = STATUS.LOADED for (var i = 0, len = (mod._entry || []).length; i < len; i++) { var entry = mod._entry[i] if (--entry.remain === 0) { entry.callback() } } delete mod._entry }
는 항목에 해당하는 모듈에 종속성 목록 중 하나가 이미 완료되었음을 알리는 것과 같습니다! 그리고 load
은 의존하는 모든 모듈이 로드되었음을 의미합니다! 그러면 이때 콜백 함수가 실행됩니다: error
for (var i = 0, len = uris.length; i < len; i++) { exports[i] = cachedMods[uris[i]].exec(); } if (callback) { callback.apply(global, exports)// 执行回调函数 }
onload
스크립트가 다운로드된 후 모듈 정보를 유지하기 위해 메서드가 즉시 실행됩니다. --entry.remain
entry.remain === 0
은 종속성이 명시적으로 지정되지 않은 경우 사용됩니다.parseDependency는 일반 일치 메서드에서 require() 조각을 사용합니다(종속성 목록을 지정하는 것이 좋습니다).
define
그런 다음
var exports = isFunction(factory) ? factory.call(mod.exports = {}, require, mod.exports, mod) : factory로그인 후 복사然后执行你在seajs.use中定义的
callback
方法:if (callback) { callback.apply(global, exports) }로그인 후 복사当你写的模块代码中require时,每次都会执行factory方法:
function require(id) { var m = mod.deps[id] || Module.get(require.resolve(id)) if (m.status == STATUS.ERROR) { throw new Error('module was broken: ' + m.uri) } return m.exec() }로그인 후 복사到这里核心的逻辑基本上讲完了,补一张状态的转换图:
以后在用的时候就可以解释一些诡异的问题了!
总结
模块化非常好用,因此在ECMAScript 6中也开始支持,但是浏览器支持还是比较堪忧的~~
위 내용은 JavaScript 모듈화 및 SeaJs 소스 코드 분석에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!