柚子快報邀請碼778899分享:前端 速通JS模塊化規(guī)范
柚子快報邀請碼778899分享:前端 速通JS模塊化規(guī)范
目錄
1模塊化概述
1.1什么是模塊化?
1.2為什么需要模塊化?
2有哪些模塊化規(guī)范?
3導(dǎo)入與導(dǎo)出的概念
4CommonJS 規(guī)范
4.1初步體驗
4.2導(dǎo)出數(shù)據(jù)
4.3導(dǎo)入數(shù)據(jù)
4.4擴(kuò)展理解
4.5瀏覽器端運(yùn)行
5ES6 模塊化規(guī)范
5.1初步體驗
5.2Node 中運(yùn)行 ES6 模塊、
.3導(dǎo)出數(shù)據(jù)
5.4導(dǎo)入數(shù)據(jù)
5.5數(shù)據(jù)引用問題
?6AMD 模塊化規(guī)范(了解)
6.1環(huán)境準(zhǔn)備、
6.2導(dǎo)出數(shù)據(jù)
6.3導(dǎo)入數(shù)據(jù)
6.4使用模塊
7CMD 模塊化規(guī)范(了解)
7.1環(huán)境準(zhǔn)備
?7.2導(dǎo)出數(shù)據(jù)
7.3導(dǎo)入數(shù)據(jù)
7.4使用模塊
1模塊化概述
1.1什么是模塊化?
●將程序文件依據(jù)一定規(guī)則拆分成多個文件,這種編碼方式就是模塊化的編碼方式?!癫鸱殖鰜砻總€文件就是一個模塊,模塊中的數(shù)據(jù)都是私有的,模塊之間互相隔離?!裢瑫r也能通過一些手段,可以把模塊內(nèi)的指定數(shù)據(jù)“交出去”,供其他模塊使用。
1.2為什么需要模塊化?
隨著應(yīng)用的復(fù)雜度越來越高,其代碼量和文件數(shù)量都會急劇增加,會逐漸引發(fā)以下問題:
1全局污染問題2依賴混亂問題3數(shù)據(jù)安全問題
2有哪些模塊化規(guī)范?
歷史背景(了解即可):2009 年,隨著 Node.js 的出現(xiàn),JavaScript 在服務(wù)器端的應(yīng)用逐漸增多,為了讓 Node.js 的代碼更好維護(hù),就必須要制定一種 Node.js 環(huán)境下的模塊化規(guī)范,來自 Mozilla 的工程師 Kevin Dangoor 提出了 CommonJS 規(guī)范(CommonJS 初期的名字叫 ServerJS),隨后 Node.js 社區(qū)采納了這一規(guī)范。
隨著時間的推移,針對 JavaScript 的不同運(yùn)行環(huán)境,相繼出現(xiàn)了多種模塊化規(guī)范,按時間排序,分別為:?
1CommonJS —— 服務(wù)端應(yīng)用廣泛
2AMD
3CMD
4ES6 模塊化 —— 瀏覽器端應(yīng)用廣泛
3導(dǎo)入與導(dǎo)出的概念
模塊化的核心思想就是:模塊之間是隔離的,通過導(dǎo)入和導(dǎo)出進(jìn)行數(shù)據(jù)和功能的共享。
●導(dǎo)出(暴露):模塊公開其內(nèi)部的一部分(如變量、函數(shù)等),使這些內(nèi)容可以被其他模塊使用。
●導(dǎo)入(引入):模塊引入和使用其他模塊導(dǎo)出的內(nèi)容,以重用代碼和功能。 ?
4CommonJS 規(guī)范
4.1初步體驗
1.「創(chuàng)建 school.js」?
const name = '尚硅谷'
const slogan = '讓天下沒有難學(xué)的技術(shù)!'
function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武漢','西安']
}
// 通過給exports對象添加屬性的方式,來導(dǎo)出數(shù)據(jù)(注意:此處沒有導(dǎo)出getCities)
exports.name = name
exports.slogan = slogan
exports.getTel = getTel
2.「創(chuàng)建 student.js」
const name = '張三'
const motto = '相信明天會更好!'
function getTel (){
return '13877889900'
}
function getHobby(){
return ['抽煙','喝酒','燙頭']
}
// 通過給exports對象添加屬性的方式,來導(dǎo)出數(shù)據(jù)(注意:此處沒有導(dǎo)出getHobby)
exports.name = name
exports.slogan = slogan
exports.getTel = getTel
3.「創(chuàng)建 index.js」
// 引入school模塊暴露的所有內(nèi)容
const school = require('./school')
// 引入student模塊暴露的所有內(nèi)容
const student = require('./student')
4.2導(dǎo)出數(shù)據(jù)
在 CommonJS 標(biāo)準(zhǔn)中,導(dǎo)出數(shù)據(jù)有兩種方式:
●第一種方式:module.exports = value●第二種方式:exports.name = value ?
注意點(diǎn)如下:
1每個模塊內(nèi)部的:this、exports、modules.exports在初始時,都指向同一個空對象,該空對象就是當(dāng)前模塊導(dǎo)出的數(shù)據(jù),如下圖:?
2無論如何修改導(dǎo)出對象,最終導(dǎo)出的都是module.exports的值。
3exports是對module.exports的初始引用,僅為了方便給導(dǎo)出象添加屬性,所以不能使用 exports = value的形式導(dǎo)出數(shù)據(jù),但是可以使用module.exports = xxxx導(dǎo)出數(shù)據(jù)
4.3導(dǎo)入數(shù)據(jù)
在CJS模塊化標(biāo)準(zhǔn)中,使用內(nèi)置的require函數(shù)進(jìn)行導(dǎo)入數(shù)據(jù)?
// 直接引入模塊
const school = require('./school')
// 引入同時解構(gòu)出要用的數(shù)據(jù)
const { name, slogan, getTel } = require('./school')
// 引入同時解構(gòu)+重命名
const {name:stuName,motto,getTel:stuTel} = require('./student')
4.4擴(kuò)展理解
一個 JS 模塊在執(zhí)行時,是被包裹在一個內(nèi)置函數(shù)中執(zhí)行的,所以每個模塊都有自己的作用域,我們可以通過如下方式驗證這一說法:
console.log(arguments)
console.log(arguments.callee.toString())
內(nèi)置函數(shù)的大致形式如下:
function (exports, require, module, __filename, __dirname){
/*********************/
}
4.5瀏覽器端運(yùn)行
Node.js 默認(rèn)是支持 CommonJS 規(guī)范的,但瀏覽器端不支持,所以需要經(jīng)過編譯,步驟如下: ●第一步:全局安裝 browserify :npm i browserify -g ●第二步:編譯
browserify index.js -o build.js
備注:index.js 是源文件,build.js 是輸出的目標(biāo)文件
●第三步:頁面中引入使用 ?
5ES6 模塊化規(guī)范
ES6 模塊化規(guī)范是一個官方標(biāo)準(zhǔn)的規(guī)范,它是在語言標(biāo)準(zhǔn)的層面上實現(xiàn)了模塊化功能,是目前最流行的模塊化規(guī)范,且瀏覽器與服務(wù)端均支持該規(guī)范。
5.1初步體驗 ?
1.「創(chuàng)建 school.js」
// 導(dǎo)出name
export let name = {str:'尚硅谷'}
// 導(dǎo)出slogan
export const slogan = '讓天下沒有難學(xué)的技術(shù)!'
// 導(dǎo)出name
export function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武漢','西安']
}
2.「創(chuàng)建 student.js」
// 導(dǎo)出name
export const name = '張三'
// 導(dǎo)出motto
export const motto = '相信明天會更好!'
// 導(dǎo)出getTel
export function getTel (){
return '13877889900'
}
function getHobby(){
return ['抽煙','喝酒','燙頭']
}
4.「頁面中引入 index.js」
5.2Node 中運(yùn)行 ES6 模塊、
Node.js中運(yùn)行ES6模塊代碼有兩種方式:
●方式一:將JavaScript文件后綴從.js 改為.mjs,Node 則會自動識別 ES6 模塊。
●方式二:在package.json中設(shè)置type屬性值為module
.3導(dǎo)出數(shù)據(jù)
ES6 模塊化提供 3 種導(dǎo)出方式:①分別導(dǎo)出、②統(tǒng)一導(dǎo)出、③默認(rèn)導(dǎo)出 1.「分別導(dǎo)出」
備注:在上方【初步體驗中】環(huán)節(jié),我們使用的導(dǎo)出方式就是【分別導(dǎo)出】
// 導(dǎo)出name
export let name = {str:'尚硅谷'}
// 導(dǎo)出slogan
export const slogan = '讓天下沒有難學(xué)的技術(shù)!'
// 導(dǎo)出getTel
export function getTel (){
return '010-56253825'
}
?2.「統(tǒng)一導(dǎo)出」
const name = {str:'尚硅谷'}
const slogan = '讓天下沒有難學(xué)的技術(shù)!'
function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武漢','西安']
}
// 統(tǒng)一導(dǎo)出了:name,slogan,getTel
export {name,slogan,getTel}
3.「默認(rèn)導(dǎo)出」
const name = '張三'
const motto = '走自己的路,讓別人五路可走!'
function getTel (){
return '13877889900'
}
function getHobby(){
return ['抽煙','喝酒','燙頭']
}
//默認(rèn)導(dǎo)出:name,motto,getTel
export default {name,motto,getTel}
備注 :「上述多種導(dǎo)出方式,可以同時使用」
// 導(dǎo)出name ———— 分別導(dǎo)出
export const name = {str:'尚硅谷'}
const slogan = '讓天下沒有難學(xué)的技術(shù)!'
function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武漢','西安']
}
// 導(dǎo)出slogan ———— 統(tǒng)一導(dǎo)出
export {slogan}
// 導(dǎo)出getTel ———— 默認(rèn)導(dǎo)出
export default getTel
5.4導(dǎo)入數(shù)據(jù)
對于 ES6 模塊化來說,使用何種導(dǎo)入方式,要根據(jù)導(dǎo)出方式?jīng)Q定。 1.「導(dǎo)入全部」(通用) 可以將模塊中的所有導(dǎo)出內(nèi)容整合到一個對象中
import * as school from './school.js'
2.「命名導(dǎo)入」(對應(yīng)導(dǎo)出方式:分別導(dǎo)出、統(tǒng)一導(dǎo)出) 導(dǎo)出數(shù)據(jù)的模塊
//分別導(dǎo)出
export const name = {str:'尚硅谷'}
//分別導(dǎo)出
export const slogan = '讓天下沒有難學(xué)的技術(shù)!'
function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武漢','西安']
}
//統(tǒng)一導(dǎo)出
export { getTel }
命名導(dǎo)入: ?
import { name,slogan,getTel } from './school.js'
通過as重命名:
import { name as myName,slogan,getTel } from './school.js'
3.「默認(rèn)導(dǎo)入」(對應(yīng)導(dǎo)出方式:默認(rèn)導(dǎo)出) 導(dǎo)出數(shù)據(jù)的模塊
const name = '張三'
const motto = '走自己的路,讓別人五路可走!'
function getTel (){
return '13877889900'
}
function getHobby(){
return ['抽煙','喝酒','燙頭']
}
//使用默認(rèn)導(dǎo)出的方式,導(dǎo)出一個對象,對象中包含著數(shù)據(jù)
export default { name,motto,getTel }
默認(rèn)導(dǎo)入:
import student from './student.js' //默認(rèn)導(dǎo)出的名字可以修改,不是必須為student
4.「命名導(dǎo)入 與 默認(rèn)導(dǎo)入可以混合使用」 導(dǎo)出數(shù)據(jù)的模塊
//分別導(dǎo)出
export const name = {str:'尚硅谷'}
//分別導(dǎo)出
export const slogan = '讓天下沒有難學(xué)的技術(shù)!'
function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武漢','西安']
}
//統(tǒng)一導(dǎo)出
export default getTel
「命名導(dǎo)入」與「默認(rèn)導(dǎo)入」混合使用,且默認(rèn)導(dǎo)入的內(nèi)容必須放在前方:
import getTel,{name,slogan} from './school.js'
5.「動態(tài)導(dǎo)入」(通用) 允許在運(yùn)行時按需加載模塊,返回值是一個 Promise。
const school = await import('./school.js');
console.log(school)
6. import 可以不接收任何數(shù)據(jù) 例如只是讓 mock.js 參與運(yùn)行 ?
import './mock.js'
此時,我們感受到模塊化確實解決了:①全局污染問題、②依賴混亂問題、③數(shù)據(jù)安全問題。
5.5數(shù)據(jù)引用問題
思考1: 如下代碼的輸出結(jié)果是什么?(不要想太多,不涉及模塊化相關(guān)知識)
function count (){
let sum = 1
function increment(){
sum += 1
}
return {sum,increment}
}
const {sum,increment} = count()
console.log(sum)
increment()
increment()
console.log(sum)
?思考2:使用 CommonJS 規(guī)范,編寫如下代碼,輸出結(jié)果是什么
let sum = 1
function increment (){
sum += 1
}
module.exports = {sum,increment}
const {sum,increment} = require('./count.js')
console.log(sum)
increment()
increment()
console.log(sum)
思考3:使用 ES6 模塊化規(guī)范,編寫如下代碼,輸出結(jié)果是什么?
let sum = 1
function increment(){
sum += 1
}
export {sum,increment}
import {sum,increment} from './count.js'
console.log(sum) //1
increment()
increment()
console.log(sum) //3
使用原則:導(dǎo)出的常量,務(wù)必用const定義
?6AMD 模塊化規(guī)范(了解)
6.1環(huán)境準(zhǔn)備、
第一步:準(zhǔn)備文件結(jié)構(gòu):
文件說明: 1js 文件夾中存放業(yè)務(wù)邏輯代碼,main.js用于匯總各模塊。 2libs 中存放的是第三方庫,例如必須要用的require.js。?
require.jshttps://www.yuque.com/preview/yuque/0/2024/js/35780599/1721441912143-417162f8-5c6d-4d5d-84dd-655fdf5a5dbd.js?from=https%3A%2F%2Fwww.yuque.com%2Ftianyu-coder%2Fopenshare%2Fhycdb5tispao428h
第二步:在index.html中配置main.js與require.js
?第三步:在main.js中編寫模塊配置對象,注冊所有模塊。
/*AMD_require.js模塊化的入口文件,要編寫配置對象,并且有固定的寫法*/
requirejs.config({
//基本路徑
baseUrl: "./js",
//模塊標(biāo)識名與模塊路徑映射
paths: {
school: "school",
student: "student",
welcome: "welcome",
}
})
6.2導(dǎo)出數(shù)據(jù)
AMD 規(guī)范使用define函數(shù)來定義模塊和導(dǎo)出數(shù)據(jù)
define(function(){
const name = '張三'
const motto = '走自己的路,讓別人五路可走!'
function getTel (){
return '13877889900'
}
function getHobby(){
return ['抽煙','喝酒','燙頭']
}
// 導(dǎo)出數(shù)據(jù)
return {name,motto,getTel}
})
6.3導(dǎo)入數(shù)據(jù)
如需導(dǎo)入數(shù)據(jù),則需要define傳入兩個參數(shù),分別為:依賴項數(shù)組、回調(diào)函數(shù)
// ['welcome']表示當(dāng)前模塊要依賴的模塊名字
// 回調(diào)接收到的welcome是模塊導(dǎo)出的數(shù)據(jù)
define(['welcome'],function(welcome){
let name = {str:'尚硅谷'}
const slogan = '讓天下沒有難學(xué)的技術(shù)!'+ welcome
function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武漢','西安']
}
// 導(dǎo)出數(shù)據(jù)
return {name,slogan,getTel}
})
6.4使用模塊
requirejs(['school','student'],function(school,student){
console.log('main',school)
console.log('main',student)
})
7CMD 模塊化規(guī)范(了解)
7.1環(huán)境準(zhǔn)備
第一步:準(zhǔn)備環(huán)境
文件說明: 1js 文件夾中存放業(yè)務(wù)邏輯代碼,main.js用于匯總各模塊。 2libs 中存放的是第三方庫,例如必須要用的sea.js。
sea.jshttps://www.yuque.com/preview/yuque/0/2024/js/35780599/1721444843940-bccc76da-f4e5-47e1-b19a-23bf954ac71b.js?from=https%3A%2F%2Fwww.yuque.com%2Ftianyu-coder%2Fopenshare%2Fhycdb5tispao428h
?
第二步:在index.html中配置main.js與sea.js
?7.2導(dǎo)出數(shù)據(jù)
CMD 中同樣使用define函數(shù)定義模塊并導(dǎo)出數(shù)據(jù)
/*
收到的三個參數(shù)分別為:require、exports、module
1. require用于引入其他模塊
2. exports、module用于導(dǎo)出數(shù)據(jù)
*/
define(function(require,exports,module){
const name = '尚硅谷'
const slogan = '讓天下沒有難學(xué)的技術(shù)!'
function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武漢','西安']
}
// 導(dǎo)出數(shù)據(jù)
module.exports = {name,slogan,getTel}
})
7.3導(dǎo)入數(shù)據(jù)
CMD 規(guī)范中使用收到的require參數(shù)進(jìn)行模塊導(dǎo)入
define(function(require,exports,module){
const name = '張三'
const motto = '相信明天會更好!'
// 引入welcome模塊
const welcome = require('./welcome')
console.log(welcome)
function getTel (){
return '13877889900'
}
function getHobby(){
return ['抽煙','喝酒','燙頭']
}
exports.name = name
exports.motto = motto
exports.getTel = getTel
})
7.4使用模塊
define(function(require){
const school = require('./school')
const student = require('./student')
// 使用模塊
console.log(school)
console.log(student)
})
柚子快報邀請碼778899分享:前端 速通JS模塊化規(guī)范
精彩文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。