<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <!-- 經過標籤加載js是不能作到模塊化的 --> <script src="./js/jquery.min.js"></script> <script src="./js/a.js"></script> <script src="./js/b.js"></script> </body> </html>
Javascript 語言自己是不具有模塊化能力的,須要自已進行封裝來實現模塊的定義以及加載,其實現遵守必定的規範(COMMONJS)html
Nodejs 是運行在服務端的Javascript,它是按着commonjs的規範實現的模塊化前端
通過實踐發現瀏覽器端Javascript按着commonjs的規範實現模塊化時,有很不足之處,此時就有人在commonjs的基礎上從新定了一個規範AMD(Async Module Define),其表明就是require.jsjquery
隨前端開發演變,又有人定義另一個瀏覽器端模塊化的規範CMD(Common Module Define),淘寶的玉伯定義的,其表明是seajs數組
模塊是以文件形式存在的(一個文件對應一個模塊也能夠一個文件對應多個模塊),經過define()方法來定義一個模塊。瀏覽器
define(function () { // 回調函數中即模塊邏輯 var str = 'a'; alert(str); // code.... });
// 經過一個數組來聲明,模塊的依賴 define(['./a'], function (a) { var str = 'b'; // 經過形式參數a來接收a模塊的返回值 // a模塊返回值(對象)包含了方法now a.now(); // a模塊返回值(對象)包含了方法sayHi a.sayHi(a.name); console.log(str); // code.... });
定義模塊時,能夠有返回值,但並非必須,返回數據類型沒有任何約束,一般返回值是對象更有意義。模塊化
define(function () { // 回調函數中即模塊邏輯 var str = 'a'; // console.log(str); // 直接返回字符串 // return str; // 還能夠是一個函數 // return function () { // console.log('如今是' + new Date); // } // 也能夠是一個對象 return { name: '小明', sayHi: function (name) { console.log('你好' + name); }, now: function () { console.log('如今是' + new Date); } } // 返回值能夠是任意類型,對象更有意義 // code.... });
經過 require() 或者 requirejs() 方法來加載一個模塊函數
<!-- 引入requirejs --> <script src="./libs/require.js"></script> <script> // 加載模塊 // 同時加載兩個模塊,執行順序與書寫順序無關 require(['./a', './b']); </script>
<!-- 引入requirejs --> <script src="./libs/require.js"></script> <script> // 加載模塊 // b和c模塊同時依賴了a模塊 // 當加載b和c模塊時,a模塊能夠自動被加載進來 require(['./b', './c']); </script>
<script> require(['./a'], function (a) { console.log(a); a.sayHi(a.name) a.now(); }); </script>
<!-- 使用自定義屬性指定的模塊,稱爲入口文件 --> <!-- 此文件會自動被執行 --> <script src="./libs/require.js" data-main="./index.js"></script>
requirejs加載模塊時,路徑是遵守一些規則的,分紅如下幾種狀況requirejs
<h2>配置requirejs的的路徑</h2> <script src="./libs/require.js" data-main="./main.js"></script> <script> // 相對於當前頁面 // require(['./src/a']); // 假如使用入口文件, // 路徑參照的是入口文件所在的目錄 // require(['./src/src/a']); </script>
// 經過config方法能夠對requirejs進行配置 // 其中經過baseUrl來配置加載路徑 require.config({ baseUrl: './public' });
經過path屬性能夠配置模塊真實路徑(baseUrl + path),這樣配置後能夠使得路徑調整變的靈活。ui
// 經過config方法能夠對requirejs進行配置 // 其中經過baseUrl來配置加載路徑 require.config({ baseUrl: './public', // 使用path能夠爲模塊真實路徑起個"別名" paths: { jquery: 'assets/jquery/jquery.min' } }); // a和b模塊都依賴於jquery,當改變jquery路徑時 // 只須要改變配置裏的path就能夠了 require(['./src/a', 'src/b']);
在現實開發中並非全部的JS庫都是按着模塊化形式開發,可是咱們又不得不使用這些JS庫,requirejs提供瞭解決方案。spa
爲了幫助理解,總結了模塊的兩個特色「舍與得」
a) 「舍」指模塊將自身模塊的功能提供給其它模塊使用
define(function () { var obj = { name: '小明', sayHi: function () { //code... }, now: function () { // code... } } // 將自身功能提供給其它模塊 return obj; })
b) 「得」指模塊將其它模塊提供的功能直接拿來用
define(['demo'], function (demo) { // 經過數組形式提定依賴的模塊 // 以形參的形式使用其它模塊提供的功能 });
對於非模塊requirejs也有解決方案,經過另一種形式來知足「舍與得」的特色,以下
// 經過config方法能夠對requirejs進行配置 // 其中經過baseUrl來配置加載路徑 require.config({ baseUrl: './public', // 使用path能夠爲模塊真實路徑起個"別名" paths: { jquery: 'assets/jquery/jquery.min', c: 'src/c', demo: 'assets/custom/demo' }, shim: { c: { // 指定當前c模塊依賴於demo // 至關於標準模塊裏的 // define(['demo'], function () {}); deps: ['demo'], exports: 'newobj' }, demo: { // 指明當前demo模塊的返回值 // 至關於標準模塊裏的 // define(function () {return obj;}); exports: 'obj' } } }); // require(['./src/a', 'src/b', 'c']); require(['c']);
// 匿名 define([], function () { // code... // return }); // 具名 define('demo', [], function () { // code... });
先寫到這裏吧,有機會再補充