js-模塊化(三大模塊化規范)


###1. JS模塊化
* 模塊化的理解
  * 什么是模塊?
      * 將一個復雜的程序依據一定的規則(規范)封裝成幾個塊(文件), 並進行組合在一起
      * 塊的內部數據/實現是私有的, 只是向外部暴露一些接口(方法)與外部其它模塊通信
  * 一個模塊的組成
      * 數據--->內部的屬性
      * 操作數據的行為--->內部的函數
  * 模塊化
      * 編碼時是按照模塊一個一個編碼的, 整個項目就是一個模塊化的項目
  * 模塊化的進化過程
    * 全局function模式
      * 編碼: 全局變量/函數
      * 問題: 污染全局命名空間, 容易引起命名沖突/數據不安全
          * function a(){}
          * function b(){} 
    * namespace模式 : 
      * 編碼: 將數據/行為封裝到對象中
      * 解決: 命名沖突(減少了全局變量)
      * 問題: 數據不安全(外部可以直接修改模塊內部的數據)
          * var abc = {
              * a: function(){}
              * b: function(){}
          * }
    * IIFE模式/增強(匿名閉包)
      * IIFE : 立即調用函數表達式--->匿名函數自調用
      * 編碼: 將數據和行為封裝到一個函數內部, 通過給window添加屬性來向外暴露接口
      * 引入依賴: 通過函數形參來引入依賴模塊
        ```
        (function(window, module2){
          var data = 'atguigu.com'
          function foo() {
             module2.xxx()
             console.log('foo()'+data)
          }
          function bar() {
             console.log('bar()'+data)
          }
        
          window.module = {foo}
        })(window, module2)
        ```

###2. 模塊化規范
  * CommonJS(同步)
    * Node.js : 服務器端
    * Browserify : 瀏覽器端    也稱為js的打包工具
    * 基本語法:
      * 定義暴露模塊 : exports
        ```
        exports.xxx = value
        module.exports = value
        ```
      引入模塊 : require
        ```
        var module = require('模塊名/模塊相對路徑')
        ```
    * 引入模塊發生在什么時候?
      * Node : 運行時, 動態同步引入
      * Browserify : 在運行前對模塊進行編譯/轉譯/打包的處理(已經將依賴的模塊包含進來了), 
                  運行的是打包生成的js, 運行時不存在需要再從遠程引入依賴模塊

    ## Browserify模塊化使用教程
    1. 創建項目結構
      ```
      |-js
          |-dist //打包生成文件的目錄
          |-src //源碼所在的目錄
            |-module1.js
            |-module2.js
            |-module3.js
            |-app.js //應用主源文件
      |-index.html
      |-package.json

     {
          "name": "browserify-test",
          "version": "1.0.0"
        }
      ```
  2. 下載browserify
      * 全局: npm install browserify -g
      * 局部: npm install browserify --save-dev
  3. 定義模塊代碼
    * module1.js
      ```
      module.exports = {
          foo() {
            console.log('moudle1 foo()')
        }
      }
      ```
    * module2.js
      ```
      module.exports = function () {
        console.log('module2()')
      }
      ```
    * module3.js
      ```
      exports.foo = function () {
        console.log('module3 foo()')
      }
    
      exports.bar = function () {
        console.log('module3 bar()')
      }
      ```
    * app.js (應用的主js)
      ```
      //引用模塊
      let module1 = require('./module1')
      let module2 = require('./module2')
      let module3 = require('./module3')
    
      let uniq = require('uniq')
    
      //使用模塊
      module1.foo()
      module2()
      module3.foo()
      module3.bar()
    
      console.log(uniq([1, 3, 1, 4, 3]))
      ```
  * 打包處理js:
      * browserify js/src/app.js -o js/dist/bundle.js
  * 頁面使用引入:
    ```
    <script type="text/javascript" src="js/dist/bundle.js"></script> 
    ```
  * AMD (Asynchronous Module Definition 異步模塊定義) : 瀏覽器端
    * require.js
    * 基本語法
      * 定義暴露模塊: define([依賴模塊名], function(){return 模塊對象})
      * 引入模塊: require(['模塊1', '模塊2', '模塊3'], function(m1, m2){//使用模塊對象})
      * 配置: 
        ```
        require.config({
          //基本路徑
          baseUrl : 'js/',
          //標識名稱與路徑的映射
          paths : {
            '模塊1' : 'modules/模塊1',
            '模塊2' : 'modules/模塊2',
            'angular' : 'libs/angular',
            'angular-messages' : 'libs/angular-messages'
          },
          //非AMD的模塊
          shim : {
            'angular' : {
                exports : 'angular'
            },
            'angular-messages' : {
                exports : 'angular-messages',
                deps : ['angular']
            }
          }
        })
        ```
  * ES6
    * ES6內置了模塊化的實現
    * 基本語法
      * 定義暴露模塊 : export
        * 暴露一個對象: 
          ```
          export default 對象
          ```
        * 暴露多個: 
          ```
          export var xxx = value1
          export let yyy = value2
          
          var xxx = value1
          let yyy = value2
          export {xxx, yyy}
          ```
              
      * 引入使用模塊 : import
        * default模塊:
          ```
          import xxx  from '模塊路徑/模塊名'
          ```
        * 其它模塊
          ```
          import {xxx, yyy} from '模塊路徑/模塊名'
          import * as module1 from '模塊路徑/模塊名'
          ```
    * 問題: 所有瀏覽器還不能直接識別ES6模塊化的語法  
    * 解決:
        * 使用Babel將ES6--->ES5(使用了CommonJS) ----瀏覽器還不能直接支行
        * 使用Browserify--->打包處理----瀏覽器可以運行

 

### Es6常規暴露方法: 

    1. 分別暴露

      export function foo(){}

      export function bar(){}

    2. 統一暴露

      function fun(){}

      function fun2(){}

      export {fun,fun2}

### ES6默認暴露

  export default () =>{

    ...

  }

  引入:improt xxx from './...'

  使用: xxx();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM