中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

再嘮叨JS模塊化加載之CommonJS、AMD、CMD、ES6

Javascript模塊化編程,已經(jīng)成為一個(gè)迫切的需求。理想情況下,開(kāi)發(fā)者只需要實(shí)現(xiàn)核心的業(yè)務(wù)邏輯,其他都可以加載別人已經(jīng)寫好的模塊。

秀英網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,秀英網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為秀英成百上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的秀英做網(wǎng)站的公司定做!

Javascript社區(qū)做了很多努力,在現(xiàn)有的運(yùn)行環(huán)境中,實(shí)現(xiàn)”模塊”的效果。

CommonJS

CommonJS定義的模塊分為:  模塊引用(require)    模塊輸出(exports)       模塊標(biāo)識(shí)(module)

CommonJS Modules有1.0、1.1、1.1.1三個(gè)版本:

  • Node.js、SproutCore實(shí)現(xiàn)了 Modules 1.0

  • SeaJS、AvocadoDB、CouchDB等實(shí)現(xiàn)了Modules 1.1.1

  • SeaJS、FlyScript實(shí)現(xiàn)了Modules/Wrappings

這里的CommonJS規(guī)范指的是CommonJS Modules/1.0規(guī)范。

CommonJS是一個(gè)更偏向于服務(wù)器端的規(guī)范。NodeJS采用了這個(gè)規(guī)范。CommonJS的一個(gè)模塊就是一個(gè)腳本文件。require命令第一次加載該腳本時(shí)就會(huì)執(zhí)行整個(gè)腳本,然后在內(nèi)存中生成一個(gè)對(duì)象。

{
  id: '...',
  exports: { ... },
  loaded: true,
  ...
}

id是模塊名,exports是該模塊導(dǎo)出的接口,loaded表示模塊是否加載完畢。此外還有很多屬性,這里省略了。

以后需要用到這個(gè)模塊時(shí),就會(huì)到exports屬性上取值。即使再次執(zhí)行require命令,也不會(huì)再次執(zhí)行該模塊,而是到緩存中取值。

// math.js
exports.add = function(a, b) {
  return a + b;
}
var math = require('math');
math.add(2, 3); // 512

由于CommonJS是同步加載模塊,這對(duì)于服務(wù)器端不是一個(gè)問(wèn)題,因?yàn)樗械哪K都放在本地硬盤。等待模塊時(shí)間就是硬盤讀取文件時(shí)間,很小。但是,對(duì)于瀏覽器而言,它需要從服務(wù)器加載模塊,涉及到網(wǎng)速,代理等原因,一旦等待時(shí)間過(guò)長(zhǎng),瀏覽器處于”假死”狀態(tài)。

所以在瀏覽器端,不適合于CommonJS規(guī)范。所以在瀏覽器端又出現(xiàn)了一個(gè)規(guī)范—AMD(AMD是RequireJs在推廣過(guò)程中對(duì)模塊定義的規(guī)范化產(chǎn)出)。

AMD

CommonJS解決了模塊化的問(wèn)題,但這種同步加載方式并不適合于瀏覽器端。

AMD是”Asynchronous Module Definition”的縮寫,即”異步模塊定義”。它采用異步方式加載模塊,模塊的加載不影響它后面語(yǔ)句的運(yùn)行。 
這里異步指的是不堵塞瀏覽器其他任務(wù)(dom構(gòu)建,css渲染等),而加載內(nèi)部是同步的(加載完模塊后立即執(zhí)行回調(diào))。

AMD也采用require命令加載模塊,但是不同于CommonJS,它要求兩個(gè)參數(shù):

require([module], callback);1

第一個(gè)參數(shù)[module],是一個(gè)數(shù)組,里面的成員是要加載的模塊,callback是加載完成后的回調(diào)函數(shù)。如果將上述的代碼改成AMD方式:

require(['math'], function(math) {
  math.add(2, 3);
})

其中,回調(diào)函數(shù)中參數(shù)對(duì)應(yīng)數(shù)組中的成員(模塊)。

requireJS加載模塊,采用的是AMD規(guī)范。也就是說(shuō),模塊必須按照AMD規(guī)定的方式來(lái)寫。

具體來(lái)說(shuō),就是模塊書寫必須使用特定的define()函數(shù)來(lái)定義。如果一個(gè)模塊不依賴其他模塊,那么可以直接寫在define()函數(shù)之中。

define(id?, dependencies?, factory);12
  • id:模塊的名字,如果沒(méi)有提供該參數(shù),模塊的名字應(yīng)該默認(rèn)為模塊加載器請(qǐng)求的指定腳本的名字;

  • dependencies:模塊的依賴,已被模塊定義的模塊標(biāo)識(shí)的數(shù)組字面量。依賴參數(shù)是可選的,如果忽略此參數(shù),它應(yīng)該默認(rèn)為 ["require", "exports", "module"]。然而,如果工廠方法的長(zhǎng)度屬性小于3,加載器會(huì)選擇以函數(shù)的長(zhǎng)度屬性指定的參數(shù)個(gè)數(shù)調(diào)用工廠方法。

  • factory:模塊的工廠函數(shù),模塊初始化要執(zhí)行的函數(shù)或?qū)ο蟆H绻麨楹瘮?shù),它應(yīng)該只被執(zhí)行一次。如果是對(duì)象,此對(duì)象應(yīng)該為模塊的輸出值。

假定現(xiàn)在有一個(gè)math.js文件,定義了一個(gè)math模塊。那么,math.js書寫方式如下:

// math.js
define(function() {
  var add = function(x, y) {
    return x + y;
  }

  return  {
    add: add
  }
})

加載方法如下:

// main.js
require(['math'], function(math) {
  alert(math.add(1, 1));
})

如果math模塊還依賴其他模塊,寫法如下:

// math.js
define(['dependenceModule'], function(dependenceModule) {
    // ...
})

當(dāng)require()函數(shù)加載math模塊的時(shí)候,就會(huì)先加載dependenceModule模塊。當(dāng)有多個(gè)依賴時(shí),就將所有的依賴都寫在define()函數(shù)第一個(gè)參數(shù)數(shù)組中,所以說(shuō)AMD是依賴前置的。這不同于CMD規(guī)范,它是依賴就近的。

CMD

CMD推崇依賴就近,延遲執(zhí)行??梢园涯愕囊蕾噷戇M(jìn)代碼的任意一行,如下:

define(factory)

factory為函數(shù)時(shí),表示是模塊的構(gòu)造方法。執(zhí)行該構(gòu)造方法,可以得到模塊向外提供的接口。factory 方法在執(zhí)行時(shí),默認(rèn)會(huì)傳入三個(gè)參數(shù):require、exports 和 module.

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

如果使用AMD寫法,如下:

// AMDdefine(['a', 'b'], function(a, b) {
  a.doSomething();
  b.doSomething();
})

這個(gè)規(guī)范實(shí)際上是為了Seajs的推廣然后搞出來(lái)的。那么看看SeaJS是怎么回事兒吧,基本就是知道這個(gè)規(guī)范了。

同樣Seajs也是預(yù)加載依賴js跟AMD的規(guī)范在預(yù)加載這一點(diǎn)上是相同的,明顯不同的地方是調(diào)用,和聲明依賴的地方。AMD和CMD都是用difine和require,但是CMD標(biāo)準(zhǔn)傾向于在使用過(guò)程中提出依賴,就是不管代碼寫到哪突然發(fā)現(xiàn)需要依賴另一個(gè)模塊,那就在當(dāng)前代碼用require引入就可以了,規(guī)范會(huì)幫你搞定預(yù)加載,你隨便寫就可以了。但是AMD標(biāo)準(zhǔn)讓你必須提前在頭部依賴參數(shù)部分寫好(沒(méi)有寫好? 倒回去寫好咯)。這就是最明顯的區(qū)別。

sea.js通過(guò)sea.use()來(lái)加載模塊。

seajs.use(id, callback?)

ES6

es6模塊特性,推薦參看阮一峰老師的:ECMAScript 6 入門 - Module 的語(yǔ)法

說(shuō)起 ES6 模塊特性,那么就先說(shuō)說(shuō) ES6 模塊跟 CommonJS 模塊的不同之處。

  • ES6 模塊輸出的是值的引用,輸出接口動(dòng)態(tài)綁定,而 CommonJS 輸出的是值的拷貝

  • ES6 模塊編譯時(shí)執(zhí)行,而 CommonJS 模塊總是在運(yùn)行時(shí)加載

CommonJS 輸出值的拷貝

CommonJS 模塊輸出的是值的拷貝(原始值的拷貝),也就是說(shuō),一旦輸出一個(gè)值,模塊內(nèi)部的變化就影響不到這個(gè)值。

// a.js
var b = require('./b');
console.log(b.foo);
setTimeout(() => {
  console.log(b.foo);
  console.log(require('./b').foo);
}, 1000);

// b.js
let foo = 1;
setTimeout(() => {
  foo = 2;
}, 500);
module.exports = {
  foo: foo,
};
// 執(zhí)行:node a.js
// 執(zhí)行結(jié)果:
// 1
// 1
// 1

上面代碼說(shuō)明,b 模塊加載以后,它的內(nèi)部 foo 變化就影響不到輸出的 exports.foo 了。這是因?yàn)?foo 是一個(gè)原始類型的值,會(huì)被緩存。所以如果你想要在 CommonJS 中動(dòng)態(tài)獲取模塊中的值,那么就需要借助于函數(shù)延時(shí)執(zhí)行的特性。

// a.js
var b = require('./b');
console.log(b.foo());
setTimeout(() => {
  console.log(b.foo());
  console.log(require('./b').foo());
}, 1000);

// b.js
let foo = 1;
setTimeout(() => {
  foo = 2;
}, 500);
module.exports = {
  foo: () => {
    return foo;
  },
};
// 執(zhí)行:node a.js
// 執(zhí)行結(jié)果:
// 1
// 2
// 2

所以我們可以總結(jié)一下:

  • CommonJS 模塊重復(fù)引入的模塊并不會(huì)重復(fù)執(zhí)行,再次獲取模塊直接獲得暴露的 module.exports 對(duì)象

  • 如果你要處處獲取到模塊內(nèi)的最新值的話,也可以你每次更新數(shù)據(jù)的時(shí)候每次都要去更新 module.exports 上的值

  • 如果你暴露的 module.exports 的屬性是個(gè)對(duì)象,那就不存在這個(gè)問(wèn)題了

所以如果你要處處獲取到模塊內(nèi)的最新值的話,也可以你每次更新數(shù)據(jù)的時(shí)候每次都要去更新 module.exports 上的值,比如:

// a.js
var b = require('./b');
console.log(b.foo);
setTimeout(() => {
  console.log(b.foo);
  console.log(require('./b').foo);
}, 1000);

// b.js
module.exports.foo = 1;   // 同 exports.foo = 1 
setTimeout(() => {
  module.exports.foo = 2;
}, 500);

// 執(zhí)行:node a.js
// 執(zhí)行結(jié)果:
// 1
// 2
// 2

ES6 輸出值的引用

然而在 ES6 模塊中就不再是生成輸出對(duì)象的拷貝,而是動(dòng)態(tài)關(guān)聯(lián)模塊中的值。

ES6 靜態(tài)編譯,CommonJS 運(yùn)行時(shí)加載

關(guān)于第二點(diǎn),ES6 模塊編譯時(shí)執(zhí)行會(huì)導(dǎo)致有以下兩個(gè)特點(diǎn):

import 命令會(huì)被 JavaScript 引擎靜態(tài)分析,優(yōu)先于模塊內(nèi)的其他內(nèi)容執(zhí)行。

  • export 命令會(huì)有變量聲明提前的效果。

    import 優(yōu)先執(zhí)行: 

從第一條來(lái)看,在文件中的任何位置引入 import 模塊都會(huì)被提前到文件頂部。

// a.js
console.log('a.js')
import { foo } from './b';

// b.js
export let foo = 1;
console.log('b.js 先執(zhí)行');

// 執(zhí)行結(jié)果:
// b.js 先執(zhí)行
// a.js

從執(zhí)行結(jié)果我們可以很直觀地看出,雖然 a 模塊中 import 引入晚于 console.log('a'),但是它被 JS 引擎通過(guò)靜態(tài)分析,提到模塊執(zhí)行的最前面,優(yōu)于模塊中的其他部分的執(zhí)行。

由于 import 是靜態(tài)執(zhí)行,所以 import 具有提升效果即 import 命令在模塊中的位置并不影響程序的輸出。

/ a.js
import { foo } from './b';
console.log('a.js');
export const bar = 1;
export const bar2 = () => {
  console.log('bar2');
}
export function bar3() {
  console.log('bar3');
}

// b.js
export let foo = 1;
import * as a from './a';
console.log(a);

// 執(zhí)行結(jié)果:
// { bar: undefined, bar2: undefined, bar3: [Function: bar3] }
// a.js

從上面的例子可以很直觀地看出,a 模塊引用了 b 模塊,b 模塊也引用了 a 模塊,export 聲明的變量也是優(yōu)于模塊其它內(nèi)容的執(zhí)行的,但是具體對(duì)變量賦值需要等到執(zhí)行到相應(yīng)代碼的時(shí)候。(當(dāng)然函數(shù)聲明和表達(dá)式聲明不一樣,這一點(diǎn)跟 JS 函數(shù)性質(zhì)一樣,這里就不過(guò)多解釋)

好了,講完了 ES6 模塊和 CommonJS 模塊的不同點(diǎn)之后,接下來(lái)就講講相同點(diǎn):

模塊不會(huì)重復(fù)執(zhí)行

這個(gè)很好理解,無(wú)論是 ES6 模塊還是 CommonJS 模塊,當(dāng)你重復(fù)引入某個(gè)相同的模塊時(shí),模塊只會(huì)執(zhí)行一次。

CommonJS 模塊循環(huán)依賴

// a.js
console.log('a starting');
exports.done = false;
const b = require('./b');
console.log('in a, b.done =', b.done);
exports.done = true;
console.log('a done');

// b.js
console.log('b starting');
exports.done = false;
const a = require('./a');
console.log('in b, a.done =', a.done);
exports.done = true;
console.log('b done');

// node a.js
// 執(zhí)行結(jié)果:
// a starting
// b starting
// in b, a.done = false
// b done
// in a, b.done = true
// a done

結(jié)合之前講的特性很好理解,當(dāng)你從 b 中想引入 a 模塊的時(shí)候,因?yàn)?node 之前已經(jīng)加載過(guò) a 模塊了,所以它不會(huì)再去重復(fù)執(zhí)行 a 模塊,而是直接去生成當(dāng)前 a 模塊吐出的 module.exports 對(duì)象,因?yàn)?a 模塊引入 b 模塊先于給 done 重新賦值,所以當(dāng)前 a 模塊中輸出的 module.exports 中 done 的值仍為 false。而當(dāng) a 模塊中輸出 b 模塊的 done 值的時(shí)候 b 模塊已經(jīng)執(zhí)行完畢,所以 b 模塊中的 done 值為 true。

從上面的執(zhí)行過(guò)程中,我們可以看到,在 CommonJS 規(guī)范中,當(dāng)遇到 require() 語(yǔ)句時(shí),會(huì)執(zhí)行 require 模塊中的代碼,并緩存執(zhí)行的結(jié)果,當(dāng)下次再次加載時(shí)不會(huì)重復(fù)執(zhí)行,而是直接取緩存的結(jié)果。正因?yàn)榇?,出現(xiàn)循環(huán)依賴時(shí)才不會(huì)出現(xiàn)無(wú)限循環(huán)調(diào)用的情況。雖然這種模塊加載機(jī)制可以避免出現(xiàn)循環(huán)依賴時(shí)報(bào)錯(cuò)的情況,但稍不注意就很可能使得代碼并不是像我們想象的那樣去執(zhí)行。因此在寫代碼時(shí)還是需要仔細(xì)的規(guī)劃,以保證循環(huán)模塊的依賴能正確工作。

所以有什么辦法可以出現(xiàn)循環(huán)依賴的時(shí)候避免自己出現(xiàn)混亂呢?一種解決方式便是將每個(gè)模塊先寫 exports 語(yǔ)法,再寫 requre 語(yǔ)句,利用 CommonJS 的緩存機(jī)制,在 require() 其他模塊之前先把自身要導(dǎo)出的內(nèi)容導(dǎo)出,這樣就能保證其他模塊在使用時(shí)可以取到正確的值。比如:

// a.js
exports.done = true;
let b = require('./b');
console.log(b.done)

// b.js
exports.done = true;
let a = require('./a');
console.log(a.done)

這種寫法簡(jiǎn)單明了,缺點(diǎn)是要改變每個(gè)模塊的寫法,而且大部分同學(xué)都習(xí)慣了在文件開(kāi)頭先寫 require 語(yǔ)句。

ES6 模塊循環(huán)依賴

跟 CommonJS 模塊一樣,ES6 不會(huì)再去執(zhí)行重復(fù)加載的模塊,又由于 ES6 動(dòng)態(tài)輸出綁定的特性,能保證 ES6 在任何時(shí)候都能獲取其它模塊當(dāng)前的最新值。

// a.js
console.log('a starting')
import {foo} from './b';
console.log('in b, foo:', foo);
export const bar = 2;
console.log('a done');

// b.js
console.log('b starting');
import {bar} from './a';
export const foo = 'foo';
console.log('in a, bar:', bar);
setTimeout(() => {
  console.log('in a, setTimeout bar:', bar);
})
console.log('b done');

// babel-node a.js
// 執(zhí)行結(jié)果:
// b starting
// in a, bar: undefined
// b done
// a starting
// in b, foo: foo
// a done
// in a, setTimeout bar: 2

動(dòng)態(tài) import()

ES6 模塊在編譯時(shí)就會(huì)靜態(tài)分析,優(yōu)先于模塊內(nèi)的其他內(nèi)容執(zhí)行,所以導(dǎo)致了我們無(wú)法寫出像下面這樣的代碼:

if(some condition) {
  import a from './a';
}else {
  import b from './b';
}

// or 
import a from (str + 'b');

因?yàn)榫幾g時(shí)靜態(tài)分析,導(dǎo)致了我們無(wú)法在條件語(yǔ)句或者拼接字符串模塊,因?yàn)檫@些都是需要在運(yùn)行時(shí)才能確定的結(jié)果在 ES6 模塊是不被允許的,所以 動(dòng)態(tài)引入 import() 應(yīng)運(yùn)而生。

import() 允許你在運(yùn)行時(shí)動(dòng)態(tài)地引入 ES6 模塊,想到這,你可能也想起了 require.ensure 這個(gè)語(yǔ)法,但是它們的用途卻截然不同的。

  • require.ensure 的出現(xiàn)是 webpack 的產(chǎn)物,它是因?yàn)闉g覽器需要一種異步的機(jī)制可以用來(lái)異步加載模塊,從而減少初始的加載文件的體積,所以如果在服務(wù)端的話 require.ensure 就無(wú)用武之地了,因?yàn)榉?wù)端不存在異步加載模塊的情況,模塊同步進(jìn)行加載就可以滿足使用場(chǎng)景了。 CommonJS 模塊可以在運(yùn)行時(shí)確認(rèn)模塊加載。

  • 而 import() 則不同,它主要是為了解決 ES6 模塊無(wú)法在運(yùn)行時(shí)確定模塊的引用關(guān)系,所以需要引入 import()

我們先來(lái)看下它的用法:

  • 動(dòng)態(tài)的 import() 提供一個(gè)基于 Promise 的 API

  • 動(dòng)態(tài)的import() 可以在腳本的任何地方使用

  • import() 接受字符串文字,你可以根據(jù)你的需要構(gòu)造說(shuō)明符

舉個(gè)簡(jiǎn)單的使用例子:

// a.js
const str = './b';
const flag = true;
if(flag) {
  import('./b').then(({foo}) => {
    console.log(foo);
  })
}
import(str).then(({foo}) => {
  console.log(foo);
})

// b.js
export const foo = 'foo';

// babel-node a.js
// 執(zhí)行結(jié)果
// foo
// foo

當(dāng)然,如果在瀏覽器端的 import() 的用途就會(huì)變得更廣泛,比如 按需異步加載模塊,那么就和 require.ensure 功能類似了。

因?yàn)槭腔?Promise 的,所以如果你想要同時(shí)加載多個(gè)模塊的話,可以是 Promise.all 進(jìn)行并行異步加載。

Promise.all([
  import('./a.js'),
  import('./b.js'),
  import('./c.js'),
]).then(([a, {default: b}, {c}]) => {
    console.log('a.js is loaded dynamically');
    console.log('b.js is loaded dynamically');
    console.log('c.js is loaded dynamically');
});

還有 Promise.race 方法,它檢查哪個(gè) Promise 被首先 resolved 或 reject。我們可以使用import()來(lái)檢查哪個(gè)cdn速度更快:

const CDNS = [
  {
    name: 'jQuery.com',
    url: 'https://code.jquery.com/jquery-3.1.1.min.js'
  },
  {
    name: 'googleapis.com',
    url: 'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js'
  }
];

console.log(`------`);
console.log(`jQuery is: ${window.jQuery}`);

Promise.race([
  import(CDNs[0].url).then(()=>console.log(CDNs[0].name, 'loaded')),
  import(CDNs[1].url).then(()=>console.log(CDNs[1].name, 'loaded'))
]).then(()=> {
  console.log(`jQuery version: ${window.jQuery.fn.jquery}`);
});

當(dāng)然,如果你覺(jué)得這樣寫還不夠優(yōu)雅,也可以結(jié)合 async/await 語(yǔ)法糖來(lái)使用。

async function main() {
  const myModule = await import('./myModule.js');
  const {export1, export2} = await import('./myModule.js');
  const [module1, module2, module3] =
    await Promise.all([
      import('./module1.js'),
      import('./module2.js'),
      import('./module3.js'),
    ]);
}

動(dòng)態(tài) import() 為我們提供了以異步方式使用 ES 模塊的額外功能。 根據(jù)我們的需求動(dòng)態(tài)或有條件地加載它們,這使我們能夠更快,更好地創(chuàng)建更多優(yōu)勢(shì)應(yīng)用程序。

export

一個(gè)模塊就是一個(gè)獨(dú)立的文件。該文件內(nèi)部的所有變量,外部無(wú)法獲取。如果希望外部文件能夠讀取該模塊的變量,就需要在這個(gè)模塊內(nèi)使用export關(guān)鍵字導(dǎo)出變量。如:

// profile.jsexport var a = 1;export var b = 2;export var c = 3;1234

下面的寫法是等價(jià)的,這種方式更加清晰(在底部一眼能看出導(dǎo)出了哪些變量):

var a = 1;var b = 2;var c = 3;
export {a, b, c}1234

import

import命令可以導(dǎo)入其他模塊通過(guò)export導(dǎo)出的部分。

var a = 1;var b = 2;var c = 3;
export {a, b, c}
//main.js
import {a, b, c} from './abc';
console.log(a, b, c);

如果想為導(dǎo)入的變量重新取一個(gè)名字,使用as關(guān)鍵字(也可以在導(dǎo)出中使用)。

import {a as aa, b, c};
console.log(aa, b, c)12

如果想在一個(gè)模塊中先輸入后輸出一個(gè)模塊,import語(yǔ)句可以和export語(yǔ)句寫在一起。

import {a, b, c} form './abc';export {a, b,  c}// 使用連寫, 可讀性不好,不建議export {a, b, c} from './abc';12345

模塊的整體加載

使用*關(guān)鍵字。

import * from as abc form './abc';

export default

在export輸出內(nèi)容時(shí),如果同時(shí)輸出多個(gè)變量,需要使用大括號(hào){},同時(shí)導(dǎo)入也需要大括號(hào)。使用export defalut輸出時(shí),不需要大括號(hào),而輸入(import)export default輸出的變量時(shí),不需要大括號(hào)。

// abc.jsvar a = 1, b = 2, c = 3;export {a, b};export default c;1234
import {a, b} from './abc';
import c from './abc'; // 不需要大括號(hào)console.log(a, b, c) // 1 2 3123

本質(zhì)上,export default輸出的是一個(gè)叫做default的變量或方法,輸入這個(gè)default變量時(shí)不需要大括號(hào)。

// abc.js
export {a as default};

// main.js
import a from './abc'; // 這樣也是可以的
import {default as aa} from './abc'; // 這樣也是可以的
console.log(aa);123456789

就到這里了吧。關(guān)于循環(huán)加載(模塊相互依賴)沒(méi)寫,CommonJS和ES6處理方式不一樣。

參考文章:

  • javascript模塊化之CommonJS、AMD、CMD、UMD、ES6

  • 深入理解 ES6 模塊機(jī)制

  • 該如何理解AMD ,CMD,CommonJS規(guī)范–javascript模塊化加載學(xué)習(xí)總結(jié)

  • AMD/CMD與前端規(guī)范

  • 前端模塊化之旅(二):CommonJS、AMD和CMD

  • 研究一下javascript的模塊規(guī)范(CommonJs/AMD/CMD)

  • Javascript模塊化編程(一):模塊的寫法

  • Javascript模塊化編程(二):AMD規(guī)范

  • Javascript模塊化編程(三):require.js的用法

  • Module

轉(zhuǎn)載請(qǐng)注明來(lái)源,再嘮叨JS模塊化加載之CommonJS、AMD、CMD、ES6 - javascript入門容易深入難,民工看似康莊大道卻是陷阱遍地 - 周陸軍的個(gè)人網(wǎng)站:https://www.zhoulujun.cn/html/webfront/ECMAScript/js/2016_0203_528.html

文有不妥之處,望告之,謝謝

本文名稱:再嘮叨JS模塊化加載之CommonJS、AMD、CMD、ES6
本文路徑:http://www.rwnh.cn/article24/jgpice.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)網(wǎng)站維護(hù)、外貿(mào)網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)
望谟县| 邻水| 沈丘县| 莱州市| 柳州市| 延庆县| 金平| 宁夏| 江川县| 姚安县| 厦门市| 鲁山县| 天津市| 玛多县| 搜索| 溧水县| 夹江县| 钟山县| 肃南| 吴江市| 连城县| 阿城市| 白河县| 酒泉市| 关岭| 山西省| 漳浦县| 廊坊市| 拜城县| 连平县| 汽车| 彝良县| 阳谷县| 黔西县| 巴马| 延庆县| 阿鲁科尔沁旗| 南和县| 新民市| 商水县| 明水县|