<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      記一次插件發(fā)布的采坑經(jīng)歷

      在你需要導(dǎo)出多個組件然后打包給外部使用的時候,需要配置package.json和vite.config.js ,下面來說一些關(guān)鍵的點,防止下次再遇到不會配置
      解釋幾個配置的意思

      1."keywords": [
      "vue",
      "video",
      "flv",
      "webrtc"
      ],
      含義:這是你庫的“標簽”或“關(guān)鍵詞”。
      作用:當其他人在 npmjs.com 網(wǎng)站上搜索時,這些關(guān)鍵詞可以幫助他們發(fā)現(xiàn)你的庫。它相當于給你發(fā)布的包做了 SEO 優(yōu)化。你的這些關(guān)鍵詞(vue, video, flv, webrtc)非常精準,能有效吸引到目標用戶。


      2. main, module, types (傳統(tǒng)入口字段)
      在現(xiàn)代打包中,這些字段可以看作是為不支持 exports 字段的舊工具提供的向后兼容的入口。
      "main": "./dist/zy-video-view.cjs.js",

      含義:定義了包的 CommonJS (CJS) 入口文件。
      誰會用它:主要被 Node.js 環(huán)境使用。當在 Node.js 項目中寫 const myLib = require('zy-video-view'); 時,Node.js 會去加載這個 cjs.js 文件。

      module": "./dist/zy-video-view.es.js",

      含義:定義了包的 ES Module (ESM) 入口文件。
      誰會用它:主要被現(xiàn)代打包工具(如 Vite, Webpack, Rollup)使用。這些工具在構(gòu)建前端項目時,會優(yōu)先尋找 module 字段。使用 ESM 格式的好處是支持搖樹優(yōu)化 (Tree Shaking),可以移除未使用的代碼,減小最終打包體積。

      "types": "./dist/zy-video-view.d.ts",

      含義:定義了包的 TypeScript 類型聲明文件 的入口。
      誰會用它:TypeScript 編譯器 (tsc) 和代碼編輯器(如 VS Code)。正是因為這個字段,當用戶 import { zyFlvVideoView } from 'zy-video-view'; 時,編輯器能提供代碼自動補全、類型檢查和屬性文檔提示。這是提升開發(fā)者體驗(DX)的關(guān)鍵。


      3. exports (現(xiàn)代入口字段)
      "exports": {
      ".": {
      "types": "./dist/zy-video-view.d.ts",
      "import": "./dist/zy-video-view.es.js",
      "require": "./dist/zy-video-view.cjs.js"
      },
      "./dist/style.css": "./dist/style.css",
      "./package.json": "./package.json"
      },

      含義:這是目前最推薦的、最權(quán)威的方式來聲明包的入口。當 exports 字段存在時,它會完全覆蓋 main、module、types 的作用。它像一個精確的“路由表”或“海關(guān)申報單”,嚴格控制了外部可以訪問你包里的哪些文件。
      "." (主入口):
      代表用戶直接導(dǎo)入包名,如 import ... from 'zy-video-view'。
      "import": 當環(huán)境使用 import (ESM) 時,提供 es.js 文件。
      "require": 當環(huán)境使用 require (CJS) 時,提供 cjs.js 文件。
      "types": 為這個主入口指定類型聲明文件。
      "./dist/style.css" (子路徑導(dǎo)出):
      這是一個非常重要的配置!它允許用戶單獨導(dǎo)入你的樣式文件,例如 import 'zy-video-view/dist/style.css';。
      如果沒有在 exports 中聲明這個路徑,用戶將無法訪問到 style.css,即使它存在于 dist 文件夾中。exports 默認會隱藏所有未聲明的文件。
      "./package.json":
      同理,允許外部工具訪問你包的 package.json 文件。為什么允許外部訪問package.json 呢?

      因為:
      1. 處理對等依賴 (peerDependencies) - 這是最重要的原因
      你的庫很可能依賴于 Vue。你應(yīng)該在 package.json 中這樣聲明:
      Generated json
      這告訴用戶:“我的庫需要 Vue 3 才能運行,但你得自己安裝它,我不會幫你打包進來。”
      當用戶安裝你的庫時,npm 或 pnpm 這樣的包管理器需要讀取你庫的 package.json 來檢查這個 peerDependencies 字段。
      如果它能讀取到,它就會檢查用戶的項目里是否安裝了 Vue 3。如果沒有,它會給出一個警告,提醒用戶安裝。
      如果你不導(dǎo)出 package.json,包管理器就無法讀取這個信息,也就無法給出這個重要的警告,可能會導(dǎo)致用戶的項目在運行時出錯。

      2. 構(gòu)建工具的模塊解析 (Module Resolution)
      像 Vite 或 Webpack 這樣的現(xiàn)代構(gòu)建工具在解析模塊時,有時會需要參考 package.json。例如,它們可能會檢查 "type": "module" 字段來確定如何處理 .js 文件。雖然 exports 字段中的 "import" 和 "require" 條件已經(jīng)提供了足夠的信息,但允許訪問 package.json 可以為更復(fù)雜的解析場景提供兼容性保障。

      3. 調(diào)試和版本檢查
      想象一下,一個用戶報告了你的庫的一個 bug。你可能會讓他運行一個診斷腳本,這個腳本需要知道他當前使用的 zy-video-view 的確切版本號。這個腳本可能會這樣做:
      Generated javascript
      // 在用戶的項目中運行
      const myLibVersion = require('zy-video-view/package.json').version;
      console.log('zy-video-view version:', myLibVersion);
      Use code with caution.
      JavaScript
      如果你的 exports 允許訪問 package.json,這段代碼會成功運行并打印出版本號。
      如果不允許,這段代碼會直接拋出 ERR_PACKAGE_PATH_NOT_EXPORTED 錯誤,調(diào)試將變得更加困難。

      4. Monorepo (單一代碼庫) 工具
      在 Monorepo 架構(gòu)中,像 pnpm workspaces 或 Turborepo 這樣的工具需要遍歷工作區(qū)內(nèi)所有包的 package.json 文件來構(gòu)建整個項目的依賴關(guān)系圖。如果某個包的 package.json 不可訪問,這些工具就可能無法正常工作。

       

      4. files
      Generated json
      "files": [
      "dist/*"
      ],
      Use code with caution.
      Json
      含義:這是一個“白名單”,指定了當你執(zhí)行 npm publish 時,哪些文件或文件夾應(yīng)該被上傳到 NPM 倉庫。
      作用:保持你發(fā)布的包干凈、輕量。它確保只有編譯后的、可直接使用的 dist 文件夾內(nèi)容會被上傳,而你的源代碼 (src)、配置文件 (vite.config.ts, .gitignore 等) 不會被包含進去。用戶下載你的包時,只會得到必要的文件。
      這就是為什么發(fā)布之前要先build構(gòu)建一下的原因,沒有dist的時候,調(diào)用方下載這個包是沒法用的


      接下來看看vite的配置部分,我的項目是一個視頻播放器組件,以此為例

      rollupOptions: {
      external: ["vue", "mpegts.js"], //不要把vue和mpegts.js這些依賴也打包進來
      output: {
      globals: {
      //UMD下的全局變量名稱
      vue: "Vue",
      "mpegts.js": "mpegts",
      },
      exports: "named", // 使用命名導(dǎo)出避免警告
      // 確保 CSS 文件被正確輸出
      assetFileNames: (assetInfo) => {
      // 處理 CSS 文件
      if (assetInfo.type === "asset" && assetInfo.names) {
      const name = assetInfo.names[0];
      if (name && name.endsWith(".css")) {
      return "style.css";
      }
      }
      return "[name][extname]";
      },
      },
      },

      講一下assetFileNames:
      1.背景問題: 當你構(gòu)建一個包含 CSS 的 Vue 組件庫時,Vite/Rollup 默認可能會為了避免緩存問題,給輸出的 CSS 文件名加上一個隨機哈希值,例如 style.a1b2c3d4.css。
      對于庫的危害: 如果文件名是隨機的,你的庫的使用者就無法像下面這樣穩(wěn)定地導(dǎo)入樣式:

      // 用戶希望這樣做,但如果文件名是隨機的,這就行不通了
      import 'zy-video-view/dist/style.css';
      Use code with caution.

      解決方案: assetFileNames 配置允許你完全控制資源文件(assets)的輸出文件名。
      你的這段代碼邏輯檢查每一個即將輸出的資源文件 (assetInfo)。
      如果發(fā)現(xiàn)這個文件是一個 CSS 文件 (assetInfo.name.endsWith('.css')),它會強制將其文件名重命名為 style.css。
      這樣,無論構(gòu)建多少次,輸出的 CSS 文件名永遠都是 style.css。

      2.cssCodeSplit: false

      背景問題: 如果你的庫里有多個組件(例如 zy-flv-video-view 和 zy-webrtc-video-view),并且它們各自有自己的 <style> 塊,Vite 默認可能會把它們的 CSS 分割成多個文件(Code Splitting)。
      對于庫的危害: 一個組件庫通常不希望用戶去導(dǎo)入多個零散的 CSS 文件。用戶只想要一個全功能的樣式入口。
      解決方案: 將 cssCodeSplit 設(shè)置為 false,它會告訴 Vite:“不要對 CSS 進行代碼分割。請把所有組件的所有樣式,全部合并到同一個 CSS 文件里去。”
      ? 核心收益: 確保了所有樣式都被打包進一個單一的文件中。這個配置與上面的 assetFileNames 完美配合:
      cssCodeSplit: false 負責將所有 CSS 合并成一個文件。
      assetFileNames 負責將這個合并后的文件命名為 style.css。

       

      最后看一下如何暴露給外部才可以實現(xiàn)既能用對象方式使用還能使用解構(gòu)方式使用
      import ZyFlvVideo from "./components/flv_video/index.vue";
      import ZyWebRtcVideo from "./components/webrtc_video/index.vue";
      import { withInstall } from "./utils/with-install";

      // 確保 VideoView 的類型是 DefineComponent
      const zyFlvVideoView = withInstall(ZyFlvVideo);
      const zyWebRtcVideoView = withInstall(ZyWebRtcVideo);

      // 創(chuàng)建一個包含所有組件的對象作為默認導(dǎo)出
      const ZyVideoView = {
      zyFlvVideoView,
      zyWebRtcVideoView,
      install(app: any) {
      app.component("zy-flv-video-view", zyFlvVideoView);
      app.component("zy-webrtc-video-view", zyWebRtcVideoView);
      },
      };

      // 默認導(dǎo)出
      export default ZyVideoView;

      // 命名導(dǎo)出
      export { zyFlvVideoView, zyWebRtcVideoView };

      // 類型導(dǎo)出
      export type { IFlvVideoProps } from "./components/flv_video/type";
      export type { IWebRtcPlayerProps } from "./components/webrtc_video/type";

      ZyVideoView對象可以寫成
      const ZyVideoView = {
      install(app: any) {
      app.component("zy-flv-video-view", zyFlvVideoView);
      app.component("zy-webrtc-video-view", zyWebRtcVideoView);
      },
      };嗎?
      是的,可以去掉。從技術(shù)上講 app.use() 功能不會受到任何影響。

      去掉后,代碼變成這樣:
      Generated typescript
      // ... zyFlvVideoView 和 zyWebRtcVideoView 的定義 ...

      // 簡化后的默認導(dǎo)出對象
      const ZyVideoView = {
      install(app: any) {
      // 這里的 zyFlvVideoView 和 zyWebRtcVideoView 仍然可以被訪問到
      // 因為它們是在同一個文件作用域內(nèi)定義的常量
      app.component("zy-flv-video-view", zyFlvVideoView);
      app.component("zy-webrtc-video-view", zyWebRtcVideoView);
      },
      };

      export default ZyVideoView;
      Use code with caution.
      TypeScript
      當用戶執(zhí)行 app.use(ZyVideoView) 時,Vue 會調(diào)用這個對象的 install 方法。由于 zyFlvVideoView 和 zyWebRtcVideoView 這兩個常量在當前文件的作用域中是存在的,所以 install 方法可以毫無問題地訪問它們并完成組件的全局注冊。
      那么,為什么通常要保留它們呢?
      盡管從 install 的角度看它們是多余的,但保留它們提供了一個重要的額外功能:將默認導(dǎo)出的對象變成一個“命名空間”或“工具箱”。
      這為庫的使用者提供了另一種靈活的使用方式。
      讓我們對比一下保留和去掉的區(qū)別:
      情況一:保留屬性(你的原始代碼)
      Generated typescript
      // 原始代碼
      const ZyVideoView = {
      zyFlvVideoView,
      zyWebRtcVideoView,
      install(app: any) { /* ... */ },
      };
      export default ZyVideoView;
      Use code with caution.
      TypeScript
      使用者可以這樣做:
      Generated typescript
      import ZyVideo from 'your-library-name'; // 默認導(dǎo)入

      // 用法1:全局安裝 (最常見)
      app.use(ZyVideo);

      // 用法2:手動、有選擇性地注冊或使用
      // 用戶可以通過默認導(dǎo)出的對象,直接訪問到具體的組件定義
      const flvPlayerComponent = ZyVideo.zyFlvVideoView;
      const webrtcPlayerComponent = ZyVideo.zyWebRtcVideoView;

      // 可以在某個組件里局部注冊
      export default {
      components: {
      'my-special-flv-player': flvPlayerComponent
      }
      }

      // 甚至可以在 JSX 或渲染函數(shù)中使用
      // import { h } from 'vue'
      // h(ZyVideo.zyFlvVideoView, { props... })
      Use code with caution.
      TypeScript
      優(yōu)點: 默認導(dǎo)出的 ZyVideo 對象本身就是一個完整的“工具箱”,包含了庫的所有部分。用戶導(dǎo)入一次,就可以訪問到所有東西,非常方便和直觀。
      情況二:去掉屬性(你提議的修改)
      Generated typescript
      // 修改后的代碼
      const ZyVideoView = {
      install(app: any) { /* ... */ },
      };
      export default ZyVideoView;
      Use code with caution.
      TypeScript
      使用者的行為會發(fā)生什么變化:
      Generated typescript
      import ZyVideo from 'your-library-name'; // 默認導(dǎo)入

      // 用法1:全局安裝 (仍然有效)
      app.use(ZyVideo);

      // 用法2:嘗試訪問組件定義
      const flvPlayerComponent = ZyVideo.zyFlvVideoView; // !!!錯誤!!!
      // Uncaught TypeError: Cannot read properties of undefined (reading 'zyFlvVideoView')
      Use code with caution.
      TypeScript
      缺點: ZyVideo 對象現(xiàn)在變成了一個“黑盒”,它除了能被 app.use() 之外,幾乎沒有其他用處。如果用戶想要獲取單個組件的定義(比如為了局部注冊或在渲染函數(shù)中使用),他們將必須同時使用命名導(dǎo)入:
      Generated typescript
      import ZyVideo, { zyFlvVideoView } from 'your-library-name';

      // 現(xiàn)在必須從命名導(dǎo)入中獲取組件
      const flvPlayerComponent = zyFlvVideoView;
      Use code with caution.
      TypeScript
      這破壞了默認導(dǎo)出作為“完整集合”的便利性,可能會讓用戶感到困惑。
      結(jié)論
      可以去掉嗎? 可以,核心的 app.use() 功能不受影響。
      應(yīng)該去掉嗎? 強烈不推薦。
      保留 zyFlvVideoView 和 zyWebRtcVideoView 作為 ZyVideoView 對象的屬性,是一種遵循社區(qū)最佳實踐的設(shè)計模式。它讓你的庫 API 更加健壯和靈活,為使用者提供了“開箱即用”的便利,同時保留了高級用法(如手動訪問和注冊)的可能性。
      這就像你買一個工具箱,你既希望店家能幫你把所有工具都安裝好(app.use),也希望自己能打開箱子,單獨拿出某一把螺絲刀來用(ZyVideo.zyFlvVideoView)。你的原始代碼完美地實現(xiàn)了這兩點。

      posted @ 2025-07-24 16:43  洛晨隨風  閱讀(47)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日本五十路熟女一区二区| 国产极品粉嫩尤物一线天| 三男一女吃奶添下面视频 | 精品av无码国产一区二区| 国产精品一区二区不卡91| 国产69精品久久久久99尤物| 好男人官网资源在线观看| 精品无码国产自产拍在线观看蜜| 自拍视频在线观看三级| 日本亚洲欧洲免费无线码| 91老肥熟女九色老女人| 亚洲精品乱码久久久久久按摩高清 | 亚洲国产午夜精品福利| 国产精品久久久久久福利| 91麻精品国产91久久久久| 中文字幕一区二区人妻电影| 国产a在视频线精品视频下载| 亚洲国产一区二区三区亚瑟| 榆社县| 亚洲av无码之国产精品网址蜜芽 | 简阳市| 精品中文人妻在线不卡| 国产欧美精品一区aⅴ影院| 精品国产成人三级在线观看| 欧美精品videosbestsex日本| 亚洲三区在线观看内射后入| 国产精品99一区二区三区| 亚洲va久久久噜噜噜久久狠狠| 欧洲精品色在线观看| 国产电影无码午夜在线播放| 伊人欧美在线| 日韩亚洲精品国产第二页| 性欧美vr高清极品| 视频二区中文字幕在线| 蜜桃一区二区三区在线看| 边添小泬边狠狠躁视频| 日韩国产欧美精品在线| 四虎永久地址www成人| 国产AV影片麻豆精品传媒| 野花香视频在线观看免费高清版 | 91亚洲国产三上悠亚在线播放|