国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

了解一下ES module 和 Commonjs

這篇具有很好參考價(jià)值的文章主要介紹了了解一下ES module 和 Commonjs。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

最近測(cè)試了幾個(gè) ES module 和 Commonjs 的例子,理解了之前不太理解的概念,記錄一下。要是想多了解的可以去看看阮老師的 Module 那部分。會(huì)貼一小部分的代碼,不會(huì)貼所有驗(yàn)證的代碼。

Commonjs require 大概流程

本質(zhì)上 Commonjs 一直是 node 在使用的規(guī)范,雖然其他平臺(tái)也可以使用。

  • 處理路徑,node 有專門的 path 模塊和__dirname 等,將路徑轉(zhuǎn)成絕對(duì)路徑,定位目標(biāo)文件
  • 檢查緩存
  • 讀取文件代碼(fs)
  • 包裹一個(gè)函數(shù)并執(zhí)行(自執(zhí)行函數(shù))
  • 緩存
  • 返回 module.exports
ES module 大概流程

最重要的應(yīng)該是解析依賴了,ES module 如果都是同步的,會(huì)很慢。都說(shuō) ES module 是異步的,在不同環(huán)境會(huì)有不同的結(jié)果。其實(shí) ES module 的三個(gè)步驟是可以分開異步進(jìn)行。在瀏覽器,會(huì)使用 HTML 的規(guī)范,最后的實(shí)例化是同步,在 node 環(huán)境,文件都是在本地,同步就顯得很容易。

  • 模塊解析,入口文件開始,構(gòu)建 Module Record,然后放置到 Module Map。Module Map 相當(dāng)于每一個(gè) js 文件,Module Record 相當(dāng)于里面依賴的每一個(gè) import
  • 獲取文件,解析文件,進(jìn)行 JavaScript 的解析,變量提升等
  • 實(shí)例化,執(zhí)行文件內(nèi)容
exports 與 module.exports

Commonjs 可以用 exports.xxx 導(dǎo)出,也可以用 module.exports = {}導(dǎo)出,因?yàn)檎麄€(gè)文件讀取之后會(huì)包裹到一個(gè)自執(zhí)行函數(shù),差不多是這樣:

(function(exports, require, module, filename, dirname){

})(exports, require, module, filename, dirname)

如果直接 exports = {}那么導(dǎo)出是無(wú)效的。下面三個(gè)例子就可以很好的理解:

function fn(obj){
  obj.num = 2;
};
let obj = {
  num: 1;
};
fn(obj);
console.log(obj);


function fn(obj){
  obj = {num: 2};
};
let obj = {
  num: 1;
};
fn(obj);
console.log(obj);


function fn(obj){
  obj = 2;
};
let obj = 1;
fn(obj);
console.log(obj);

對(duì)象是指針的引用,相當(dāng)于 obj = xxxx,用 obj.xx 賦值其實(shí)就是給指針 xxxx 指向的對(duì)象賦值,如果 obj = {},相當(dāng)于 obj 的指針改變了,相當(dāng)于 obj = xx,所以 exports = {}是無(wú)效的。

ES module 是值的引用,Commonjs 是值的拷貝

這塊其實(shí)挺好實(shí)驗(yàn)的,導(dǎo)出一個(gè)變量,調(diào)用函數(shù)改變這個(gè)變量再輸出,可以得到 Commonjs 的值是不會(huì)因?yàn)閳?zhí)行了 add 就改變,ES module 就會(huì):

let a = 10;
exports.a = a;
exports.add = () => {
  a++;
};

let a = 10;
export const b = a;
exports.add = () => {
  a++;
};
ES module 是編譯時(shí)輸出,Commonjs 是運(yùn)行時(shí)加載

運(yùn)行時(shí)加載也比較好實(shí)驗(yàn)(個(gè)人觀點(diǎn)這樣可以表示是運(yùn)行時(shí)加載):

main.js
let a = require('./a.js');
let b = require('./b.js');

a.js
exports.a = 'a';
let b = require('./b.js');
exports.aa = 'aa';

b.js
let a = require('./a.js');
console.log(a,'in b.js');

這樣去執(zhí)行的時(shí)候,b.js 里面的 a 是{a: ‘a(chǎn)’},如果把 exports.aa = ‘a(chǎn)a’;放到 let b = require(‘./b.js’);之前,b.js 里面的 a 是{a: ‘a(chǎn)’, aa: ‘a(chǎn)a’}。

所以 Commonjs 是一邊運(yùn)行一邊加載,當(dāng) a.js 執(zhí)行到 let b = require(‘./b.js’);的時(shí)候,之前的代碼是執(zhí)行過(guò)了,并緩存起來(lái),這時(shí)候就會(huì)去加載 b.js 并執(zhí)行。

ES module 是編譯時(shí)輸出

不太確定是否能這樣理解:

index.js
import {c} from './c.js';


c.js
import n5n3t3z from './d.js';
export let c = 'c';


d.js
import {c} from './c.js';
console.log(c,'in d.js');
export const d = 'd';

得到的結(jié)果會(huì)報(bào)錯(cuò):Cannot access ‘c’ before initialization,如果 let c 改成 var c,結(jié)果是 undefined in d.js。

ES module 會(huì)有一個(gè)跟 JavaScript 解析一樣的過(guò)程,先是解析整個(gè) js,做一些變量提升,然后再執(zhí)行。就是說(shuō)會(huì)先加載所有的文件,并且解析,不會(huì)執(zhí)行,在所有依賴文件加載解析完成,再開始執(zhí)行。所以我是這樣去理解的 ES module 是編譯時(shí)輸出。

ES module 和 Commonjs 循環(huán)引用的區(qū)別

這點(diǎn)其實(shí)挺重要的,ES module 和 Commonjs 都是通過(guò)緩存來(lái)解決循環(huán)引用的問(wèn)題,不會(huì)造成死循環(huán)。Commonjs 是運(yùn)行時(shí)加載,在解析到 require 的時(shí)候,會(huì)先檢查緩存,如果沒(méi)有,會(huì)先進(jìn)行緩存再繼續(xù)往下執(zhí)行:

main.js
require('./a.js');

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

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

result:
b.js {}
a.js { b: 'b' }

大概流程:

  • main.js require(‘./a.js’); 檢查緩存,沒(méi)有 a.js,執(zhí)行 a.js
  • a.js,檢查緩存,沒(méi)有,緩存 a.js。執(zhí)行 let b = require(‘./b.js’);,檢查緩存,沒(méi)有 b.js,執(zhí)行 b.js
  • b.js,檢查緩存,沒(méi)有 b.js,緩存 b.js。執(zhí)行 let a = require(‘./a.js’);,檢查緩存,有 a.js,獲取緩存,打印獲取的緩存,b.js 緩存加上 b: ‘b’
  • 回到 a.js,a.js 緩存加上 a: ‘a(chǎn)’,打印

所以 Commonjs 多次引入和循環(huán)引入的解決方案,是先緩存,再根據(jù)執(zhí)行的內(nèi)容新增緩存的內(nèi)容,而且只會(huì)執(zhí)行一次。

ES module 解決多次引入和循環(huán)引入也是依賴緩存,但是緩存的機(jī)制不一樣。ES module 是值的引用和編譯時(shí)輸出,ES module 導(dǎo)出的是內(nèi)存地址的索引:

index.js
import {c} from './c.js';

c.js
import n5n3t3z from './d.js';
console.log(d,'in c.js');
export var c = 'c';

d.js
import {c} from './c.js';
console.log(c,'in d.js');
export const d = 'd';

result
undefined in d.js
d in c.js

當(dāng)解析到 d.js 的 import {c} from ‘./c.js’;,會(huì)去 module map 檢查是否有 c moduel record,有,建立模塊指向。當(dāng)依賴解析完成之后,代碼也解析完成了,最后實(shí)例化運(yùn)行代碼,所以 d.js 執(zhí)行的時(shí)候 c 是 undefined。

ES module 動(dòng)態(tài)引入 import()

Commonjs 的 require 可以是動(dòng)態(tài)的,也不一定要放在頂層,ES module 的 import 就必須放在最頂層。動(dòng)態(tài)加載在實(shí)際應(yīng)用場(chǎng)景是必須的,對(duì)于性能方面有非常大的提升。最典型的就是路由懶加載,如果不是有動(dòng)態(tài) import,打包出來(lái)的是一個(gè)文件,首次加載會(huì)非常慢。還有是一些條件語(yǔ)句決定是否加載某些文件,對(duì)性能也非常友好。

tree shaking

ES module 可以實(shí)現(xiàn) tree shaking,核心就是 ES module 是編譯時(shí)輸出,新進(jìn)行編譯再執(zhí)行,編譯過(guò)程就能確定哪些內(nèi)容是無(wú)用的,Commonjs 就無(wú)法實(shí)現(xiàn),只有在執(zhí)行過(guò)程中才知道哪些內(nèi)容是無(wú)用的。

node 執(zhí)行 ES module

如果文件后綴是.mjs(node 執(zhí)行的后綴是.cjs),那么 node 會(huì)根據(jù) ES module 規(guī)范去執(zhí)行,如果是 js,那么 package.json 里面要新增"type": “module”,否則會(huì)報(bào)錯(cuò):

Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
SyntaxError: Cannot use import statement outside a module

也可以配置 exports 做兼容,exports 優(yōu)先級(jí)高于 main:

"exports": {
    "import": "./src/index.js",
    "require": "./src/index.cjs"
  }
require 尋找引入的順序

先看是否是內(nèi)置包,如果是直接返回;看是否是相對(duì)路徑,是就處理成可識(shí)別絕對(duì)路徑,如果找不到就報(bào)錯(cuò);不是內(nèi)置包沒(méi)有相對(duì)路徑,從當(dāng)前目錄開始尋找 node_modules,找不到依次往上的目錄尋找 node_modules,直到根目錄,還找不到就報(bào)錯(cuò)。會(huì)先以文件名找,再依次是.js、.json、.node。

歡迎關(guān)注訂閱號(hào) coding個(gè)人筆記文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-532644.html

到了這里,關(guān)于了解一下ES module 和 Commonjs的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • CommonJS 和 ES6 module

    CommonJS 和 ES6 module

    本文主要自己覺(jué)得要記錄的點(diǎn)記錄下來(lái),不耽誤大家時(shí)間,會(huì)持續(xù)更新。 Module對(duì)象 CommonJS加載一次之后會(huì)緩存文件 加載過(guò)程 CommonJS返回的是對(duì)象引用之后,在A地方修改后,會(huì)影響到B地址的加載結(jié)果。 CommonJS? 模塊同步加載并執(zhí)行模塊文件,ES6 模塊提前加載并執(zhí)行模塊文件,

    2024年02月12日
    瀏覽(22)
  • 記錄一下,C#運(yùn)行nodejs調(diào)用js文件提示報(bào)錯(cuò):Error: node:internal/modules/cjs/loader:1080

    個(gè)人記錄一下,C#運(yùn)行nodejs調(diào)用js文件提示報(bào)錯(cuò): 報(bào)錯(cuò)提示信息: Error: node:internal/modules/cjs/loader:1080 throw err; ? ^ ?Error: Cannot find module \\\'F:鎴戠殑....................” .....................下面還有很多報(bào)錯(cuò)內(nèi)容 還有英文提示模塊未找到的提示。 我另一個(gè)文件運(yùn)行沒(méi)報(bào)錯(cuò),運(yùn)行正常有

    2024年02月11日
    瀏覽(30)
  • 深入理解CommonJS和ES Module? 優(yōu)缺點(diǎn)?什么時(shí)候用?

    在webpack中,我們可以使用多種模塊化方式,如CommonJS和ES Module。 CommonJS是什么? CommonJS是一種模塊化規(guī)范,它是Node.js采用的模塊化規(guī)范,它的主要特點(diǎn)是同步加載模塊,模塊輸出的是一個(gè)值的拷貝,而不是引用。CommonJS的優(yōu)點(diǎn)是簡(jiǎn)單易用,可以在服務(wù)器端和客戶端使用,缺點(diǎn)

    2024年02月03日
    瀏覽(24)
  • Node.js開發(fā)、CommondJS 、ES-Module模塊化設(shè)計(jì)

    Node.js開發(fā)、CommondJS 、ES-Module模塊化設(shè)計(jì)

    目錄 ?Node.js是什么 基礎(chǔ)使用 Node的REPL 全局變量 ?模塊化設(shè)計(jì) CommondJS規(guī)范 ?基礎(chǔ)使用exports和module.exports require ?CommondJS優(yōu)缺點(diǎn) AMD和CMD規(guī)范 ES_Module ?基本使用方法 導(dǎo)出 導(dǎo)入 ?結(jié)合使用 默認(rèn)導(dǎo)出 ES Module解析流程 ?Node與瀏覽器的對(duì)比 ?在瀏覽器中,HTML與CSS交給Blink處理,如果其

    2023年04月21日
    瀏覽(31)
  • CommonJS 和 ES6 Module:一場(chǎng)模塊規(guī)范的對(duì)決(上)

    CommonJS 和 ES6 Module:一場(chǎng)模塊規(guī)范的對(duì)決(上)

    ?? 前端開發(fā)工程師(主業(yè))、技術(shù)博主(副業(yè))、已過(guò)CET6 ?? 阿珊和她的貓_CSDN個(gè)人主頁(yè) ?? ??透呒?jí)專題作者、在牛客打造高質(zhì)量專欄《前端面試必備》 ?? 藍(lán)橋云課簽約作者、已在藍(lán)橋云課上架的前后端實(shí)戰(zhàn)課程《Vue.js 和 Egg.js 開發(fā)企業(yè)級(jí)健康管理項(xiàng)目》、《帶你從入

    2024年01月23日
    瀏覽(28)
  • JavaScript:模塊化【CommonJS與ES6】

    在 JavaScript 編程中,隨著項(xiàng)目的復(fù)雜性增加,代碼的組織和管理變得至關(guān)重要。模塊化是一種強(qiáng)大的編程概念,它允許我們將代碼劃分為獨(dú)立的模塊,提高了可維護(hù)性和可擴(kuò)展性。本文將詳細(xì)介紹 CommonJS 和 ES6 模塊,幫助你理解它們的特點(diǎn)和用法。 1. CommonJS 模塊化 CommonJS 是

    2024年02月13日
    瀏覽(92)
  • 前端架構(gòu)師-week3-Node項(xiàng)目如何支持ES Module

    目錄 方案一: 通過(guò) webpack 完成 ES Module 資源構(gòu)建 通過(guò) webpack target 屬性支持 Node 內(nèi)置庫(kù) webpack loader 配置 babel-loader 支持低版本 Node? 方案二: 通過(guò)Node原生支持ES Module Node 支持 ES Module 的兩種方法 總結(jié) ? ? 根目錄下創(chuàng)建 webpack.config.js

    2024年02月06日
    瀏覽(23)
  • 008Node.js模塊、自定義模塊和CommonJs

    008Node.js模塊、自定義模塊和CommonJs

    CommonJS API定義很多普通應(yīng)用程序(主要指非瀏覽器的應(yīng)用)使用的API,從而填補(bǔ)了這個(gè)空白。它的終極目標(biāo)是提供一個(gè)類似Python,Ruby和Java標(biāo) 準(zhǔn)庫(kù)。這樣的話,開發(fā)者可以使用CommonJS API編寫應(yīng)用程序,然后這些應(yīng)用可以運(yùn)行在不同的JavaScript解釋器和不同的主機(jī)環(huán)境中。在兼容

    2024年04月13日
    瀏覽(22)
  • 前端面試:【前端工程化】CommonJS 與 ES6 模塊

    嗨,親愛(ài)的前端開發(fā)者!在現(xiàn)代Web開發(fā)中,模塊化是構(gòu)建可維護(hù)和可擴(kuò)展應(yīng)用程序的關(guān)鍵。本文將深入探討兩種主要的JavaScript模塊系統(tǒng):CommonJS 和 ES6 模塊,以幫助你了解它們的工作原理、用法以及如何選擇合適的模塊系統(tǒng)。 1. CommonJS: 用途: CommonJS 是一種模塊系統(tǒng),最初

    2024年02月11日
    瀏覽(103)
  • 前端jd要求:了解一門后端開發(fā)語(yǔ)言優(yōu)先 解決方案之Node.js

    作為前端開發(fā)者,了解一門后端開發(fā)語(yǔ)言可以為我們提供更多的職業(yè)機(jī)會(huì)和技術(shù)優(yōu)勢(shì)。在當(dāng)今的技術(shù)領(lǐng)域中,前后端分離的開發(fā)模式已經(jīng)成為主流,前端和后端的協(xié)作和溝通變得越來(lái)越緊密。因此,作為前端開發(fā)者,學(xué)習(xí)一門后端語(yǔ)言已經(jīng)成為提高自己技能的重要途徑。 以下

    2024年02月12日
    瀏覽(22)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包