成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何實現(xiàn)并部署自己的Npm解析服務(wù)

開發(fā) 前端
當(dāng)我們從項目Package.json中獲取到依賴庫的名稱后,完全可以從CDN直接請求依賴庫對應(yīng)的代碼,為什么還需要一個獨立的「Npm解析服務(wù)」呢?

大家好,我卡頌。

你是否好奇 —— codesandbox是如何在線運行代碼的?

要回答這個問題,我們先看看前端項目是如何在本地跑起來的。簡單來說分為3步:

  • 執(zhí)行npm install安裝依賴。
  • 使用打包工具(比如webpack)打包、編譯代碼(如果使用Vite會省去打包的步驟,但會執(zhí)行「預(yù)構(gòu)建」)。
  • 將步驟2的產(chǎn)物通過script標(biāo)簽注入頁面。

codesandbox能在線運行代碼,顯然他也實現(xiàn)了上述步驟,具體來說,codesandbox內(nèi)置了2個在線服務(wù):

  • npm解析服務(wù) —— 用于實現(xiàn)上述步驟1。
  • 在線打包服務(wù) —— 用于實現(xiàn)上述步驟2、3。

本文我們來聊聊如何實現(xiàn)并部署自己的npm解析服務(wù)。

codesandbox簡要工作原理

下面是一個常見的codesandbox界面,包含兩部分:

  • 左邊的文件系統(tǒng)、代碼編輯器。
  • 右邊的效果預(yù)覽區(qū)域。

其中「效果預(yù)覽區(qū)域」是一個iframe,對于上圖中的例子,iframe的地址是https://pjdp86.csb.app/。如果你打開這個地址,會發(fā)現(xiàn)他就是代碼的預(yù)覽效果:

但這并不意味著codesandbox幫我們部署了項目。實際上,這個地址中前端代碼是在頁面打開后再編譯、打包的。

打開codesandbox項目時經(jīng)常看到的下述界面,就是前端編譯代碼的畫面:

具體來說,當(dāng)我們打開一個codesandbox項目,iframe對應(yīng)地址初始化時,會執(zhí)行如下操作:

  • 下載項目代碼(即編輯器中顯示的代碼)。
  • 根據(jù)項目package.json中指明的依賴,從「npm解析服務(wù)」下載項目依賴的代碼。
  • 下載在線打包器(一個mini webpack)、編譯器(babel)相關(guān)代碼。
  • 在線打包、編譯。
  • 運行打包后的代碼。

正是有了在線打包、編譯的流程,codesandbox才能在線運行:

  • React項目(需要編譯JSX)。
  • TS項目(需要編譯TS語法)。
  • Vue項目(需要編譯SFC文件)。

回到本文的主題 —— 「npm解析服務(wù)」。當(dāng)我們從項目package.json中獲取到依賴庫的名稱后,完全可以從CDN直接請求依賴庫對應(yīng)的代碼,為什么還需要一個獨立的「npm解析服務(wù)」呢?

npm解析服務(wù)的作用

之所以需要獨立的「npm解析服務(wù)」,主要是因為 —— npm包本身可能還依賴別的npm包,如果每次初始化iframe時依次下載:

  • package.json中指定的依賴
  • 依賴的依賴
  • 依賴的依賴的依賴
  • ...

那會極大拖慢項目初始化的時間。同時,這樣做也可能會下載大量實際不會使用的代碼。

所以,需要一個「npm解析服務(wù)」,當(dāng)?shù)谝粋€用戶第一次請求某個庫時,依次完成:

  • 從庫的入口代碼解析AST,分析其中的require語句,遞歸的解析這個庫的依賴。
  • 下載依賴代碼,將所有依賴的代碼匯總到一個JSON文件。
  • 將步驟2的JSON文件保存在對象存儲中。
  • 返回步驟2的JSON文件。

那么,后續(xù)所有用戶在請求這個庫時,都能直接從對象存儲中直接獲取解析好的JSON文件,這能極大提高在線安裝依賴的速度。

比如,react@18.2.0經(jīng)由「npm解析服務(wù)」解析后會返回如下JSON:

{
  "contents": {
    "/node_modules/react/index.js": {
      // 庫的代碼
      "content": "...省略",
      "isModule": false,
      // 依賴的其他模塊
      "requires": [
        "./cjs/react.production.min.js",
        "./cjs/react.development.js"
      ]
    },
    "/node_modules/react/cjs/react.production.min.js": {/*省略*/},
    "/node_modules/react/cjs/react.development.js": {/*省略*/},
    "/node_modules/js-tokens/package.json": {/*省略*/},
    "/node_modules/loose-envify/package.json": {/*省略*/},
    "/node_modules/react/package.json": {/*省略*/}
  },
  // 庫的版本信息
  "dependency": {
    "name": "react",
    "version": "18.2.0"
  },
  "peerDependencies": {},
  // 依賴的依賴
  "dependencyDependencies": {
    "loose-envify": {/*省略*/},
    "js-tokens": {/*省略*/}
  },
  "dependencyAliases": {}
}

上述JSON中,入口代碼在/node_modules/react/index.js,通過遞歸分析他的AST,發(fā)現(xiàn)他依賴了:

  • "./cjs/react.production.min.js"
  • "./cjs/react.development.js"

于是,這2個文件對應(yīng)代碼也包含在JSON中。

當(dāng)下一個用戶加載的項目依賴react@18.2.0,就能直接從對象存儲中獲取上述JSON。

npm解析服務(wù)的實現(xiàn)

codesandbox在線打包相關(guān)的代碼都是開源的,比如:

  • 編輯器的部分對應(yīng)sandpack-react[1]
  • npm解析服務(wù)對應(yīng)dependency-packager[2]
  • 在線打包服務(wù)對應(yīng)codesandbox-client[3]

所以,我們可以基于dependency-packager部署自己的「npm解析服務(wù)」。

dependency-packager是一個serverless服務(wù),通過AWS Lambda部署。由于采用的是開源的serverless框架,所以我們可以很方便的將項目中AWS Lambda的部分替換成其他serverless服務(wù)商(比如阿里云函數(shù)計算)。

整個dependency-packager包含兩個serverless函數(shù):

  • api:實際對外提供的服務(wù)
  • packager:根據(jù)包名和版本號生成JSON的服務(wù)

他們的關(guān)系如下:

其中,生成的JSON保存在AWS S3中。同樣,這里也可以替換成其他云服務(wù)廠家的存儲方案。

packager服務(wù)的工作流程如下:

其中,「驗證依賴的入口文件」會嘗試下面這些文件后綴:

const found = [
  path.join(basedir, pkg.module),
  path.join(basedir, pkg.module + ".js"),
  path.join(basedir, pkg.module + ".cjs"),
  path.join(basedir, pkg.module + ".mjs"),
  path.join(basedir, pkg.module, "index.js"),
  path.join(basedir, pkg.module, "index.mjs"),
].find((p) => {
  try {
    const l = fs.statSync(p);
    return l.isFile();
  } catch (e) {
    return false;
  }
});

驗證完成后,會以package.json中的module或main字段作為入口文件,將代碼轉(zhuǎn)換為AST,分析AST中的require語句(cjs語法中引入模塊的語法),找到依賴的模塊。最終將這些模塊匯總在JSON中。

總結(jié)

codesandbox在線打包相關(guān)的代碼都是開源的,包括:

  • 編輯器
  • npm解析服務(wù)
  • 在線打包服務(wù)

其中,npm解析服務(wù)作為一個serverless服務(wù)包括兩部分:

  • api服務(wù)
  • packager服務(wù)

packager服務(wù)代碼量不多,如果想嘗試部署自己的serverless服務(wù),是個不錯的選擇。

參考資料

[1]sandpack-react:https://github.com/codesandbox/sandpack/tree/main/sandpack-react。

[2]dependency-packager:https://github.com/codesandbox/dependency-packager。

[3]codesandbox-client:https://github.com/codesandbox/codesandbox-client。

責(zé)任編輯:姜華 來源: 魔術(shù)師卡頌
相關(guān)推薦

2021-05-21 05:22:52

腳手架工具項目

2018-08-14 10:00:09

服務(wù)器域名代理商

2011-11-25 10:18:48

SaaS云計算

2021-12-01 06:40:32

Bind原理實現(xiàn)

2023-12-30 13:33:36

Python解析器JSON

2022-07-13 15:43:02

Docker后端api

2024-11-11 09:51:46

Nginx部署負載

2020-04-17 13:35:15

OpenStack私有云云計算

2010-03-30 14:08:53

Nginx狀態(tài)監(jiān)控

2020-06-30 15:35:36

JavaSPI代碼

2013-05-21 09:21:12

2014-03-06 09:23:19

Git服務(wù)器Github

2012-07-31 09:20:15

移動應(yīng)用市場推廣

2017-08-18 08:00:04

SaaS云計算公有云

2021-11-19 07:55:17

存儲鏡像部署

2021-08-27 11:03:57

Azure公有云云原生

2023-12-15 10:14:42

數(shù)據(jù)庫select語句

2021-11-30 06:56:58

CallApply函數(shù)

2023-09-11 08:31:12

自動配置熱部署DevTools

2023-10-12 22:38:18

SpringBoot熱部署
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久在线 | 久热国产精品视频 | 一区网站 | 日韩伦理一区二区 | 亚洲国产精品激情在线观看 | 九九久久99 | 最新av中文字幕 | 国产在线视频一区二区 | 999久久精品 | 天天弄天天操 | 欧美激情视频网站 | 91精品久久久 | 精品久久国产 | 91一区 | 天天综合永久 | 精品久久伊人 | 蜜桃官网 | 国产精品高清在线 | 爱爱爱av| 久久婷婷国产麻豆91 | 国产精品免费av | 欧美 日韩精品 | 91精品国产综合久久国产大片 | 自拍视频在线观看 | 中文字幕亚洲视频 | 日韩高清中文字幕 | 日韩在线国产精品 | 九九久久在线看 | 综合二区 | 成人国产在线观看 | 91精品国产91久久久久游泳池 | 五月天婷婷综合 | 中日韩欧美一级片 | 日韩欧美精品一区 | 国内91在线 | 日韩精品久久久久 | 久久国产日韩 | 久久精品国产亚洲一区二区三区 | 国产aa| 中文字幕一区二区三区日韩精品 | 亚洲成人自拍 |