中文在线免费看视频_国产成人精品亚洲日本在线观看_亚洲精品第一综合99久久_国产亚洲精品日韩综合网

當前位置: 首頁 / 技術干貨 / 正文
JavaScript 模塊化

2022-12-02

模塊 js require module

  模塊化簡介

  JavaScript 最初的目的是為了解決用戶交互頁面的問題;但是隨著互聯(lián)網(wǎng)技術的發(fā)展,瀏覽器性能大大提升,很多用戶交互頁面也隨之復雜起來,更是隨著 Web2.0 的發(fā)展,頁面異步交互,前端代碼庫層出不窮,前端代碼日益膨脹;此時 Js 方便就會去考慮使用代碼模塊規(guī)范去管理。

  而在項目開發(fā)中我們常把一個功能歸類為一個模塊,多個程序員去負責不同的模塊。 js也不例外,然而 js 早期通過閉包的方式去實現(xiàn)模塊化的方式存在很多的問題,隨著 js 的發(fā)展中, 很多人為 js 提供了各種出色的模塊化方案。 其中代表有requirejs ,seajs,commonjs,es6 的模塊化方案。(其中 es6 的模塊化方案必定是將來的主流,這也是至今官方提出唯一的規(guī)范)。

  模塊化初級

  什么是模塊

  將一些復雜的程序代碼根據(jù)制定的規(guī)則封裝成幾個塊(文件), 并進行組合在一起

  塊(文件)的內(nèi)部數(shù)據(jù)是私有的, 只向外部暴露部分接口(方法)與其它模塊進行通信

  模塊化的進化

  原始寫法

  模塊就是實現(xiàn)特定功能的一組方法。只要把不同的函數(shù)(以及記錄狀態(tài)的變量)簡單地放在一起,就算是一個模塊。

  function m1(){

  //...

  }

  function m2(){

  //...

  }

  上面的函數(shù) m1()和 m2(),組成一個模塊。使用的時候,直接調(diào)用就行了。這種做法的缺點很明顯:"污染"了全局變量,無法保證不與其他模塊發(fā)生變量名沖突,而且模塊成員之間看不出直接關系。

  對象寫法

  為了解決上面的缺點,可以把模塊寫成一個對象,所有的模塊成員都放到這個對象里面。

  var module1 = {

  count : 0.

  m1: function (){

  //...

  },

  m2: function (){

  //...

  }

  };

  上面的函數(shù) m1()和 m2(),都封裝在 module1 對象里。使用的時候,就是調(diào)用這個對象的屬性。module1.m1();但是,這樣的寫法會暴露所有模塊成員,內(nèi)部狀態(tài)可以被外部改寫。比如,外部代碼可以直接改變內(nèi)部計數(shù)器的值。module1.count = 5;

  匿名函數(shù)自調(diào)用(閉包)

  將數(shù)據(jù)和行為封裝到一個函數(shù)內(nèi)部, 通過給 window 添加屬性來向外暴露接口

  // module.js 文件

  (function(window,$) {

  var data = '1000phone.com'

  //操作數(shù)據(jù)的函數(shù)

  function foo() {//用于暴露有函數(shù)

  console.log("foo()"+data);

  }

  function bar() {//用于暴露有函數(shù)

  console.log("bar()"+data);

  $('body').css('background', 'red');

  otherFun(); //內(nèi)部調(diào)用

  }

  function otherFun() {

  //內(nèi)部私有的函數(shù)

  console.log('otherFun()');

  }

  //暴露行為

  window.myModule = {

  foo: foo,

  bar: bar

  }

  })(window, $)

  使用閉包的方式, 可以達到不暴露私有成員的目的, 外部通過暴露的方法操作私有成員

  案例中通過 jquery 方法將頁面的背景顏色改成紅色, 所以必須先引入 jQuery 庫,就把這個庫當作參數(shù)傳入。 這樣做除了保證模塊的獨立性,還使得模塊之間的依賴關系變得明顯。

  模塊化的好處

  減少命名空間污染

  更好的分離, 按需加載

  更高復用性

  高可維護性

  引入多個模塊后出現(xiàn)的問題

  請求過多

  首先我們要依賴多個模塊,那樣就會發(fā)送多個請求,導致請求過多

  依賴模糊

  我們不知道他們的具體依賴關系是什么,也就是說很容易因為不了解他們之間的依賴關系導致加載先后順序出錯。

  難以維護

  前兩個原因就導致了很難維護,很可能出現(xiàn)牽一發(fā)而動全身的情況導致項目出現(xiàn)嚴重的問題。

  模塊化固然有多個好處,然而一個頁面需要引入多個 js 文件,就會出現(xiàn)以上這些問題。而這些問題可以通過模塊化規(guī)范來解決

  CommonJS

  09 年, Ryan Dahl 創(chuàng)造了 node.js 項目,將 JavaScript 語言用于服務器端編程。這也標志著"JavaScript 模塊化編程"正式誕生。因為老實說,在瀏覽器環(huán)境下,沒有模塊也不是特別大的問題,畢竟網(wǎng)頁程序的復雜性有限;但是在服務器端,一定要有模塊, 與操作系統(tǒng)和其他應用程序互動,否則根本沒法編程。

  node.js 的模塊系統(tǒng),就是參照 CommonJS 規(guī)范實現(xiàn)的。在 CommonJS 中,有一個全局性方法 require(),用于加載模塊。假定有一個文件模塊 fs.js,就可以像下面這樣加載,并調(diào)用模塊提供的方法

  const fs = require('fs');

  fs.writeFileSync('./test.js'.'hello node');

  //require()用于加載模塊

  上面的代碼中有一個問題,fs.writeFileSync('./test.js'.'hello node')代碼的運行是在載入 fs.js 之后; 即文件的同步加載還是異步加載, 這對于服務端不是問題,但是對于瀏覽器端就是大問題;瀏覽器端如果是同步加載模塊, 則載入的模塊的等待時間取決于網(wǎng)速的快慢,可能需要等待很長時間, 這對用戶體驗是一個很大的考驗。 由此而來 AMD 規(guī)范誕生的背景。

  AMD 異步模塊定義

  目前,主要有兩個 Javascript 庫實現(xiàn)了 AMD 規(guī)范: require.js 和 curl.js。

  我們主要介紹require.js

  require.js 的誕生,就是為了解決這兩個問題:

  實現(xiàn) js 文件的異步加載,避免網(wǎng)頁失去響應;

  管理模塊之間的依賴性,便于代碼的編寫和維護。

  require.js 的加載

  使用 require.js 的第一步,是先去官方網(wǎng)站下載最新版本。https://requirejs.org/docs/download.html#latest,下載后,假定把它放在 js/libs 子目錄下面,就可以加載了。

  上面的 require.js 加載完畢后,會首先檢查script標簽中的 data-main 屬性, 加載 data-main 屬性值中所定義的 js 文件;如:data-main='js/libs/main',將在 require.js 加載完畢后第一個加載 js/libs 路徑下的main.js注意: require.js 后綴名是 js,所以 main 的后綴名省略)

  使用案例(引入第三方庫)

  創(chuàng)建 js/libs 目錄存放 require.js 及第三方庫文件

  將下載的 require.js 文件及需要用到的第三方庫文件放入 js/libs 目錄下

  編寫自定義模塊

  編寫自定義功能模塊(網(wǎng)址大寫轉換)

  // js/modules/dataService.js 文件

  // 定義沒有依賴的模塊

  define(function() {

  var msg = 'www.1000phone.com';

  function getMsg() {

  return msg.toUpperCase();

  }

  return { getMsg } // 暴露模塊

  })

  編寫自定義功能模塊(控制臺輸出,改變網(wǎng)頁背景顏色)

  // js/modules/console.js 文件

  // 定義有依賴的模塊

  define(['dataService','jquery'], function(dataService,$) {

  var name = 'Leon';

  function showMsg() {

  console.log(dataService.getMsg() + ',' + name);

  $('body').css('background','skyblue');

  }

  // 暴露模塊

  return { showMsg }

  })

  語法解析: 定義暴露模塊:

  //定義沒有依賴的模塊

  define(function(){

  return 模塊

  })

  //定義有依賴的模塊

  define(['module1', 'module2'], function(m1. m2){

  return 模塊

  })

  // 其中 module1. module2 為依賴模塊

  定義入口模塊

  // js/main.js 文件

  (function() {

  require.config({

  baseUrl: 'js/', //基本路徑 出發(fā)點在根目錄下

  paths: {

  //映射: 模塊標識名: 路徑

  // 自定義模塊

  console: './modules/console', //此處不能寫成 console.js,會報錯

  dataService: './modules/dataService',

  // 第三方模塊

  jquery: './libs/jquery-1.11.3.min'

  }

  });

  require(['console'], function(console) {

  console.showMsg();

  });

  })()

  語法解析:

  引入使用模塊:

  require(['module1', 'module2'], function(m1. m2){

  // 使用 m1/m2

  })

  require——該函數(shù)用于讀取依賴。同樣它是一個全局函數(shù),不需要使用 requirejs 命名空間.

  config——該函數(shù)用于配置 RequireJS.

  require.config 配置參數(shù)選項

  baseUrl——用于加載模塊的根路徑。

  paths——用于映射存在根路徑下面的模塊路徑

  定義主頁面

  AMD module

  小結:AMD 模塊定義的方法非常清晰,不會污染全局環(huán)境,能夠清楚地顯示依賴關系。 AMD 模式可以用于瀏覽器環(huán)境,并且允許非同步加載模塊,也可以根據(jù)需要動態(tài)加載模塊。

  CMD

  CMD 規(guī)范專門用于瀏覽器端,模塊的加載是異步的,模塊使用時才會加載執(zhí)行。 CMD 規(guī)范整合了 CommonJS 和 AMD 規(guī)范的特點。在 Sea.js 中,所有 JavaScript 模塊都遵循 CMD模塊定義規(guī)范。 Sea.js 可以實現(xiàn) JavaScript 的模塊化開發(fā)及加載機制。它應用于早期的一些 js 項目中,是淘寶 js 工程師玉伯提出的一個方案。文檔

  CMD 規(guī)范基本語法

  define(function(require, exports, module){...});

  用來定義模塊。 Sea.js 推崇一個模塊一個文件,遵循統(tǒng)一的寫法

  define(function(require){var a = require("xModule"); ... });

  require 用來獲取指定模塊的接口,引入的是模塊, js 文件的后綴.js 可以不寫

  require.async

  用來在模塊內(nèi)部異步加載一個或多個模塊。 例如:

  define(function(require){

  require.async(['aModule','bModule'],function(a,b){

  // 異步加載多個模塊,在加載完成時,執(zhí)行回調(diào)

  a.func();

  b.func();

  });

  });

  exports

  用來在模塊內(nèi)部對外提供接口。 例如:

  define(function(require, exports){

  exports.varName01 = 'varValue'; // 對外提供 varName01 屬性

  exports.funName01 = function(p1.p2){ // 對外提供 funName01 方法

  ....

  }

  });

  module.exports

  用來在模塊內(nèi)部對外提供接口。例如:

  define(function(require, exports, module) {

  module.exports = { // 對外提供接口

  name: 'a',

  doSomething: function() {...};

  };

  });

  seajs.config({...});

  用來對 Sea.js 進行配置。

  seajs.use(['a','b'],function(a,b){...});

  用來在頁面中加載一個或多個模塊。

  定義暴露模塊:

  //定義沒有依賴的模塊

  define(function(require, exports, module){

  exports.xxx = value

  module.exports = value

  })

  //定義有依賴的模塊

  define(function(require, exports, module){

  //引入依賴模塊(同步)

  var module2 = require('./module2')

  //引入依賴模塊(異步)

  require.async('./module3', function (m3) {})

  //暴露模塊

  exports.xxx = value

  })

  引入使用模塊:

  define(function (require) {

  var m1 = require('./module1')

  var m4 = require('./module4')

  m1.show()

  m4.show()

  })

  創(chuàng)建 js/libs 目錄,

  將下載的 seajs 放在js/libs目錄下

  自定義模塊代碼并使用

  定義 module1 模塊,并暴露 show 方法

  // js/modules/module1.js 文件

  define(function (require, exports, module) {

  //內(nèi)部變量數(shù)據(jù)

  var data = '1000phone.com';

  //內(nèi)部函數(shù)

  function show() {

  console.log('module1 show() ' + data);

  }

  //向外暴露

  exports.show = show;

  })

  定義 module2 模塊,并暴露接口信息 msg

  // js/modules/module2.js 文件

  define(function (require, exports, module) {

  module.exports = {

  msg: '1000phone study'

  }

  })

  定義 module3 模塊,并暴露一個常量信息

  // js/modules/module3.js 文件

  define(function(require, exports, module) {

  const API_KEY = 'leon';

  exports.API_KEY = API_KEY

  })

  定義 module4 模塊, 同步引入 module2. 異步引入 module3 模塊

  // js/modules/module4.js 文件

  define(function (require, exports, module) {

  // 引入依賴模塊(異步)

  require.async('./module3', function (m3) {

  console.log('異步引入依賴模塊 3 ' + m3.API_KEY)

  });

  // 引入依賴模塊(同步)

  var module2 = require('./module2');

  function show() {

  console.log('module4 show() ' + module2.msg)

  }

  exports.show = show;

  });

  定義主文件 main 模塊,引入模塊 module1 和模塊 module4 并分別調(diào)用 show 方法

  // js/modules/main.js 文件

  define(function (require) {

  var m1 = require('./module1')

  var m4 = require('./module4')

  m1.show()

  m4.show()

  })

  創(chuàng)建主頁面,并在頁面中加載 main 模塊

  小結:通過 Sea.js 可以將大量 javascript 代碼封裝成一個個小模塊,然后輕松實現(xiàn)模塊的加載和依賴管理

  ES6 的 Module

  在 ES6 之前,模塊加載方案主要還是使用 CommonJS 和 AMD 兩種。前者用于服務器,后者用于瀏覽器。 ES6 在語言標準的層面上,實現(xiàn)了模塊功能,而且實現(xiàn)得相當簡單,完全可以取代 CommonJS 和 AMD 規(guī)范,成為瀏覽器和服務器通用的模塊解決方案。ES6 模塊的設計思想是盡量的靜態(tài)化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量。 CommonJS 和 AMD 模塊,都只能在運行時確定這些東西。比如:CommonJS 模塊就是對象,輸入時必須查找對象屬性。ES6 的模塊自動采用嚴格模式,不管你有沒有在模塊頭部加上 "use strict";。

  模塊功能主要命令

  模塊功能主要由兩個命令構成: export 和 import。

  export 命令用于規(guī)定模塊的對外接口,

  import 命令用于輸入其他模塊提供的功能。

  一個模塊就是一個獨立的文件。該文件內(nèi)部的所有變量,外部無法獲取。如果你希望外部能夠讀取模塊內(nèi)部的某個變量,就必須使用 export 關鍵字輸出該變量。使用 export 命令定義了模塊的對外接口以后,其他 JS 文件就可以通過 import 命令加載這個模塊。

  /** 定義模塊 math.js **/

  var basicNum = 0;

  var add = function (a, b) {

  return a + b;

  };

  export { basicNum, add };

  /** 引用模塊 **/

  import { basicNum, add } from './math';

  function test(ele) {

  ele.textContent = add(99 + basicNum);

  }

  瀏覽器加載 ES6 模塊

  瀏覽器加載 ES6 模塊,也使用上面代碼在網(wǎng)頁中插入一個模塊 foo.js,由于 type 屬性設為 module,所以瀏覽器知道這是一個 ES6 模塊。

  瀏覽器對于帶有 type="module"的

  使用 Web 服務器打開首頁 index.html 文件

圖片10

分享: 更多

上一篇:JavaScript 線程與進程初探

下一篇:手封MyPromise

好程序員公眾號

  • · 剖析行業(yè)發(fā)展趨勢
  • · 匯聚企業(yè)項目源碼

好程序員開班動態(tài)

More+
  • HTML5大前端 <高端班>

    開班時間:2021-04-12(深圳)

    開班盛況

    開班時間:2021-05-17(北京)

    開班盛況
  • 大數(shù)據(jù)+人工智能 <高端班>

    開班時間:2021-03-22(杭州)

    開班盛況

    開班時間:2021-04-26(北京)

    開班盛況
  • JavaEE分布式開發(fā) <高端班>

    開班時間:2021-05-10(北京)

    開班盛況

    開班時間:2021-02-22(北京)

    開班盛況
  • Python人工智能+數(shù)據(jù)分析 <高端班>

    開班時間:2021-07-12(北京)

    預約報名

    開班時間:2020-09-21(上海)

    開班盛況
  • 云計算開發(fā) <高端班>

    開班時間:2021-07-12(北京)

    預約報名

    開班時間:2019-07-22(北京)

    開班盛況
IT培訓IT培訓
在線咨詢
IT培訓IT培訓
試聽
IT培訓IT培訓
入學教程
IT培訓IT培訓
立即報名
IT培訓

Copyright 2011-2023 北京千鋒互聯(lián)科技有限公司 .All Right 京ICP備12003911號-5 京公網(wǎng)安備 11010802035720號

中文在线免费看视频_国产成人精品亚洲日本在线观看_亚洲精品第一综合99久久_国产亚洲精品日韩综合网

            久久精品夜夜夜夜久久| 日韩欧美久久久| 久久亚洲私人国产精品va媚药| 亚洲美女一区二区三区| 另类欧美日韩国产在线| 91网站黄www| 久久久久国产精品免费免费搜索| 亚洲成a人在线观看| 99久久久无码国产精品| 久久久亚洲精品一区二区三区| 亚洲成a人片综合在线| 91免费视频网| 国产精品视频在线看| 九色|91porny| 91麻豆精品国产91久久久更新时间 | 亚洲亚洲人成综合网络| 99视频在线观看一区三区| 欧美精品一区二区精品网| 天堂午夜影视日韩欧美一区二区| 色偷偷一区二区三区| 国产嫩草影院久久久久| 国产一区二区三区| 精品国产伦一区二区三区观看方式 | 欧美日韩午夜在线| 亚洲免费观看在线视频| 播五月开心婷婷综合| 久久精品视频免费| 国产精品一区二区你懂的| 日韩一级片网站| 日韩中文字幕区一区有砖一区 | 成人精品一区二区三区四区| 精品999久久久| 九一久久久久久| 欧美成人aa大片| 老司机精品视频导航| 日韩美女视频一区二区在线观看| 视频一区二区不卡| 宅男噜噜噜66一区二区66| 午夜影视日本亚洲欧洲精品| 在线观看av一区| 亚洲在线视频免费观看| 欧美三级韩国三级日本三斤| 亚洲午夜激情网站| 欧美久久久久久蜜桃| 日韩成人精品在线观看| 91麻豆精品久久久久蜜臀| 免费看精品久久片| 欧美r级在线观看| 国产精品一区二区视频| 国产欧美日韩不卡免费| 成人黄页在线观看| 亚洲欧美激情在线| 欧美手机在线视频| 日韩电影免费在线观看网站| 欧美不卡一区二区三区| 国产在线一区二区综合免费视频| 久久久精品免费免费| 成人性生交大合| 亚洲日本在线视频观看| 在线观看91精品国产入口| 丝袜亚洲另类丝袜在线| 日韩欧美在线不卡| 国产一区二区调教| 国产精品视频第一区| 一本色道久久加勒比精品| 午夜精品久久久久久久蜜桃app | 99国产精品久| 亚洲午夜久久久久久久久电影院| 欧美电影一区二区三区| 久久疯狂做爰流白浆xx| 国产精品情趣视频| 欧美中文字幕亚洲一区二区va在线 | 亚洲图片激情小说| 欧美日韩一区二区三区四区 | 美女www一区二区| 久久久综合精品| 波多野结衣中文字幕一区| 亚洲综合视频在线观看| 日韩免费看的电影| 成人免费看片app下载| 亚洲一区日韩精品中文字幕| 日韩欧美一区二区三区在线| 高清beeg欧美| 亚洲高清免费视频| 国产午夜三级一区二区三| 91年精品国产| 麻豆精品视频在线观看免费| 国产精品久久久久久亚洲毛片| 欧美日韩亚洲综合在线 欧美亚洲特黄一级 | 9191成人精品久久| 国产91综合一区在线观看| 亚洲国产欧美在线| 久久精品一区二区三区av| 欧美亚洲动漫精品| 国产91精品一区二区麻豆网站 | 久久久高清一区二区三区| 91久久线看在观草草青青| 黄页视频在线91| 亚洲中国最大av网站| 久久久久久久综合日本| 欧美系列一区二区| 成人免费视频一区| 日韩电影免费在线看| 1024成人网色www| 精品成a人在线观看| 欧美日韩在线播放三区| 成人久久视频在线观看| 蜜臀av在线播放一区二区三区| 亚洲视频香蕉人妖| 久久夜色精品国产欧美乱极品| 在线视频综合导航| 丁香天五香天堂综合| 午夜影院久久久| 亚洲视频一二三| 国产亚洲一区字幕| 日韩视频在线你懂得| 在线免费观看一区| 丰满少妇久久久久久久| 久久精品国产澳门| 亚洲成人激情社区| 亚洲精品午夜久久久| 久久精品亚洲国产奇米99| 日韩片之四级片| 欧美精品一卡二卡| 色婷婷av一区二区三区软件 | 国产精品亚洲视频| 日本大胆欧美人术艺术动态| 亚洲综合激情网| 国产精品传媒入口麻豆| 久久色在线视频| 日韩一级片在线观看| 欧美丰满一区二区免费视频| 日本二三区不卡| 97se亚洲国产综合自在线不卡| 国产超碰在线一区| 国产精品91xxx| 韩国精品久久久| 日韩av中文在线观看| 亚洲成人av免费| 亚洲综合成人在线视频| 亚洲精品日韩一| 亚洲美女免费视频| 亚洲色图另类专区| 自拍av一区二区三区| 国产精品久久久久9999吃药| 欧美国产精品专区| 国产农村妇女精品| 国产欧美一区二区三区在线看蜜臀 | 国产精品1区二区.| 国产最新精品免费| 国产呦精品一区二区三区网站| 精品一区二区三区在线播放| 麻豆精品久久久| 精品一二三四区| 久久国产成人午夜av影院| 精品制服美女久久| 精品一区二区三区免费观看 | 日本特黄久久久高潮| 亚洲v精品v日韩v欧美v专区| 婷婷国产v国产偷v亚洲高清| 视频一区二区不卡| 免费成人在线观看视频| 美女性感视频久久| 激情久久五月天| 国产成人亚洲综合a∨婷婷| 国产乱码一区二区三区| 国产成人av福利| 成人黄色国产精品网站大全在线免费观看 | 久久综合999| 国产亲近乱来精品视频| 国产精品免费aⅴ片在线观看| 成人欧美一区二区三区白人 | 亚洲国产日韩av| 日本不卡1234视频| 国内不卡的二区三区中文字幕| 国产成人精品免费视频网站| 不卡的电影网站| 日本高清免费不卡视频| 欧美日韩亚洲另类| 精品国产乱码久久久久久牛牛| 国产日韩精品视频一区| 最新热久久免费视频| 一区二区久久久| 青青草国产成人99久久| 国产精品一卡二| 一本到不卡免费一区二区| 欧美久久久久久久久| 久久综合狠狠综合久久综合88| 国产精品美女视频| 亚洲成av人综合在线观看| 久久精品久久精品| 99热精品国产| 欧美精品在线观看播放| 久久久久国产精品厨房| 亚洲三级理论片| 久久精品久久精品| 99久久99久久免费精品蜜臀| 欧美福利视频一区| 欧美国产国产综合| 亚洲成a人片在线不卡一二三区 |