Vue 組件庫自動引入最佳實踐

前言

你是否好奇ElementPlusResolver如何實現(xiàn)自動導入的?今天來解密element-plus組件自動導入如何實現(xiàn)的。如果你是組件庫作者,那一定不容錯過茉继。其他同學也可以學習到monorepo架構、workspace蚀乔、vue項目從0開始搭建烁竭、vue組件編輯器自動提示這些干貨。

// vite.config.ts
import { defineConfig } from "vite";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

export default defineConfig({
  // ...
  plugins: [
    // ...
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
});

背景

筆者項目基于 monorepo 架構吉挣,以組織前端項目和內(nèi)部公共組件庫派撕。monorepo 是使用的pnpm workspace技術,極簡配置即可使用睬魂,如下终吼。

monorepo 倉庫更目錄創(chuàng)建pnpm-workspace.yaml

packages:
  # all packages in direct subdirs of packages/
  - "packages/*"
  # all packages in subdirs of app/
  - "app/*"
  # exclude packages that are inside test directories
  - "!**/test/**"

在了解完了pnpm workspace技術后,現(xiàn)在的問題是氯哮,在app/management目錄下的應用頁面中际跪,需要引入packages/components目錄里的組件button.vue

有人要問:那不是很簡單嗎?

是的姆打,直接import Button from 'components/button.vue'就行了良姆。

好了,好了幔戏,文章到此結束玛追。。闲延。

停停停痊剖!

手動引入當然沒有問題,問題是要自動引入啊垒玲,這樣不是更爽嗎陆馁,早點下班不香嗎?

創(chuàng)建項目工作區(qū)侍匙,使用內(nèi)部 npm 包

monorepo 倉庫根目錄下執(zhí)行命令氮惯,還原筆者的工作區(qū)

mkdir app/management -p

# 創(chuàng)建應用management
cd app
# `Project Name`輸入`management`
npm create vue@latest

# 進入management目錄完成安裝
cd management
pnpm install


cd ../../

# 創(chuàng)建npm包,components組件庫
mkdir packages/components -p

cd packages/components

pnpm init

# 創(chuàng)建button組件
echo "<template>Button</template>" > button.vue

# 回到應用management中
cd ../../app/management

# 在應用management中添加components組件包
pnpm add components --workspace


echo "<template><WButton/></template>" > src/views/HomeView.vue

下面開始演示HomeView.vue<WButton/>不使用import語法實現(xiàn)自動按需導入components包里面的button組件想暗。

回歸正題,自動引入的實現(xiàn)過程

筆者既要實現(xiàn) button 組件的自動引入帘不,同時還要實現(xiàn)編輯器vscode對組件的屬性的提示说莫。

1. components包支持es module

需要修改packages/components/package.json,添加"type": "module",

2. 實現(xiàn)自動導入寞焙,提供 resolver

auto-import.mjs, 文件路徑:packages/components/auto-import.mjs

/**
 *
 * @param {string} componentName
 * @returns
 */
function resolver(componentName) {
  if (componentName.substring(0, 1).toLowerCase() !== "w") {
    return;
  }
  const map = new Map([["Button", "components/button.vue"]]);
  //下劃線風格轉為駝峰
  const name = componentName
    .replace(/-(\w)/g, (m, m1) => m1.toUpperCase())
    .slice(1);
  if (map.has(name)) {
    const from = map.get(name);
    if (from)
      return {
        from,
        name: "default" /*components/button.vue默認以default方式導出*/,
      };
  }
}

export default resolver;

注意:ts 項目需要添加d.ts文件储狭,避免在 vite 中引入 resolver 報錯:類型未定義

auto-import.d.ts, 文件路徑:packages/components/auto-import.d.ts

export default function resolver(componentName: string):
  | {
      name: string;
      from: string;
    }
  | undefined;

驗證

1. 安裝vite自動導入插件unplugin-vue-components

app/management目錄下執(zhí)行

pnpm add unplugin-vue-components -D

2. vite添加自動導入配置

修改文件app/management/vite.config.ts

import { defineConfig } from "vite";
import Components from "unplugin-vue-components/vite";
import ComponentsResolver from "components/auto-import";

// https://vitejs.dev/config/
export default defineConfig({
  //...
  plugins: [
    Components({
      dts: "./components.d.ts",
      types: [],
      resolvers: [ComponentsResolver],
      exclude: [/[\\/]node_modules[\\/]/],
    }),
    //...
  ],
});

3. [關鍵]添加組件庫ts類型

修改文件app/management/env.d.ts

/// <reference types="vite/client" />
/**
 * !**非常關鍵** unplugin-vue-components生成的組件類型聲明
 */
/// <reference types="./components" />

這一步會讓vscode獲得組件參數(shù)的自動提示

4. 測試

此時我們把button.vue組件修改一下

<template>
  {{ txt }}
</template>
<script setup lang="ts">
defineProps<{ txt: string }>();
</script>

修改文件HomeView.vue

<script setup lang="ts"></script>
<template><WButton txt="Hello Vue!" /></template>

啟動項目

pnpm dev

我們在HomeView.vue可以看到<WButton/>組件標紅,鼠標移上去顯示msg屬性為string類型

總結

文章主要介紹了如何實現(xiàn)npm包組件庫的resolver實現(xiàn)組件自動捣郊、按需加載辽狈,同時實現(xiàn)編輯器自動提示包內(nèi)組件的屬性。如果有些技術要點不清楚呛牲,建議根據(jù)自己需要進一步了解下面這些技術要點刮萌。

技術要點

干貨拿走,不謝娘扩!

文章的代碼倉庫

為了方便大家學習着茸,已經(jīng)將文章內(nèi)容和代碼全部提交到github

workspace-autoimport

感謝你的閱讀!

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末琐旁,一起剝皮案震驚了整個濱河市涮阔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌灰殴,老刑警劉巖敬特,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡伟阔,警方通過查閱死者的電腦和手機辣之,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來减俏,“玉大人召烂,你說我怎么就攤上這事⊥蕹校” “怎么了奏夫?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長历筝。 經(jīng)常有香客問我酗昼,道長,這世上最難降的妖魔是什么梳猪? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任麻削,我火速辦了婚禮,結果婚禮上春弥,老公的妹妹穿的比我還像新娘呛哟。我一直安慰自己,他們只是感情好匿沛,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布扫责。 她就那樣靜靜地躺著,像睡著了一般逃呼。 火紅的嫁衣襯著肌膚如雪鳖孤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天抡笼,我揣著相機與錄音苏揣,去河邊找鬼。 笑死推姻,一個胖子當著我的面吹牛平匈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拾碌,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼吐葱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了校翔?” 一聲冷哼從身側響起弟跑,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎防症,沒想到半個月后孟辑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哎甲,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年饲嗽,在試婚紗的時候發(fā)現(xiàn)自己被綠了炭玫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡貌虾,死狀恐怖吞加,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情尽狠,我是刑警寧澤衔憨,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站袄膏,受9級特大地震影響践图,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沉馆,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一码党、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斥黑,春花似錦揖盘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缨叫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間荔燎,已是汗流浹背耻姥。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留有咨,地道東北人琐簇。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像座享,于是被迫代替她去往敵國和親婉商。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容