日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

javascript中的模块系统

發(fā)布時間:2024/2/28 javascript 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 javascript中的模块系统 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 簡介
  • CommonJS和Nodejs
  • AMD異步模塊加載
  • CMD
  • ES modules和現(xiàn)代瀏覽器
  • 在HTML中使用module和要注意的問題

簡介

在很久以前,js只是簡單的作為瀏覽器的交互操作而存在,一般都是非常短小的腳本,所以都是獨立存在的。

但是隨著現(xiàn)代瀏覽器的發(fā)展,特別是nodejs的出現(xiàn),js可以做的事情變得越來越多也越來越復(fù)雜。于是我們就需要模塊系統(tǒng)來組織不同用途的腳本,進行邏輯的區(qū)分和引用。

今天將會給大家介紹一下js中的模塊系統(tǒng)。

CommonJS和Nodejs

CommonJS是由Mozilla公司在2009年1月份提出來了。沒錯,就是那個firfox的公司。

最初的名字叫做ServerJS,在2009年8月的時候為了表示這個標準的通用性,改名為CommonJS。

CommonJS最主要的應(yīng)用就是服務(wù)端的nodejs了。瀏覽器端是不直接支持CommonJS的,如果要在瀏覽器端使用,則需要進行轉(zhuǎn)換。

CommonJS使用require()來引入模塊,使用module.exports來導(dǎo)出模塊。

我們看一個CommonJS的例子:

require("module"); require("../file.js"); exports.doStuff = function() {}; module.exports = someValue;

注意,CommonJS是同步加載的。

AMD異步模塊加載

AMD的全稱是Asynchronous Module Definition 。它提供了一個異步加載模塊的模式。

AMD是RequireJS在推廣過程中對模塊定義的規(guī)范化產(chǎn)出。

異步加載的好處就是可以在需要使用模塊的時候再進行加載,從而減少了一次性全部加載的時間,尤其是在瀏覽器端,可以提升用戶的體驗。

看下AMD加載模塊的定義:

define(id?, dependencies?, factory);

AMD是通過define來定義和加載依賴模塊的。

其中id表示要定義的模塊的名字,dependencies表示這個模塊的依賴模塊,factory是一個函數(shù),用來初始化模塊或者對象。

我們看一個例子:

define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {exports.verb = function() {return beta.verb();//Or:return require("beta").verb();}});

這個例子中,我們定義了一個alpha模塊,這個模塊需要依賴"require", “exports”, "beta"三個模塊。

并且在factory中導(dǎo)出了beta模塊的verb方法。

define中id和dependencies都不是必須的:

//無iddefine(["alpha"], function (alpha) {return {verb: function(){return alpha.verb() + 2;}};});//無依賴define({add: function(x, y){return x + y;}});

甚至我們可以在AMD中使用CommonJS:

define(function (require, exports, module) {var a = require('a'),b = require('b');exports.action = function () {};});

定義完之后,AMD使用require來加載模塊:

require([dependencies], function(){});

第一個參數(shù)是依賴模塊,第二個參數(shù)是回調(diào)函數(shù),會在前面的依賴模塊都加載完畢之后進行調(diào)用。加載的模塊會以參數(shù)形式傳入該函數(shù),從而在回調(diào)函數(shù)內(nèi)部就可以使用這些模塊。

require(["module", "../file"], function(module, file) { /* ... */ });

require加載模塊是異步加載的,但是后面的回調(diào)函數(shù)只會在所有的模塊都加載完畢之后才運行。

CMD

CMD是SeaJS在推廣過程中對模塊定義的規(guī)范化產(chǎn)出。它的全稱是Common Module Definition。

CMD也是使用define來定義模塊的,CMD推崇一個文件作為一個模塊:

define(id?, deps?, factory)

看起來和AMD的define很類似,都有id,依賴模塊和factory。

這里的factory是一個函數(shù),帶有三個參數(shù),function(require, exports, module)

我們可以在factory中通過require來加載需要使用的模塊,通過exports來導(dǎo)出對外暴露的模塊,module表示的是當前模塊。

我們看一個例子:

// 定義模塊 myModule.js define(function(require, exports, module) {var $ = require('jquery.js')$('div').addClass('active'); });// 加載模塊 seajs.use(['myModule.js'], function(my){});

所以總結(jié)下AMD和CMD的區(qū)別就是,AMD前置要加載的依賴模塊,在定義模塊的時候就要聲明其依賴的模塊。

而CMD加載完某個依賴模塊后并不執(zhí)行,只是下載而已,只有在用到的時候才使用require進行執(zhí)行。

ES modules和現(xiàn)代瀏覽器

ES6和現(xiàn)代瀏覽器對模塊化的支持是通過import和export來實現(xiàn)的。

首先看下import和export在瀏覽器中支持的情況:

首先我們看下怎么使用export導(dǎo)出要暴露的變量或者方法:

export const name = 'square';export function draw(ctx, length, x, y, color) {ctx.fillStyle = color;ctx.fillRect(x, y, length, length);return {length: length,x: x,y: y,color: color}; }

基本上,我們可以使用export導(dǎo)出var, let, const變量或者function甚至class。前提是這些變量或者函數(shù)處于top-level。

更簡單的辦法就是將所有要export的放在一行表示:

export { name, draw, reportArea, reportPerimeter };

export實際上有兩種方式,named和default。上面的例子中的export是named格式,因為都有自己的名字。

下面看下怎么使用export導(dǎo)出默認的值:

// export feature declared earlier as default export { myFunction as default };// export individual features as default export default function () { ... } export default class { .. }

named可以導(dǎo)出多個對象,而default只可以導(dǎo)出一個對象。

導(dǎo)出之后,我們就可以使用import來導(dǎo)入了:

import { name, draw, reportArea, reportPerimeter } from './modules/square.js';

如果導(dǎo)出的時候選擇的是default,那么我們在import的時候可以使用任何名字:

// file test.js let k; export default k = 12;// some other file import m from './test'; // 因為導(dǎo)出的是default,所以這里我們可以使用import m來引入 console.log(m); // will log 12

我們可以在一個module中使用import和export從不同的模塊中導(dǎo)入,然后在同一個模塊中導(dǎo)出,這樣第三方程序只需要導(dǎo)入這一個模塊即可。

export { default as function1,function2 } from 'bar.js';

上面的export from 等價于:

import { default as function1,function2 } from 'bar.js'; export { function1, function2 };

上面的例子中,我們需要分別import function1 function2才能夠使用,實際上,我們可以使用下面的方式將所有的import作為Module對象的屬性:

import * as Module from './modules/module.js';Module.function1() Module.function2()

然后function1,function2就變成了Module的屬性,直接使用即可。

在HTML中使用module和要注意的問題

怎么在HTML中引入module呢?我們有兩種方式,第一種是使用src選項:

<script type="module" src="main.js"></script>

第二種直接把module的內(nèi)容放到script標簽中。

<script type="module">/* JavaScript module code here */ </script>

注意,兩種script標簽的類型都是module。

在使用script來加載module的時候,默認就是defer的,所以不需要顯示加上defer屬性。

如果你在測試的時候使用file:// 來加載本地文件的話,因為JS模塊安全性的要求,很有可能得到一個CORS錯誤。

最后,import() 還可以作為函數(shù)使用,來動態(tài)加載模塊:

squareBtn.addEventListener('click', () => {import('./modules/square.js').then((Module) => {let square1 = new Module.Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue');square1.draw();square1.reportArea();square1.reportPerimeter();}) });

本文作者:flydean程序那些事

本文鏈接:http://www.flydean.com/js-modules/

本文來源:flydean的博客

歡迎關(guān)注我的公眾號:「程序那些事」最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發(fā)現(xiàn)!

總結(jié)

以上是生活随笔為你收集整理的javascript中的模块系统的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。