前端模組化

2022-07-09 01:57:12 字數 3089 閱讀 2500

最近在看一些前端工程化知識,總結模組化相關而成此篇,其中僅詳細介紹commonjs和es6 modules

原始模組化

commonjs

cmdumd

es6 modules

模組輸出

commonjs輸出的是乙個值的拷貝,es6 模組輸出的是值的引用。

commonjs輸出的是乙個值的拷貝意味著,在commonjs匯出生成之後,再修改原模組中的值無法改變匯出物件的值

// lib/counter.js

var counter = 1;

function increment()

function decrement()

module.exports = ;

// src/main.js

var counter = require('../../lib/counter');

counter.increment();

console.log(counter.counter); // 1

es6 modules 輸出值的引用意味著,你仍可以通過修改原模組的值來修改匯出模組的值

// lib/counter.js

exportlet counter = 1;

exportfunction increment()

exportfunction decrement()

// src/main.js

import * as counter from'../../counter';

console.log(counter.counter); // 1

counter.increment();

console.log(counter.counter); // 2

載入時機

因為 commonjs 載入的是乙個物件(module.exports),物件只有在有指令碼執行的時候才能生成。而 es6 模組不是乙個物件,只是乙個靜態的定義。在**解析階段就會生成。

es6 模組是編譯時輸出介面,因此有如下2個特點:

// a.js

console.log('a.js')

import from'./b';

// b.js

exportlet foo = 1;

console.log('b.js 先執行');

// 執行結果:

// b.js 先執行

// a.js

迴圈載入的差異

在 commonjs 中,指令碼**在 require 的時候,就會全部執行。一旦出現某個模組被"迴圈載入",就只輸出已經執行的部分,還未執行的部分不會輸出。

es6 處理「迴圈載入」與 commonjs 有本質的不同。es6 模組是動態引用,如果使用import從乙個模組載入變數(即import foo from 'foo'),那些變數不會被快取,而是成為乙個指向被載入模組的引用,需要開發者自己保證,真正取值的時候能夠取到值。

commonjs:

// a.js

exports.done = false;

var b = require('./b.js');

console.log('在 a.js 之中,b.done = %j', b.done);

exports.done = true;

console.log('a.js 執行完畢');

// b.js

exports.done = false;

var a = require('./a.js');

console.log('在 b.js 之中,a.done = %j', a.done);

exports.done = true;

console.log('b.js 執行完畢');

// main.js

var a = require('./a.js');

var b = require('./b.js');

console.log('在 main.js 之中, a.done=%j, b.done=%j', a.done, b.done);

//輸出結果

在 b.js 之中,a.done = false

b.js 執行完畢

在 a.js 之中,b.done = true

a.js 執行完畢

在 main.js 之中, a.done=true, b.done=true

從上面我們可以看出:

在b.js之中,a.js沒有執行完畢,只執行了第一行。

main.js執行到第二行時,不會再次執行b.js,而是輸出快取的b.js的執行結果,即它的第四行

es6 modules:

// a.mjs

import from'./b';

console.log('a.mjs');

console.log(bar);

exportlet foo = 'foo';

// b.mjs

import from'./a';

console.log('b.mjs');

console.log(foo);

exportlet bar = 'bar';

//執行結果

b.mjs

referenceerror: foo is not defined

具體的執行結果如下:

執行a.mjs以後,引擎發現它載入了b.mjs,因此會優先執行b.mjs,然後再執行a.mjs

執行b.mjs的時候,已知它從a.mjs輸入了foo介面,這時不會去執行a.mjs,而是認為這個介面已經存在了,繼續往下執行。

執行到第三行console.log(foo)的時候,才發現這個介面根本沒定義,因此報錯。

意思是,已載入過的(即使沒載入完),就會認為其已載入完,並呼叫模組輸出的引用拷貝

前端模組化

前端模組化解決什麼問題?有了模組,我就可以很方便的使用別人的 想要什麼功能,就用載入什麼模組。但是,這樣做需要有乙個前提,那就是大家必須以同樣的方式編寫模組,否則就亂套了。所以組內需要有一套統一的模組規範。如何實現模組?1 物件字面量的變體 2 js設計模式的模組模式 3 採用成熟的庫檔案。前兩種方...

前端模組化

定義 具有相同屬性和行為的事物的集合 在前端中 將一些屬性比較類似和行為比較類似的內容放在同乙個js檔案裡面,把這個js檔案稱為模組 目的 為了每個js檔案只關注與自身有關的事情,讓每個js檔案各行其職 模組化 指的就是遵守commonjs規範,解決不同js模組之間相互呼叫問題 commonjs a...

前端模組化

當多人開發同一專案時,很容易就會產生命名衝突的問題,尤其是js檔案,任何的js引入順序的打亂都可能導致專案執行失敗,為了解決命名衝突的問題,在es6之前,可以使用函式閉包來解決這個問題。即可能像這樣 function 這樣雖然可以解決命名衝突的問題,但也使得 的復用性變得極差,因為其它的檔案將無法再...