成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

seajs源碼解析

YPHP / 1547人閱讀

摘要:最后將執(zhí)行的結(jié)果暴露給對象。腳本事件在腳本執(zhí)行的時候不會立馬觸發(fā)解決辦法是通過腳本的來判斷總結(jié)以上就是對的一個大致的分析,如有錯誤,歡迎指出。

Seajs是一款模塊化開發(fā)框架,遵循CMD規(guī)范。雖然到現(xiàn)在為止很多模塊打包工具比它更加的完善,但還是有必要拜讀一下的,畢竟為前端模塊化的發(fā)展做了很大的貢獻,分析一下漲漲姿勢。
文章主要從以下幾個方面來分析。有不對的地方,歡迎大家指出。

1、什么是CMD規(guī)范

CMD(Common Module Definition)是seajs在推廣中規(guī)范出來的。詳情請看 CMD模塊定義規(guī)范

2、模塊化開發(fā)的好處

2.1、提高代碼可維護性

2.2、按需加載

2.3、避免變量污染

2.4、為前端工程化發(fā)展打下基礎(chǔ)

3、seajs是如何加載模塊,如何設(shè)計api的

先在瀏覽器控制臺中打印下seajs這個全局變量,可以看到它掛載的一些對象和方法。讓我們先對它有個整體的感受

seajs 從use函數(shù)開始,到加載module的過程大致如下:

模塊加載完后瀏覽器會立馬執(zhí)行define函數(shù),這個函數(shù)比較有意思,先看源代碼

// Resolve id to uri
Module.resolve = function(id, refUri) {
  // Emit `resolve` event for plugins such as text plugin
  var emitData = { id: id, refUri: refUri }
  emit("resolve", emitData)

  return emitData.uri || seajs.resolve(emitData.id, refUri)
}

// Define a module
Module.define = function (id, deps, factory) {
  var argsLen = arguments.length

  // define(factory)
  if (argsLen === 1) {
    factory = id
    id = undefined
  }
  else if (argsLen === 2) {
    factory = deps

    // define(deps, factory)
    if (isArray(id)) {
      deps = id
      id = undefined
    }
    // define(id, factory)
    else {
      deps = undefined
    }
  }

  // Parse dependencies according to the module factory code
  if (!isArray(deps) && isFunction(factory)) {
    deps = parseDependencies(factory.toString())
  }

  var meta = {
    id: id,
    uri: Module.resolve(id),
    deps: deps,
    factory: factory
  }

  // Try to derive uri in IE6-9 for anonymous modules
  if (!meta.uri && doc.attachEvent) {
    var script = getCurrentScript()

    if (script) {
      meta.uri = script.src
    }

    // NOTE: If the id-deriving methods above is failed, then falls back
    // to use onload event to get the uri
  }

  // Emit `define` event, used in nocache plugin, seajs node version etc
  emit("define", meta)

  meta.uri ? Module.save(meta.uri, meta) :
      // Save information for "saving" work in the script onload event
      anonymousMeta = meta
}

有意思的是如果factory是個函數(shù),同時deps不是一個數(shù)組,那么會將factory序列化,然后通過正則匹配從其中解析出依賴

var REQUIRE_RE = /"(?:"|[^"])*"|"(?:"|[^"])*"|/*[Ss]*?*/|/(?:/|[^/
])+/(?=[^/])|//.*|.s*require|(?:^|[^$])requires*(s*([""])(.+?)1s*)/g
var SLASH_RE = //g

function parseDependencies(code) {
  var ret = []

  code.replace(SLASH_RE, "")
      .replace(REQUIRE_RE, function(m, m1, m2) {
        if (m2) {
          ret.push(m2)
        }
      })

  return ret
}

解析依賴后會扔到模塊緩存系統(tǒng)中。之前模塊加載的時候就可以看到,主模塊加載完之后會執(zhí)行factory函數(shù)。在執(zhí)行factory函數(shù)的時候,會執(zhí)行require加載的依賴。而require函數(shù)會判斷模塊狀態(tài)是否已經(jīng)執(zhí)行過了,如果不是那么就加載依賴,加載完后執(zhí)行依賴。最后將執(zhí)行的結(jié)果暴露給exports對象。
到此,seajs的整個加載執(zhí)行過程已經(jīng)分析完畢。相比requirejs,seajs代碼不是很多,但是能夠感受到代碼組織起來的精妙之處。

4、seajs是如何解決模塊互相依賴問題

seajs解決模塊的互相依賴是通過緩存系統(tǒng)和模塊的狀態(tài)來實現(xiàn)的。

5、seajs如何解決瀏覽器兼容性問題

5.1、onload 事件在 webkit<535.23和firfox<9.0中不支持

// `onload` event is not supported in WebKit < 535.23 and Firefox < 9.0
// ref:
//  - https://bugs.webkit.org/show_activity.cgi?id=38995
//  - https://bugzilla.mozilla.org/show_bug.cgi?id=185236
//  - https://developer.mozilla.org/en/HTML/Element/link#Stylesheet_load_events
var isOldWebKit = +navigator.userAgent
    .replace(/.*(?:AppleWebKit|AndroidWebKit)/(d+).*/, "$1") < 536

解決的辦法是通過一個定時器,去監(jiān)聽link節(jié)點是否已經(jīng)加載,并且解析完。

5.2、腳本onload事件在腳本執(zhí)行的時候不會立馬觸發(fā)

function getCurrentScript() {
  if (currentlyAddingScript) {
    return currentlyAddingScript
  }

  // For IE6-9 browsers, the script onload event may not fire right
  // after the script is evaluated. Kris Zyp found that it
  // could query the script nodes and the one that is in "interactive"
  // mode indicates the current script
  // ref: http://goo.gl/JHfFW
  if (interactiveScript && interactiveScript.readyState === "interactive") {
    return interactiveScript
  }

  var scripts = head.getElementsByTagName("script")

  for (var i = scripts.length - 1; i >= 0; i--) {
    var script = scripts[i]
    if (script.readyState === "interactive") {
      interactiveScript = script
      return interactiveScript
    }
  }
}

解決辦法是通過腳本的readyState===‘interactive’來判斷

6、總結(jié)

以上就是對seajs的一個大致的分析,如有錯誤,歡迎指出。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/93001.html

相關(guān)文章

  • seajs 源碼解讀

    摘要:本文主要簡單地解讀一下的源碼和模塊化原理。其中,是這次源碼解讀的核心,但我也會順帶介紹一下其他文件的作用的。對代碼比較簡單,其實就是聲明一下全局的命名空間。然而,真正的核心在于處理模塊依賴的問題。 seajs 簡單介紹 seajs是前端應(yīng)用模塊化開發(fā)的一種很好的解決方案。對于多人協(xié)作開發(fā)的、復(fù)雜龐大的前端項目尤其有用。簡單的介紹不多說,大家可以到seajs的官網(wǎng)seajs.org參看...

    LiangJ 評論0 收藏0
  • 閱讀sea.js源碼小結(jié)

    摘要:依賴信息是一個數(shù)組,比如上面的依賴數(shù)組是源碼如下是利用正則解析依賴的一個函數(shù)時間出發(fā)函數(shù)主要看這個部分注釋是防止拷貝該時間的回調(diào)函數(shù),防止修改,困惑了一下。對的賦值需要同步執(zhí)行,不能放在回調(diào)函數(shù)里。 sea.js想解決的問題 惱人的命名沖突 煩瑣的文件依賴 對應(yīng)帶來的好處 Sea.js 帶來的兩大好處: 通過 exports 暴露接口。這意味著不需要命名空間了,更不需要全局變量。...

    chavesgu 評論0 收藏0
  • seajs 模塊源碼解讀

    摘要:這里的依賴都是通過來異步加載的,加載完畢之后立刻執(zhí)行函數(shù),在模塊文件執(zhí)行完畢后包括和其他代碼,觸發(fā)的事件。 入口 seajs.use seajs.use直接調(diào)用Module.use(),Module.use的源碼如下: // Use function is equal to load a anonymous module // ids:模塊標識,uri是dirname + _us...

    e10101 評論0 收藏0
  • seajs入門教程

    摘要:一般也不需要傳入,需要用到的模塊用加載即可。根據(jù)應(yīng)用場景的不同,提供了三個載入模塊的,分別是和。主要用于載入入口模塊。入口模塊相當于語言的函數(shù),同時也是整個模塊依賴樹的根。表示下載文件的最大時長,以毫秒為單位。 本文轉(zhuǎn)自張洋,因為SeaJS更新版本很快,所以原文中很多地方不太適用,在這里發(fā)布一個更新版。 如何使用SeaJS 下載及安裝在這里不贅述了,不了解的請查詢官網(wǎng)。 基本開發(fā)原則 ...

    n7then 評論0 收藏0
  • Seajs源碼解讀

    摘要:如果這個模塊的時候沒有設(shè)置,就表示是個匿名模塊,那怎么才能與之前發(fā)起請求的那個相匹配呢這里就有了一個全局變量,先將元數(shù)據(jù)放入這個對象。模塊加載完畢的回調(diào)保存元數(shù)據(jù)到匿名模塊,為請求的不管是不是匿名模塊,最后都是通過方法,將元數(shù)據(jù)存入到中。 近幾年前端工程化越來越完善,打包工具也已經(jīng)是前端標配了,像seajs這種老古董早已停止維護,而且使用的人估計也幾個了。但這并不能阻止好奇的我,為了了...

    bigdevil_s 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<