掌握模塊化基本概念以及使用模塊化帶來的好處html
當你的網站開發愈來愈複雜的時候,會常常遇到什麼問題?前端
歷史上,JavaScript一直沒有模塊(module)體系, 沒法將一個大程序拆分紅互相依賴的小文件,再用簡單的方法拼裝起來。 其餘語言都有這項功能,好比Ruby的 require
、Python的 import
, 甚至就連CSS都有 @import
, 可是JavaScript任何這方面的支持都沒有,這對開發大型的、複雜的項目造成了巨大障礙。jquery
如何解決不經過 script 標籤就能加載 JavaScript 文件代碼。git
什麼是模塊化github
使用模塊化開發的方式帶來的好處面試
眼見他起高樓,眼見他宴賓客,眼見他樓塌了。ajax
體驗刀耕火種的模塊化解決方式npm
之後若是不使用第三方規範的狀況下, 若是寫模塊能夠採用下面這種方式編程
```js ; (function (形參模塊名, 依賴項, 依賴項) { // 經過 形參模塊名 修改模塊數組
window.模塊名 = 形參模塊名 })(window.模塊名 || {}, 依賴項, 依賴項) ```
下面是一個關於模塊化的面試題,一塊兒觀察和分析這段代碼的做用:
js var UTIL = (function (parent, $) { // 動態的給一個不存在的對象掛載一個子對象 var my = parent.ajax = parent.ajax || {} my.get = function (url, params, callback) { return $.getJSON(url, params, callback) } return parent }(UTIL || {}, jQuery))
天然界生態系統、計算機操做系統、軟件辦公系統,還有教育系統、金融系統、網絡系統、 理論系統等等。究竟什麼是系統呢?
維基百科:系統泛指由一羣有關連的個體組成,根據預先編排好的規則工做, 能完成個別元件不能單獨完成的工做的羣體。 系統分爲天然系統與人爲系統兩大類。
簡單來講,系統有兩個基本特性:
系統之間的個體能夠成爲系統成員,要構建一個系統,最基本的層面須要作兩件事:
Sea.js 是一個適用於 Web 瀏覽器端的模塊加載器。 在 Sea.js 裏,一切皆是模塊,全部模塊協同構建成模塊系統。 Sea.js 首要要解決的是模塊系統的基本問題:
在前端開發領域,一個模塊,能夠是JS 模塊,也能夠是 CSS 模塊,或是 Template 等模塊。 而 Sea.js 則專一於 JS 文件模塊:
把上面兩點中說起的基本書寫格式和基本交互規則描述清楚,就能構建出一個模塊系統。 對書寫格式和交互規則的詳細描述,就是模塊定義規範(Module Definition Specification)。
好比 CommonJS 社區的 Modules 1.1.1
規範, 以及 NodeJS 的 Modules
規範, 還有 RequireJS 提出的 AMD
規範等等。
Sea.js 遵循的是 CMD 規範。
CMD、AMD、CommonJS 都是社區制定出來的模塊規範, 他們的目的都是爲了解決 JavaScript 沒有模塊化系統的問題。 他們都有如何定模塊成員,以及模塊成員之間如何進行通訊交互的規則。
AngularJS Module 也是 ng 框架自己提供的一個模塊系統解決方案。 ng定義模塊須要起名,即使你去加載或者依賴一個模塊的時候, 這個被依賴的模塊也須要經過 script 標籤引入到 html 頁面中。
2015 年 9 月份,ECMAScript 官方推出了 ECMAScript 6 語言標準。 在最新的 ES6 語言規範標準中,已經制定了 JavaScript 模塊化規範。
export import
前端界的風氣:都喜歡追趕新技術,甚至把沒有推出來的標準直接幹到了生產環境。
這個社區太浮躁了。
A Module Loader for the Web, Enjoy the fun of programming.
關於 SeaJS
爲何學習和使用 SeaJS ?
誰在用?
SeaJS 適用場景
bower install seajs
npm install seajs
define
函數定義模塊require
函數加載模塊module.exports
對外暴露接口對象seajs.use
函數啓動模塊系統seajs.use
加載模塊,啓動模塊系統。
seajs.use('id')
seajs.use('id', callback)
加載多個模塊,加載完成時,執行回調 seajs.use(['id1','id2',...],callback)
注意:
DOM ready
事件沒有任何關係。若是某些操做要確保在 DOM ready
後執行,須要使用 jquery 等類庫來保證define
中的模塊代碼裏define(factory)
define
是一個全局函數,用來定義模塊。
define
接受 factory
參數,factory
能夠是一個函數,也能夠是一個對象或字符串。
factory
爲對象、字符串時,表示模塊的接口就是該對象、字符串。
factory 是一個對象時
define({})
factory 是一個字符串時
define('hello')
factory 是一個函數時
define(function(require, exports, module){})
require
require 用來加載一個 js 文件模塊, require 用來獲取指定模塊的接口對象 module.exports
。
require 在加載和執行的時候,js 會按照同步的方式和執行。
使用注意:
必須
命名爲 requireTips: 把 require
看作是語法關鍵字就好啦
模塊標識是一個字符串,用來標識模塊。
模塊標識能夠不包含文件後綴名,好比 .js
模塊標識能夠是 相對 或 頂級 標識
相對標識
相對標識以 .
開頭,永遠相對於當前模塊所處的路徑來解析。
頂級標識不以 .
或 /
開始,會相對模塊系統的基礎路徑(base路徑,默認是 sea.js 文件所屬的路徑)。 能夠手動配置 base 路徑。
js seajs.config({ base: './js' })
除了相對和頂級標識以外的標識都是普通路徑。 普通路徑的解析規則,會相對當前頁面解析。
```js // 假設當前頁面是 http://example.com/path/to/page/index.html
// 絕對路徑是普通路徑: require.resolve('http://cdn.com/js/a'); // => http://cdn.com/js/a.js
// 根路徑是普通路徑: require.resolve('/js/b'); // => http://example.com/js/b.js
// use 中的相對路徑始終是普通路徑: seajs.use('./c'); // => 加載的是 http://example.com/path/to/page/c.js
seajs.use('../d'); // => 加載的是 http://example.com/path/to/d.js ```
Tips:
base
基礎路徑解析。
seajs.config({ base: '基礎路徑' })
來配置基礎路徑seajs.use
中的相對路徑始終相對當前頁面來解析。module 是一個對象,上面存儲了與當前模塊相關聯的一些屬性和方法。
module.id
define
方法的第一個參數來指定,默認爲該模塊文件的絕對路徑module.uri
module.dependencies
module.exports
return module.exports
exports 僅僅是 module.exports 的一個引用。 也就是說修改了 exports 就至關於修改了 module.exports。
可是一旦在 factory 內部給 exports 從新賦值,並不會改變 module.exports 的值。 所以給 exports 賦值是無效的。
module.exports
module.exports
或給它賦值改變模塊接口對象exports
是 module.exports
的一個引用,就比如在每個模塊定義最開始的地方寫了這麼一句代碼:var exports = module.exports
關於這倆哥們兒的區別請分析一下代碼:
```js var module = { exports: {} }
function changeExports (exports, module) { // var exports = module.exports exports.foo = 'bar'
// 這裏賦值拿不到,不要使用使用 // exports = function () {} return module.exports }
changeExports(module.exports, module) ```
那爲啥要有 exports
?
爲了開發體驗,API更友好,使用 exports 的時候,能夠少寫一個點兒。
若是你實在分不清楚 exports
和 module.exports
之間的區別,就只記得 module.exports
就能夠了。