本文目錄一覽:
- 1、在 Node.js 中使用原生 ES 模塊方法解析
- 2、使用 MockJs — 實現真正的前後端分離
- 3、「官方」總結2021的IPFS:成為Web3主流勢頭的支柱
- 4、在node環境下怎麼使用commonjs模塊去使用require方法
- 5、怎樣寫一個能同時用於 Node 和瀏覽器的
在 Node.js 中使用原生 ES 模塊方法解析
從版本
8.5.0
開始,Node.js
開始支持原生
ES
模塊,可以通過命令行選項打開該功能。新功能很大程度上得歸功於
Bradley
Farias。
1.演示
這個示例的代碼目錄結構如下:
esm-demo/
lib.mjs
main.mjs
lib.mjs:
export
function
add(x,
y)
{
return
x
+
y;
}
main.mjs:
import
{add}
from
‘./lib.mjs’;
console.log(‘Result:
‘+add(2,
3));
運行演示:
$
node
–experimental-modules
main.mjs
Result:
5
2.清單:需要注意的事情
ES
模塊:
·不能動態導入模塊。但是
動態import()
的相關工作正在進行中,應該很快就能提供支持。
·沒有元變量,如
__dirname
和
__filename。但是,有一個的類似功能的提案:「import.meta」。看起來可能是這樣:
console.log(import.meta.url);
·現在所有模塊標識符都是
URL(這部分在
Node.js
是新增的):
·文件
–
帶文件擴展名的相對路徑:
../util/tools.mjs
·庫
–
沒有文件擴展名,也沒有路徑
lodash
·如何更好地使
npm
庫在瀏覽器中也可用(不使用
bundler)仍有待觀察。一種可能性是引入
RequireJS
風格的配置數據,將路徑映射到實際路徑。目前,在瀏覽器中使用
bare
path
的模塊標識符是非法的。
與
CJS
模塊的互操作性
你可以導入
CJS
模塊,但它們總是只有默認的導出
–
即
module.exports
的值。讓
CJS
模塊支持命名導出已經在做了,但可能需要一段時間。如果你能幫忙,可以來做。
import
fs1
from
‘fs’;
console.log(Object.keys(fs1).length);
//
86
import
*
as
fs2
from
‘fs’;
console.log(Object.keys(fs2));
//
[‘default’]
·
不能在
ES
模塊中使用
require()。主要原因是:
· 路徑解析工作稍有不同:ESM
不支持
NODE_PATH
和
require.extensions。而且,它的標識符始終是
URL
也會導致一些細微差異。
·
ES
模塊始終以異步方式加載,這確保了與
Web
的最大兼容性。這種加載風格並不能通過
require()
混合使用同步加載
CJS
模塊。
·
禁止同步模塊加載也可以為
Top-level
await
導入
ES
模塊保留後路(一個當前正在考慮的功能)。
3.早期版本的
Node.js
上的
ES
模塊
如果要在
8.5.0
之前的
Node.js
版本上使用
ES
模塊,請參閱
John-David
Dalton
的
@std/esm。
提示:如果不啟用任何可解鎖的額外功能,將在
Node.js
保持
100%
兼容原生
ES
模塊.
FAQ
什麼時候可以不帶命令行選項使用ES
模塊?
目前的計劃是在
Node.js
10
LTS
中默認可使用
ES
模塊。
進一步閱讀
有關
Node.js
和瀏覽器中
ES
模塊的更多信息:
·
「Making
transpiled
ES
modules
more
spec-compliant」
[using
ES
modules
natively
vs.
transpiling
them
via
Babel]
·
「Module
specifiers:
what’s
new
with
ES
modules?」
[Why
.mjs?
How
are
module
specifiers
resolved?
Etc.]
·
「Modules」
[in-depth
chapter
on
ES
modules
in
「Exploring
ES6」]
即將到來的
ECMAScript
提案:
·
博客:
「ES
proposal:
import()
–
dynamically
importing
ES
modules」
·
提案:
「import.meta」
總結
以上就是小編給大家帶來的在
Node.js
中使用原生
ES
模塊方法解析的全部內容,希望對大家有所幫助。如果您有什麼問題,可以給我留言。感謝大家對本站的支持。
使用 MockJs — 實現真正的前後端分離
前言: 剛剛看了下的後台,發現我技術文章中,閱讀留言最多的是關於移動端的文章,甚至還有人付費讚賞或諮詢。關於 PC 端的技術文章就顯得比較冷清了,唉,廢了好大勁寫的,沒人看。 和我想的一樣,移動端才是王道,下次找工作我也搞移動端? 。
背景: 去年我寫了一篇 學習使用 json-server 和 mockjs 的文章,當時沒有仔細研究,文章只提到了 MockJs 其中一個 Random 的用法,關於 MockJs 攔截器和另一個很常用的 Mock.mock 函數都沒有提及。這次來搞一下。
唉!以前我也是經常會聽到 前後端分離 這個名詞,只模糊的知道它最重要的一個作用就是,大大的提升了 前端的地位。 但是平時在開發的時候,我也會想奶奶的,沒有接口這前端不就寫了一個破頁面,後期還的和後端對接口,對接口的時候花費的時間,肯定是不比前端開發的時候短,工期上最起碼一半一半吧, 這也就前後端分離 ,我這個小腦袋就不是太明白了。
不過我現在是終於搞明白這個問題了, 對於前端來講,真正的前後端分離,標誌是不依賴後端的前端工作開發完成,項目基本宣告結束。 後端開發完接口,只需要提換一個 URL 就行了,這也意味着前端需要去寫一些接口。
除了帶來開發任務稍微重點外,我至少看到了兩個最大的優點:
我體會最深就是這兩點。
插曲 :對了,今天中午我撿到一個手機,我必須要用一張動圖來描述下:
這個經典的 GIF ,來自鄭伊健的恐怖電影「第一誡」,清涼一冬,絕對值得一看,雖然劇情有很大的 bug ,但是港片就這點好,它有很抓人的地方,讓你覺得特別好看。
正文由此開始:
待續~~~
上面三種方案都可以,但你要知道接口很多,需要支持批量引入,所以 使用 Axios 響應攔截器 就不太可取,只能在這簡單的造些假數據。
著名開源項目 vue-element-admin 開發環境下模擬假接口使用的是 在 webpack-dev-server 的 before 處攔截。生產環境下是在項目入口文件( index,js )使用 Mock.mock 模擬的。
攔截請求的步驟如下,根據 devserverbefore 配置的栗子?:
可知道 before 接收一個函數,函數的第一個參數一般叫 app ,因為它的作用和 express 的 app 是等效的。也就是說這個 app 自帶路由, 正好解決接口批量引入的問題。
在項目中,一般都是這麼寫,把邏輯提出去:
./mock/mock-server.js 文件的內容為:
./mock/index.js 文件的內容為:
mockXHR 不用看,因為這是給線上環境用的,所以可以簡單的改寫為:
隨便找一個,例如 user 看下接口怎麼寫的:
完美,到此結束。
我想你一定對更改文件的時候,為什麼要 清路由和清緩存感興趣。
如果熟悉 express 框架,看到 app._router.stack 你就知道了。不知道也沒關,我演示給你看,新建一個JS 文件,文件內容為:
執行結束,看在 test.js 文件的內容:
發現沒,重複被添加的路由,不是覆蓋而是擴展。
這個涉及到 CJS 模塊的運行機制, 記住 require 的文件會被加到 require.cache 裏面,當文件改變讀的是緩存,而不是最新更改的文件。
項目結構過大,如果只在 mock 文件夾裏面管理有點麻煩,我就想在頁面所在目錄直接寫接口,怎麼辦?沒錯使用 require.context 來批量引入。但是 NodeJs 是沒有批量引入的 API 的。找遍了 npm 也沒發現一個 package 和 require.context 長得像的。
難道沒辦法了嗎?當然不是,自己動手豐衣足食。 依照 vue-cli 插件的命名規範,我給寫的 package 取名 node-plugin-require-context ,簡單講下實現原理:
其實還有一個缺點,如果你看過 Antd-Pro 項目,你就會發現它模擬數據,模塊化採用的是 ESModule ,而不是 CJS。保持編碼模塊化風格一致確實也是需要優化的一個地方,不管了,反正我不幹。
官網本來就是中文的,我在使用中發現寫的賊好,我就不用畫蛇添足了。建議每次使用前:
「官方」總結2021的IPFS:成為Web3主流勢頭的支柱
原文:
Web3 應用程序在 2021 年的受歡迎程度飆升。該技術用例的增長也為支持它們的基礎設施帶來了更大的需求。 IPFS 已成為開發人員和用戶在新興 Web3 生態系統中使用的解決方案不可或缺的一部分。 網絡統計:存儲在 IPFS 上的 NFT:15M+每周唯一活躍 IPFS 節點:230K+ipfs.io 網關用戶每周:370 萬+ipfs.io 每周網關請求:805M+
2021 年合作與整合
擁有 IPFS 和NFT.Storage等工具 , Web3.存儲 , 和Estuary 在後端使項目能夠提供分散存儲功能作為其產品的一部分。
讓我們來看看一些最值得注意的應用程序:
1 Opensea 集成 NFT.Storage 以實現安全、平台範圍的 NFT 持久性
OpenSea 是去中心化網絡上最大的 NFT 市場之一。它合作了 與 IPFS 和 FIlecoin 集成 NFT.Storage 並允許用戶「凍結」他們的 NFT 元數據。這個過程允許創作者真正去中心化他們的 NFT,將權力交還給創作者,而不是託管者。
如今, OpenSea 用戶可以創建不可變的 NFT 數據以持久存儲在 Filecoin 的區塊鏈上,並通過 IPFS 內容 ID 完成檢索數據的尋址。 IPFS 內容尋址通過消除「地毯拉動」或 NFT 元數據錯位的可能性,為 NFT 託管提供了完美的解決方案。
2 Brave 在其正在進行的 Web3 集成中添加了對 IPFS 的本地支持
在包含自己的加密貨幣錢包之後,Brave 通過集成 IPFS,繼續為其桌面 Web 瀏覽器添加 Web3 功能。 現在允許用戶通過本地解析 IPFS 地址來訪問存儲在協議上的內容。
整合是多年合作的結果 兩個團隊之間的合作, 目標是讓最終用戶儘可能地訪問 IPFS。這是朝着將 IPFS 轉變為所有瀏覽器最終可能支持的公認互聯網標準邁出的一大步。
3 Opera 擴展了對 IPFS 協議尋址的支持
Opera 於 2020 年首次在其 Android 瀏覽器中添加了對 IPFS 的支持 。今年,它將相同的功能擴展到其Opera Touch iOS 用戶的瀏覽器,允許他們導航到 ipfs:// 和 ipns:// 地址。
4 Pinata 讓任何人都可以輕鬆利用 IPFS
這種固定和文件管理服務允許用戶以簡單無縫的方式存儲區塊鏈經常引用的內容。 Pinata 充分利用IPFS 固定服務 API 將內容發佈到 IPFS 網絡,允許基於 CID 的去中心化存儲和高效檢索 。
5 ScalaShare 通過 IPFS 為 Web3 帶來了安全的文件共享
互聯網上用戶之間的文件共享始於 P2P 共享,但ScalaShare 帶來了 在 IPFS 的幫助下將此功能應用於 Web3。 對於那些不願意將數據交給大公司的人來說,這個簡單的開源工具可能會成為首選的文件存儲系統。
6 Audius 依靠 CID 按需流式傳輸音樂
Audius 將 Web3 上的音樂流媒體服務帶入了一個新的方向。 Audius使用 IPFS 集成來存儲和檢索數據 可以確保沒有斷開的曲目鏈接,並且所有音樂都交付給用戶,而不依賴於集中式服務器 。
IPFS 的 CID 是確保此音樂流媒體服務正常運行並繼續使用的關鍵 流行的 Web 2.0 應用程序(如 TikTok)上的 Web3 基礎架構。
7 Palm 在其可持續的 NFT 平台上使用 IPFS 進行存儲
這個相對較新的 NFT 工作室最近與 IPFS 合作。Palm 具有用於生成 NFT 的可持續架構。它使用基於代幣的經濟來維持具有快速交易時間和低gas費用的生態系統,所有這些都基於節能技術。 IPFS 提供了它需要的解決方案,以確保用戶始終可以訪問他們的工作 。
8 Valist 信任 IPFS 以實現安全的 Web3 軟件分發
通過網站或應用商店發佈軟件有時會引入安全問題,正如 2020 SolarWinds 攻擊所證明的那樣。Valist通過允許開發團隊以 Web3-native 方式分發軟件來解決這個問題。 IPFS 通過提供大量開箱即用的安全保證,充當 Valist 的主要存儲層。
9 Snapshot 確保 DAO 投票過程通過 IPFS 去中心化
流行的 DAO 投票系統快照 依賴 IPFS 作為其基礎設施的核心部分。 它允許 DAO 成員通過去中心化投票過程就特定協議提案達成共識。快照是從產品到協議的一切社區治理不斷增長的空間中最常用的工具之一
技術更新
2021 年還見證了 IPFS 工作方式的多項技術更新。其中的核心是:
1 IPFS 0.11.0
這是面向 Go 開發人員的 IPFS 實現。除了重要的修復之外, 最新版本還改進了 UnixFS 分片和 PubSub 實驗以及對 Circuit-Relay v2 的支持 。在這一年中,還進行了其他改進,例如:
對 go-ipfs 的 IPLD 內部結構的更改使使用非 UnixFS DAG 更容易提供多種新命令和配置選項網關支持通過 DAG 導出端點下載任意 IPLD 圖自定義 DNS 解析器支持非 ICANN DNSLink 名稱單獨打包的遷移為 Apple M1 硬件構建固定服務的 WebUI 支持遠程固定服務更快的固定和取消固定
2 JS IPFS 0.60.0
JS IPFS 是基於 JavaScript 的類似實現。 它緩解了將 IPFS 數據與 JavaScript 應用程序鏈接的問題,允許開發人員使用它來本地訪問 IPFS 數據 。最新版本包括重要的錯誤修復,並且全年進行了重要的改進,例如:
ESM 和 CJS 雙重發佈一個更簡單的 globSource APIPubSub 支持解決瀏覽器連接限制ipfs.get 上的壓縮包輸出默認從 RSA 切換到 Ed25519Dag 導入導出實現更好的類型定義啟用 NAT UPnP 打孔在 ipfs-http-client 中添加了對支持遠程固定服務的支持
3 IPFS 集群 0.14.1
用於設置和運行 IPFS 集群的源代碼 。這個開源發行版向更多用戶和開發人員打開了 IPFS 的世界。在這一年中,它收到了更新,包括:
提高可以列出 pinset 的速度將內容遷移到新集群時更靈活CAR導入支持批量固定攝取對 Badger 數據存儲的自動垃圾收集
為了更好地理解為什麼這些改進很重要,請務必查看本技術指南 到 IPFS。
採用的下一步
儘管 IPFS 在去年取得了長足的進步,但仍有增長空間。新的合作夥伴關係和進步將是更廣泛的 Web3 可用性的關鍵。 隨着越來越多的主流用戶意識到對去中心化互聯網的需求,對 IPFS 等工具的需求將會增加 。隨着他們繼續進入這個領域,我們將看到 2022 年會帶來什麼。
在node環境下怎麼使用commonjs模塊去使用require方法
最初的 CommonJS 小組 的參與者們決定弄一份於時下的 JavaScript 編程語言有效,但不必束縛於瀏覽器 JS 環境的限制,的模塊規範。開始的願景是在瀏覽器里使用一些權宜之計, 並希望能藉此影響瀏覽器廠商,促使它們為這種模塊規範的原生支持提供解決方案。權宜之計有:
要麼使用一個服務來轉譯 CJS 模塊成瀏覽器中可用的代碼
要麼使用 XMLHttpRequest(XHR)以文本形式加載模塊,再在瀏覽器中做文本變換、解析的工作
CJS 模塊規範僅允許每文件一個模塊,所以為優化、打包,可使用某種「轉換格式」將多個模塊合併到單個文件。
通過這種方式,CommonJS 小組搞定了依賴引用、如何處理循環依賴,以及如何獲得當前模塊的某些屬性等問題。 但是,他們並沒能接納瀏覽器環境里不可改變、並且仍將影響模塊設計的某些特性:
網絡加載
異步繼承 … 這也同時意味着他們為了實現這個規範,將負擔更多地放到了 Web 開發者身上,而這些權宜之計也使調試變得更麻煩。 調試 eval 的代碼,或者調試多個文件合併之後的單個文件,都有實際使用時的壞處。 這些缺點或許在未來某天會被瀏覽器調試工具解決掉,但結論仍然是:在最普遍的 JS 環境,瀏覽器中,使用 CommonJS 模塊並不是最好的辦法。
怎樣寫一個能同時用於 Node 和瀏覽器的
因此讓我們來寫一個小的 JavaScript 包,叫做 base64-encode-string。它所做的只是接收一個字符串作為輸入,輸出其 base64 編碼的版本。
對於瀏覽器來說,這很簡單:我們只需要使用自帶的 btoa 函數:
module.exports = function (string) {
return btoa(string);
};
然而在 Node 里並沒有 btoa 函數。因此,作為替代,我們需要自己創建一個 Buffer,然後在上面調用 buffer.toString():
module.exports = function (string) {
return Buffer.from(string, ‘binary’).toString(‘base64’);
};
對於一個字符串,這兩者都應提供其正確的 base64 編碼版本,比如:
var b64encode = require(‘base64-encode-string’);
b64encode(‘foo’); // Zm9v
b64encode(‘foobar’); // Zm9vYmFy
現在我們只需要一些方法來檢測我們究竟是在瀏覽器上運行還是在 Node 上,好讓我們能保證使用正確的版本。Browserify 和 Webpack 都定義了一個叫 process.browser 的字段,它會返回 true(譯者註:即瀏覽器環境下),然而在 Node 上這個字段返回 false。所以我們只需要簡單地:
if (process.browser) {
module.exports = function (string) {
return btoa(string);
};
} else {
module.exports = function (string) {
return Buffer.from(string, ‘binary’).toString(‘base64’);
};
}
現在我們只需要把我們的文件命名為 index.js,鍵入 npm publish,我們就完成了,對不對?好的吧,這個方法有效,但不幸的是,這種實現有一個巨大的性能問題。
因為我們的 index.js 文件包含了對 Node 自帶的 process 和 Buffer 模塊的引用,Browserify 和 Webpack 都會自動引入 其 polyfill,來將它們打包進這些模塊。
對於這個簡單的九行模塊,我算了一下, Browserify 和 Webpack 會創建 一個壓縮後有 24.7KB 的包 (7.6KB min+gz)。對於這種東西,用掉的空間實在是太多,因為在瀏覽器里,只需要 btoa 就能表示這個。
「browser」 字段,我該如何愛你
如果你在 Browserify 或者 Webpack 文檔里找解決這個問題的提示,你可能最後會發現 node-browser-resolve。這是一個對於 package.json 內 “browser” 字段的規範,可以被用於定義在瀏覽器版本構建時需要被換掉的東西。
使用這種技術,我們可以將接下來這段加入我們的 package.json:
{
/* … */
“browser”: {
“./index.js”: “./browser.js”
}
}
然後將函數分割成兩個不同的文件:index.js 和 browser.js:
// index.js
module.exports = function (string) {
return Buffer.from(string, ‘binary’).toString(‘base64’);
};
// browser.js
module.exports = function (string) {
return btoa(string);
};
有了這次改進以後,Browserify 和 Webpack 會給出 更加合理的包:Browserify 的包壓縮後是 511 位元組(315 min+gz),Webpack 的包壓縮後是 550 位元組(297 min+gz)。
當我們將我們的包發佈到 npm 時,在 Node 里運行 require(‘base64-encode-string’) 的人將得到 Node 版的代碼,在 Browserfy 和 Webpack 里跑的人會得到瀏覽器版的代碼。
對於 Rollup 來說,這就有點複雜了,但也不需要太多額外的工作。Rollup 用戶需要使用 rollup-plugin-node-resolve 並在選項里將 browser 設置為 true。
對 jspm 來說,很不幸地,沒有對 「browser」 字段的支持,但是 jspm 用戶可以通過 require(‘base64-encode-string/browser’) 或者 jspm install npm:base64-encode-string -o “{main:’browser.js’}” 來迂迴地解決問題。另一種方法是,包的作者可以在他們的 package.json 里 指定一個 「jspm」 字段。
進階技巧
這種直接使用的 “browser” 方法可以工作得很好,但是對於大型項目來說,我發現它在 package.json 和代碼庫間引入了一種尷尬的耦合。比如說,我們的 package.json 會很快長成這樣:
{
/* … */
“browser”: {
“./index.js”: “./browser.js”,
“./widget.js”: “./widget-browser.js”,
“./doodad.js”: “./doodad-browser.js”,
/* etc. */
}
}
在這種情況下,任何時候你想要一個適配於瀏覽器的模塊,都需要分別創建兩個文件,並且要記住在 “browser” 字段上添加額外行來將它們連接起來。還要注意不能拼錯任何東西!
並且,你會發現你在費盡心機地將微小的代碼提取到分離的模塊里,僅僅是因為你想要避免 if (process.browser) {} 檢查。當這些 *-browser.js 文件積累起來的時候,它們會開始讓代碼庫變得很難跳轉。
如果這種情況變得實在太笨重了,有一些別的解決方案。我自己的偏好是使用 Rollup 作為構建工具,來自動地將單個代碼庫分割到不同的 index.js 和 browser.js 文件里。這對於將你提供給用戶的代碼的解模塊化有額外的價值,節省了空間和時間。
要這樣做的話,先安裝 rollup 和 rollup-plugin-replace,然後定義一個 rollup.config.js 文件:
import replace from ‘rollup-plugin-replace’;
export default {
entry: ‘src/index.js’,
format: ‘cjs’,
plugins: [
replace({ ‘process.browser’: !!process.env.BROWSER })
]
};
(我們將使用 process.env.BROWSER 作為一種方便地在瀏覽器構建和 Node 構建間切換的方式。)
接下來,我們可以創建一個帶有單個函數的 src/index.js 文件,使用普通的 process.browser 條件:
export default function base64Encode(string) {
if (process.browser) {
return btoa(string);
} else {
return Buffer.from(string, ‘binary’).toString(‘base64’);
}
}
然後將 prepublish 步驟添加到 package.json 內,來生成文件:
{
/* … */
“scripts”: {
“prepublish”: “rollup -c index.js BROWSER=true rollup -c
browser.js”
}
}
生成的文件都相當直白易讀:
// index.js
‘use strict’;
function base64Encode(string) {
{
return Buffer.from(string, ‘binary’).toString(‘base64’);
}
}
module.exports = base64Encode;
// browser.js
‘use strict’;
function base64Encode(string) {
{
return btoa(string);
}
}
module.exports = base64Encode;
你將注意到,Rollup 會按需自動地將 process.browser 轉換成 true 或者 false,然後去掉那些無用代碼。所以在生成的瀏覽器包里不會有對於 process 或者 Buffer 的引用。
使用這個技巧,在你的代碼庫里可以有任意個的 process.browser 切換,並且發佈的結果是兩個小的集中的 index.js 和 browser.js 文件,其中對於 Node 只有 Node 相關的代碼,對於瀏覽器只有瀏覽器相關的代碼。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/307197.html