node.js支持import語(yǔ)法,很簡(jiǎn)單一個(gè)知識(shí)點(diǎn),但是卻能提醒我們從知識(shí)誤區(qū)里走出來(lái),多關(guān)注外邊的知識(shí)世界,不斷打開(kāi)自己的知識(shí)邊界。
(資料圖片)
前端主流模塊化規(guī)范,目前有以下幾種:
CommonJS, Node.js提出的規(guī)范ECMAScript Module,ESM,由ECMAScript組織提出的JavaScript標(biāo)準(zhǔn)規(guī)范已淘汰的有:CMD、AMD等,再就綜合體UMD(支持各種規(guī)范的集合體)因此,主流有兩種規(guī)范CommonJS和ESM兩種規(guī)范,但是由于Node.js不支持ESM規(guī)范,導(dǎo)致很多時(shí)候我們的項(xiàng)目里面并存兩種規(guī)范的代碼,從而出現(xiàn)下面這種情況:
// 在node端執(zhí)行構(gòu)建的時(shí)候const _ = require("loadsh")// 在瀏覽器端實(shí)現(xiàn)的時(shí)候import _ from "loadsh";這樣子開(kāi)發(fā)就很容易出現(xiàn)痛點(diǎn),往往我們的解決方案就是通過(guò)各種構(gòu)建工具去解決,如:webpackvite,尤其是我們?cè)趯?xiě)項(xiàng)目中寫(xiě)node.js編譯腳本,經(jīng)常需要切換?!鞠嚓P(guān)教程推薦:nodejs視頻教程、編程教學(xué)】
但是從Node.js V14+版本后,它開(kāi)始支持ESM規(guī)范啦,你可以直接在Node.js中使用importexport等語(yǔ)法了,終于等到這一天?。
PS: 其實(shí)早在Node.js V8.5版本就已經(jīng)加入該特性了,只不過(guò)一直需要通過(guò)全局變量–experimental-modules去開(kāi)啟這一特性,由于不穩(wěn)定性大多數(shù)項(xiàng)目都沒(méi)有開(kāi)啟,不過(guò)自從16+后,我們就可以大膽放心在項(xiàng)目中使用了,不過(guò)一些古老的項(xiàng)目建議暫時(shí)不用開(kāi)啟。
我們先從官網(wǎng)上去看相關(guān)使用說(shuō)明:
通過(guò)上述我們就可以知道幾個(gè)使用方式:
將文件后綴改為.mjs,node.js加載的時(shí)候自動(dòng)會(huì)用ESM規(guī)范
在項(xiàng)目中package.json新增配置項(xiàng)"type":"module",那么整個(gè)項(xiàng)目中的.js文件都會(huì)按照ESM規(guī)范去執(zhí)行
增加執(zhí)行參數(shù)--input-type也可以實(shí)現(xiàn)相同效果
各種使用方式
1、常規(guī)方式:
import _ from "lodash";import { readFile } from "fs";import Demo from "./Demo.mjs"; // 絕對(duì)路徑或相對(duì)路徑都可以export readFile;export default readFile;2、帶參數(shù)的使用:
// 由于參數(shù)不同, 這個(gè)會(huì)讓`foo.mjs`被加載兩次,而不會(huì)利用緩存中的`foo.mjs`import "./foo.mjs?query=1"; // loads ./foo.mjs with query of "?query=1"import "./foo.mjs?query=2"; // loads ./foo.mjs with query of "?query=2"
3、支持data:格式URL的形式
import "data:text/javascript,console.log("hello!");"; // text/javascript 會(huì)將后面的內(nèi)容當(dāng)成js模塊import { test } from "data:text/javascript,function test(){console.log("test")};export {test};"; // 這里我們是不是擴(kuò)寬思路,直接加載在線js呢?import _ from "data:application/json,"world!"" assert { type: "json" }; // application/json 則是json// application/wasm for Wasm4、assert斷言(實(shí)驗(yàn)特性)將文件強(qiáng)制加載為某種格式內(nèi)容,如:jsonjavascriptwebassembly等
import fooData from "./foo.json" assert { type: "json" };5、加載commonjs規(guī)范模塊
當(dāng)然肯定也支持加載commonjs規(guī)范的模塊,用法如下:
import { default as cjs } from "cjs"; // module.exports 導(dǎo)出import cjsSugar from "cjs"; // module.exportsimport * as m from "cjs";6、import() 異步導(dǎo)入這種用法就很正常,不需要實(shí)時(shí)加載,等到需要用的時(shí)候再加載
const { default: barData } = await import("./bar.json", { assert: { type: "json" } });7、支持從http/https引入(實(shí)驗(yàn)特性)
目前屬于實(shí)驗(yàn)特性,有限制,比如:
不支持http2/3協(xié)議http協(xié)議只能用于127.0.0.1等本地ip地址Cookie、Authorization等信息不會(huì)攜帶發(fā)送只會(huì)加載執(zhí)行遠(yuǎn)端的js文件,而不會(huì)加載遠(yuǎn)端中依賴其他文件import worker_threads from "node:worker_threads";import { configure, resize } from "https://example.com/imagelib.mjs";configure({ worker_threads });限制
唯一的限制:當(dāng)開(kāi)啟ESM規(guī)范后,你只允許填寫(xiě)import或export,不允許使用require或module.exports,會(huì)報(bào)一下錯(cuò)誤:
const a = require("a") ^ReferenceError: require is not defined in ES module scope, you can use import instead at file:///Users/borfyqiu/Desktop/study/github/qiubohong.github.io/code/demo-rollup/test.mjs:4:12 at ModuleJob.run (node:internal/modules/esm/module_job:193:25) at async Promise.all (index 0) at async ESMLoader.import (node:internal/modules/esm/loader:530:24) at async loadESM (node:internal/process/esm_loader:91:5) at async handleMainPromise (node:internal/modules/run_main:65:12)其實(shí)這個(gè)也不算是冷門(mén)知識(shí),只要稍微對(duì)Node.js有做持續(xù)關(guān)注,基本上都可以了解到該特性。
但是作為不關(guān)注的人,很容易就陷入自己的知識(shí)誤區(qū),會(huì)一直認(rèn)為Node.js不支持ESM規(guī)范,甚至?xí)虏跱ode.js為什么不支持呢?
所以這里有一句話需要提醒自己—— 【書(shū)山無(wú)路勤為徑,學(xué)海無(wú)涯苦作舟】。
更多node相關(guān)知識(shí),請(qǐng)?jiān)L問(wèn):nodejs 教程!
以上就是淺析node中怎么使用import語(yǔ)法的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!
關(guān)鍵詞: