您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)如何在Nodejs或者瀏覽器直接運(yùn)行esm代碼,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
怎么在Nodejs或者瀏覽器直接運(yùn)行esm代碼?
Commonjs
CommonJs 可以動(dòng)態(tài)加載語句,代碼發(fā)生在運(yùn)行時(shí)
CommonJs 導(dǎo)出值是拷貝, 不好排查引起變量污染
ES module(后續(xù)簡稱 esm)
ESM 是靜態(tài)的,代碼發(fā)生在編譯時(shí)
ESM 導(dǎo)出是引用值之前都存在映射關(guān)系,并且值都是可讀的,不能修改 參考 淺析什么是CommonJs和Es Module?有什么區(qū)別?
esm 是 JavaScript 模塊化的未來。因?yàn)樗鉀Q了變量污染,代碼維護(hù),代碼依賴的問題。它讓你的代碼更加科學(xué)。這也是 deno 默認(rèn)采用 esm 的原因。
回歸正題,我們有什么方法在 Nodejs 或者瀏覽器直接運(yùn)行 esm 代碼,這是個(gè)有趣而又實(shí)際的問題。
最常見的方式是利用webpack等打包工具搭配 babel 使用。隨著 webpack 和 vue 的大熱,這些工具似乎成為了標(biāo)配,但是 webpack 的缺點(diǎn)也很明顯,它能讓 commonjs 和 esm 的混寫,導(dǎo)致代碼存在一些寫法不規(guī)范的情況,我相信這種情況是普遍出現(xiàn)在業(yè)務(wù)代碼里面,也存在于 antd3 這樣的知名第三方組件庫中。
而rollup則是基于 ES6 的語法規(guī)范進(jìn)行編譯,它的輕便小巧,非常適合 npm 庫的打包。新興的打包工具例如esbuild和swc,也可以實(shí)現(xiàn)編譯打包,即使速度越來越快,但是還是需要編譯的過程。這些倉庫很重要的一個(gè)特點(diǎn)就是使用 esm 語法。
以上這些工具都可以應(yīng)用于 esm 語法編譯,但是有很多項(xiàng)目不一定需要打包編譯這樣耗時(shí)的流程的,例如一些 cli 工具、簡易微服務(wù)等,如何保證高效正確的運(yùn)行 esm 代碼呢?
在 Nodejs 版本較低的情況,我們可以利用一些工具,工具的使用形式有幾種,一種是 Module Loader,另一種是 Command Line(簡稱為 cli)。
Module Loader,這里介紹standard-things/esm,它可以 preload 第三方提供的 esm 包,從此,可以做到 babelless, bundleless。你不需要使用大型編譯工具也可以直接運(yùn)行 esm 代碼,使用方式如下。
node -r esm index.js
同樣,egoist/esbuild-register這個(gè)庫在 esbuild 的支持下,同樣可以做到 Module Loader 的效果,利用 esbuild 的高性能特性,代碼運(yùn)行效率更高。
node -r esbuild-register index.js
Command Line,基于封裝后的 cli,不過是換一種形式進(jìn)行模塊的提前處理。babel-node直接利用它的 babel 語法優(yōu)勢來運(yùn)行 esm 代碼。由于 babel 本身還是 js 的實(shí)現(xiàn),它的官方文檔也表明了不建議在生產(chǎn)環(huán)境使用,會導(dǎo)致內(nèi)存高占用的問題,這也是這一類工具的通病。
babel-node index.js
同樣,esno可以直接在命令行運(yùn)行 esm 代碼。原理基于 esbuild。在這里更推薦使用這種方式,鑒于 esbuild 是由 go 語言實(shí)現(xiàn),能夠較大程度解決內(nèi)存高占用的問題,保證了一定的執(zhí)行性能。
esno index.ts esmo index.ts
這一類第三方倉庫適合在低版本 nodejs 且非生產(chǎn)環(huán)境使用,它們的存在是為了便利性,而并非實(shí)用性和穩(wěn)定性。怎么樣才能高效地運(yùn)行 esm 代碼?
Node verison 13.2.0 起開始正式支持 ES Modules 特性
所以利用 Native Nodejs 環(huán)境運(yùn)行 esm 代碼是非常必要的,高版本的 Nodejs 提供了直接運(yùn)行 esm 的功能,這里建議使用 lts14 版本。有兩種方式運(yùn)行 esm 代碼:
第一種,package.json 中填寫 type: "modules",表明模塊的類型。此后,直接運(yùn)行node index.js
即可。
// pakage.json { ... "type": "modules" }
第二種,則是將文件名改成.mjs
,標(biāo)明該文件是 esm 代碼。這兩種方式最大的區(qū)別則是模塊作用域。前者是包的作用域,它的聲明是以 package 為維度。后者則是以文件為維度,不受限于包的作用域。
瀏覽器的情況有別于 Nodejs 環(huán)境,在大部分的新版本瀏覽器都支持 esm 的運(yùn)行。esm 級別的代碼編譯和打包,可以有效地減少包的體積和資源傳輸速度。這也是為什么像 vite 這樣的框架會采用現(xiàn)代瀏覽器的打包模式(外加 legacy 兼容模式)的原因。具體的原理是在 html 當(dāng)中的 script 標(biāo)簽加入type="module"
則表明它引入的是 esm 代碼,當(dāng)舊瀏覽器沒法支持 esm 的情況下,它會讀取nomodule script
中的地址,讀取兼容版本的 js 代碼。這樣一來,可以有效地減少大部分瀏覽器加載的 js 體積,又保證了老瀏覽器的兼容性問題。
<script type="module" src="dist/index.js"></script> <script nomodule src="dist/index.legacy.js"></script>
如今 Nodejs 和瀏覽器環(huán)境都能對 esm 語法有了很好的 Native 支持。作為前端工程師的我們,應(yīng)該要保持著技術(shù)的前瞻性,在寫一個(gè)倉庫的時(shí)候,我們要想到要用 typescript,esm 還是 common.js 呢?
看完上述內(nèi)容,你們對如何在Nodejs或者瀏覽器直接運(yùn)行esm代碼有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。