寫在前面
在之前的 JS模塊化的各種規(guī)范 之 CJS、AMD、CMD、UMD、ESM 文章中,介紹了關(guān)于JS模塊化的各種規(guī)范的區(qū)別和簡(jiǎn)單使用。
由于ESM模塊規(guī)范也是 ECMAScript2015(ES6)中的規(guī)范標(biāo)準(zhǔn),在日常的Web項(xiàng)目開發(fā)、小程序開發(fā)、APP開發(fā)等都是很常用的,所以本文重點(diǎn)將 ESM模塊規(guī)范中的 導(dǎo)出、導(dǎo)入、導(dǎo)出、引用、調(diào)用等,結(jié)合日常開發(fā)需求做進(jìn)一步的介紹。
實(shí)例代碼
這里分別以不同的實(shí)例代碼,逐步介紹ESM模塊規(guī)范的導(dǎo)出、 導(dǎo)入、引用、調(diào)用等使用方法。
1、模塊導(dǎo)出 - export
模塊導(dǎo)出 就是將js文件中的 變量、常量、函數(shù)、對(duì)象、類 等對(duì)象 向外導(dǎo)出(暴露)以方便外部的js文件所引用和調(diào)用。
在JS的ESM模塊規(guī)范中,主要通過 export 關(guān)鍵字 來 向外導(dǎo)出想要導(dǎo)出(暴露)的對(duì)象。
導(dǎo)出之 - 獨(dú)立導(dǎo)出
獨(dú)立導(dǎo)出方式,是直接在要向外導(dǎo)出(暴露)變量、常量、函數(shù)、對(duì)象、類 等對(duì)象的對(duì)面加上 export 關(guān)鍵字即可!
export let count = 666;
export const PI = Math.PI;
const random = Math.random();
export { random as default };
export const sum = (n1, n2) => {
return n1 + n2;
};
export function isOdd(n) {
return n % 2 === 1 || n % 2 === -1;
};
export class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Hello! 我是${this.name}`);
}
};
導(dǎo)出之 - 集中多個(gè)導(dǎo)出
集中多個(gè)導(dǎo)出方式,一般是在代碼的最底部,將要向外導(dǎo)出(暴露)變量、常量、函數(shù)、對(duì)象、類等對(duì)象,通過 export export default 以對(duì)象的形式導(dǎo)出!
let count = 666;
const PI = Math.PI;
const sum = (n1, n2) => {
return n1 + n2;
};
function isOdd(n) {
return n % 2 === 1 || n % 2 === -1;
};
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Hello! 我是${this.name}`);
}
};
// 集中多個(gè)導(dǎo)出
export {
count, // 注:如果對(duì)象中的 鍵key 和 值value 的命名完全相同 可省去 :random 后面這部分!!
PI,
sum,
isOdd,
Person
};
導(dǎo)出之 - 默認(rèn)導(dǎo)出
默認(rèn)導(dǎo)出方式,是使用 export default 關(guān)鍵字 直接導(dǎo)出,該導(dǎo)出方式只能導(dǎo)出單個(gè)內(nèi)容。
// 可直接向外導(dǎo)出(暴露)變量、常量、函數(shù)、對(duì)象、類等對(duì)象
export default function sayHello(name) {
console.log(`Hello! 我是${name}`);
};
- 注意:export default 默認(rèn)導(dǎo)出 在一個(gè)js模塊文件中,不能同時(shí)存在多個(gè)默認(rèn)導(dǎo)出(也就是說,在一個(gè)js模塊文件中 export default 能只出現(xiàn)一次?。。。?/strong>
導(dǎo)出之 - 集中默認(rèn)導(dǎo)出
集中默認(rèn)導(dǎo)出方式,是使用 export default 關(guān)鍵字 以對(duì)象形式導(dǎo)出,該導(dǎo)出方式可以同時(shí)導(dǎo)出多個(gè)內(nèi)容。
const PI = Math.PI
function isOdd(n) {
return n % 2 === 1 || n % 2 === -1;
};
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Hello! 我是${this.name}`);
}
};
export default {
count: 666,
PI,
sum: (n1, n2) => {
return n1 + n2;
},
isOdd,
Person,
sayHello: function (name = '') {
console.log(`Hello! 我是${name}`);
},
};
導(dǎo)出之 - 混合導(dǎo)出
混合導(dǎo)出方式,就是 在一個(gè)JS模塊文件中,既有獨(dú)立導(dǎo)出、集中導(dǎo)出 又有 默認(rèn)導(dǎo)出、集中默認(rèn)導(dǎo)出等形式一起組合導(dǎo)出。
??下面混合導(dǎo)出的代碼內(nèi)容 以 demo.js 文件命名,為接下來的模塊 導(dǎo)入、引用、調(diào)用實(shí)例做演示用!!
/**
* demo.js
*/
let count = 666;
// 獨(dú)立導(dǎo)出 常量
export const PI = Math.PI;
const sum = (n1, n2) => {
return n1 + n2;
};
// 獨(dú)立導(dǎo)出 函數(shù)
export function isOdd(n) {
return n % 2 === 1 || n % 2 === -1;
};
// 獨(dú)立導(dǎo)出 類
export class Person {
constructor(name = '') {
this.name = name;
}
sayHello() {
console.log(`Hello! 我是${this.name}`);
}
};
// 默認(rèn)導(dǎo)出
export default {
// 默認(rèn)導(dǎo)出 變量
count: count,
// 默認(rèn)導(dǎo)出 函數(shù)
sum,
// 默認(rèn)導(dǎo)出 類
Person,
// 默認(rèn)導(dǎo)出 字符變量 (可直接創(chuàng)建 并 導(dǎo)出[ 變量、常量、函數(shù)、對(duì)象、類] 等對(duì)象)
pi: '3.141592653589793',
// 默認(rèn)導(dǎo)出 函數(shù) 方式1
is: function (val, type) {
return toString.call(val) === `[object ${type}]`;
},
// 默認(rèn)導(dǎo)出 函數(shù) 方式2
isArray: (arr = []) => {
return Object.prototype.toString.call(arr) === '[object Array]' || Array.isArray(arr);
},
// 默認(rèn)導(dǎo)出 函數(shù) 方式3
isObject(val) {
// 注:在這里還可以通過 this關(guān)鍵字 來調(diào)用當(dāng)前默認(rèn)導(dǎo)出模塊中的 其他導(dǎo)出屬性內(nèi)容
// 如 this.pi; this.sum(1, 2);
return val !== null && this.is(val, 'Object') || (typeof val === 'object' && val !== null);
},
// 默認(rèn)導(dǎo)出 類
AudioTrack: class {
constructor(trackId = '', trackName = '', trackUrl = 'https://') {
this.trackId = trackId;
this.trackName = trackName;
this.trackUrl = trackUrl;
};
start() {
console.log(`開始播放${this.trackName}`);
};
stop() {
console.log(`停止播放${this.trackName}`);
};
}
};
2、模塊導(dǎo)入 - import
在JS的ESM模塊規(guī)范中,
當(dāng)通過 export 關(guān)鍵字 來 向外導(dǎo)出想要導(dǎo)出(暴露)對(duì)象以后,
就可以通 import 關(guān)鍵字 來 導(dǎo)入 對(duì)應(yīng)的(注:要一一對(duì)應(yīng)) 導(dǎo)出內(nèi)容。
導(dǎo)入之 - 全部導(dǎo)入
全部導(dǎo)入方式,使用 ?星號(hào) 將模塊文件中所有的import 獨(dú)立導(dǎo)出、export default 默認(rèn)導(dǎo)出 等導(dǎo)出的內(nèi)容全部導(dǎo)入進(jìn)來。
import * as all from "./demo.js";
// 注:通過export default 關(guān)鍵 默認(rèn)導(dǎo)出(暴露)的內(nèi)容在default屬性中,和export獨(dú)立導(dǎo)出的在同一級(jí)上?。?/span>
console.log('demo.js模塊 所有導(dǎo)出的內(nèi)容:', all);
導(dǎo)入之 - 默認(rèn)導(dǎo)入
默認(rèn)導(dǎo)入方式,只會(huì)將導(dǎo)出文件中通過export default 關(guān)鍵字向外 導(dǎo)出(暴露)的內(nèi)容導(dǎo)入進(jìn)來。
import def from "./demo.js";
// 注:該導(dǎo)入方式只會(huì) export default 關(guān)鍵字向外 導(dǎo)出(暴露)的內(nèi)容導(dǎo)入進(jìn)來!
console.log('demo.js模塊 默認(rèn)導(dǎo)出的內(nèi)容:', def );
導(dǎo)入之 - 指定導(dǎo)入
指定導(dǎo)入方式,是將導(dǎo)出文件中通過export 關(guān)鍵字向外 導(dǎo)出(暴露)的內(nèi)容 根據(jù)指定變量名(不分順序)的導(dǎo)入進(jìn)來。
// 指定將PI, isOdd, Person 導(dǎo)入進(jìn)來
import { PI, isOdd, Person } from "./demo.js";
導(dǎo)入之 - 混合導(dǎo)入
混合導(dǎo)入方式,就是將導(dǎo)出文件中通過export default 關(guān)鍵字 和 export 關(guān)鍵字 向外 導(dǎo)出(暴露)的內(nèi)容 根據(jù)指定變量名(不分順序)的導(dǎo)入進(jìn)來。
// 注:def 接收的就是在導(dǎo)出文件中通過export default 關(guān)鍵字向外導(dǎo)出內(nèi)容,而在大括號(hào){}中接收到在導(dǎo)出文件中通過export關(guān)鍵字向外導(dǎo)出內(nèi)容。
// 注:def 這個(gè)變量名字是可能自定義的。
import def, { PI, isOdd, Person } from "./demo.js";
導(dǎo)入之 - 改名導(dǎo)入
改名導(dǎo)入,是在導(dǎo)入時(shí)的 變量名 和 當(dāng)前文件中的 變量名 有沖突(相同)時(shí),通過 as 關(guān)鍵字 將導(dǎo)入的變量 新更改一下名字,再導(dǎo)入進(jìn)來。
// 將原大寫的PI 更改為 小寫的pi
import def, { PI as pi, isOdd, Person } from "./demo.js";
// 當(dāng)前文件中的 變量名 有沖突
const PI = '3.141592653589793 ';
console.log(PI, pi);
3、模塊導(dǎo)入即導(dǎo)出
模塊導(dǎo)入即導(dǎo)出方式,一般主要是用于,為了盡可能的減少 在各個(gè)JS模塊文件之間出到多次導(dǎo)入問題的。
例如:
在A.js模塊文件中,同時(shí)需要用到B.js模塊文件 和 C.js模塊文件。
而B.js模塊文件中也要用到C.js模塊文件。
此時(shí): 我們可以只需在A.js模塊文件中 導(dǎo)入 B.js模塊文件,然后B.js模塊文件中 導(dǎo)入 C.js模塊文件即可。
導(dǎo)入即導(dǎo)出之 - 所有導(dǎo)入導(dǎo)出
所有導(dǎo)入導(dǎo)出,是將模塊所有的內(nèi)容導(dǎo)入 又 全部導(dǎo)出。
- 這里扮演的B.js模塊文件 向A.js模塊文件 導(dǎo)出C.js模塊文件中的所有導(dǎo)出 。
export * from './demo.js';
導(dǎo)入即導(dǎo)出之 - 默認(rèn)導(dǎo)入導(dǎo)出
默認(rèn)導(dǎo)入導(dǎo)出,是將 demo.js模塊文件中的 export default 默認(rèn)模塊向外導(dǎo)出。
export { default } from './demo.js';
導(dǎo)入即導(dǎo)出之 - 默認(rèn)改名導(dǎo)入導(dǎo)出
將 demo.js模塊文件中的 export default 默認(rèn)模塊改名在MyDemo下向外導(dǎo)出。
export { default as MyDemo } from './demo.js';
導(dǎo)入即導(dǎo)出之 - 指定多個(gè)導(dǎo)入導(dǎo)出
指定多個(gè)導(dǎo)入導(dǎo)出,是將導(dǎo)出文件中通過export 關(guān)鍵字向外 導(dǎo)出(暴露)的內(nèi)容 根據(jù)指定變量名(不分順序)的導(dǎo)入和導(dǎo)出
- 這里扮演的B.js模塊文件 向A.js模塊文件導(dǎo)出PI, random, isOdd,【在A.js模塊文件中,同時(shí)需要用到B.js模塊文件 和 C.js模塊文件】。
export { PI, random, isOdd } from './demo.js';
導(dǎo)入即導(dǎo)出之 - 混合導(dǎo)入即導(dǎo)出
混合導(dǎo)入即導(dǎo)出,就是將 默認(rèn)模塊 和 指定多個(gè)變量一起導(dǎo)出。
// 注:default 是關(guān)鍵字,它裝著在導(dǎo)出模塊文件中通過export default默認(rèn)導(dǎo)出的內(nèi)容。
export { default PI, isOdd, Person } from './demo.js';
// 將 demo.js模塊文件中的 export default 默認(rèn)模塊改名在myDef后向外導(dǎo)出。
export { default as myDef, PI, isOdd, Person } from './demo.js';
4、模塊引用與調(diào)用
在模塊導(dǎo)入以后 引用與調(diào)用,就是在模塊導(dǎo)入以后 就和 我們平時(shí)在一個(gè)js文件中寫代碼一樣去引用和調(diào)用 變量、常量、函數(shù)、對(duì)象、類 等對(duì)象一樣,直接使用即可。
引用與調(diào)用之 - 本地資源加載
在vite + vue3 項(xiàng)目開發(fā)過程,有時(shí)需要在 js 代碼中去加載本地圖片,由于vite默認(rèn)不支持 require()方法,所以我們可以使用 import來加載本地資源,而且 在項(xiàng)目構(gòu)建(打包)后也能正常的顯示資源。文章來源:http://www.zghlxwxcb.cn/news/detail-743050.html
- 注:在下面代碼中, 資源前面的…/assets/ 是根據(jù)當(dāng)前這個(gè)getLocalFile()函數(shù)所在的js文件的相對(duì)路徑,在vue項(xiàng)目中,一般這個(gè)文件是放在src目錄下面的utils文件夾里面,而資產(chǎn)文件則一般是放在src目錄下面的assets文件夾里面,utils 和 assets是同一級(jí)目錄的(都在src目錄下);
function getLocalFile(url) {
return new URL(`../assets/${url}`, import.meta.url).href;
};
getLocalFile('img/logo.jpg');
// ts寫法的簡(jiǎn)寫
const getLocalFile = (url: string): string => new URL(`../assets/${url}`, import.meta.url).href;
getLocalFile('img/logo.jpg');
引用與調(diào)用之 - 異步(按需)加載模塊
模塊異步加載,在一些業(yè)務(wù)場(chǎng)景中是非常有用的,例如:聊天室,在用戶進(jìn)入聊天室之前需要先進(jìn)行登錄后才能進(jìn)入,所以在用戶沒登錄成功以前,WebSocket是不應(yīng)該連接的,需要等到登錄成功以后才連接。文章來源地址http://www.zghlxwxcb.cn/news/detail-743050.html
function load() {
import('./demo.js').then((esm) => {
console.log('esm就是./demo.js模塊文件中所有導(dǎo)出的內(nèi)容:', esm);
console.log(esm.PI);
const def = esm.default;
console.log('esm.default就是./demo.js模塊文件中默認(rèn)導(dǎo)出的內(nèi)容:', def);
def.sum(100, 200);
});
import('./demo.js').then(({ PI, isOdd, Person }) => {
console.log('也可以直接解構(gòu)./demo.js模塊文件分別獨(dú)立導(dǎo)出的內(nèi)容:', PI, isOdd, Person);
isOdd(666);
const p = new Person('沐楓');
p.sayHello();
});
};
// 在用戶點(diǎn)擊以后再去加載 想要引用和調(diào)用的模塊。
btn.onclick = function () {
load();
};
// 注:如果是在html文件中直接使用時(shí),需要在script標(biāo)簽中加上type="module"屬性,并且要在http服務(wù)器環(huán)境中打開才能正常使用哦!!
<script type="module">
import('./demo.js').then((esm) => {
...
});
</script>
到了這里,關(guān)于JS模塊化,ESM模塊規(guī)范的 導(dǎo)入、導(dǎo)出、引用、調(diào)用詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!